Jamoma API  0.6.0.a19
j.receivemaster.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxLibrary
4  *
5  * @brief Jamoma For Max Shared Library
6  *
7  * @details Manage j.receive instances.
8  *
9  * @authors Tim Place, Trond Lossius
10  *
11  * @copyright Copyright © 2007, Tim Place @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
17 #include "Jamoma.h"
18 
19 
20 // Prototypes
21 
22 /************************************************************************************/
23 // Object Life
24 
25 /** This method is called when a object is instantiated.
26  @param msg Message passed to the object when instantiated.
27  @param argc The number of arguments to the object.
28  @param argv Pointer to arguments as atoms.
29  @return Pointer to the object.
30  */
31 void *receivemaster_new(t_symbol *msg, long argc, t_atom *argv);
32 
33 
34 /** Method called when the object is freed.
35  @param x Pointer to the object.
36  */
37 void receivemaster_free(t_jcom_receivemaster *x);
38 
39 
40 /** Send message to an object by remote communiction.
41  @param x Pointer to this object.
42  @param name The (OCS) name of the receiving object.
43  @param msg Message passed to the object.
44  @param argc The number of arguments of the message to send.
45  @param argv Pointer to arguments of the message as atoms.
46  */
47 void receivemaster_dispatch(t_jcom_receivemaster *x, t_symbol *name, t_symbol *msg, long argc, t_atom *argv);
48 
49 
50 /** Add an object to a linked list of receiving objects associated with a certain name.
51  @param x This object
52  @param name The symbol that the receiving object is to be associated with.
53  Example: For a "j.send foo" object the name would be "foo".
54  @param obj Pointer to the receiving object that is to be added.
55  */
56 void receivemaster_add(t_jcom_receivemaster *x, t_symbol *name, t_object *obj);
57 
58 
59 /** Remove an object from the linked list of receiving objects associated with a certain name.
60  @param x This Object.
61  @param name The symbol that the receiving object is currently associated with.
62  Example: For a "j.send foo" object the name would be "foo".
63  @param obj Pointer to the receiving object that is to be removed.
64  */
65 void receivemaster_remove(t_jcom_receivemaster *x, t_symbol *name, t_object *obj);
66 
67 
68 // Globals
69 static t_class *s_receivemaster_class = NULL; ///< Required: Global pointer the j.receivemaster class
70 static t_hashtab *s_receive_lists = NULL; ///< hash full of linked lists, keyed on the name of the j.receive instances
71 
72 
73 /************************************************************************************/
74 
75 void receivemaster_initclass()
76 {
77  // Define our class
78  s_receivemaster_class = class_new( "j.receivemaster",
79  (method)receivemaster_new,
80  (method)receivemaster_free,
81  sizeof(t_jcom_receivemaster),
82  (method)0L,
83  A_GIMME,
84  0);
85 
86  // Make methods accessible for our class:
87  class_addmethod(s_receivemaster_class, (method)receivemaster_dispatch, "dispatch", A_CANT, 0L);
88  class_addmethod(s_receivemaster_class, (method)receivemaster_add, "add", A_CANT, 0L);
89  class_addmethod(s_receivemaster_class, (method)receivemaster_remove, "remove", A_CANT, 0L);
90 
91  // Finalize our class
92  class_register(CLASS_NOBOX, s_receivemaster_class);
93 }
94 
95 void *receivemaster_new(t_symbol *msg, long argc, t_atom *argv)
96 {
97  t_jcom_receivemaster *x = (t_jcom_receivemaster *)object_alloc(s_receivemaster_class);
98 
99  if (!s_receive_lists)
100  s_receive_lists = hashtab_new(0);
101  return x;
102 }
103 
104 void receivemaster_free(t_jcom_receivemaster *x)
105 {
106  ; // we could delete the hashtab, but this class is never deleted so it doesn't really make a difference
107  // does it?
108 }
109 
110 
111 /************************************************************************************/
112 // Methods
113 
114 void receivemaster_dispatch(t_jcom_receivemaster *x, t_symbol *name, t_symbol *msg, long argc, t_atom *argv)
115 {
116  t_linklist *list = NULL; // linklist of receives with this name
117 
118  hashtab_lookup(s_receive_lists, name, (t_object **)&list); // 1. Look up the correct linklist in the hashtab
119  if (list)
120  linklist_methodall(list, jps_dispatch, msg, argc, argv); // 2. Call method on every object in the linklist
121 }
122 
123 void receivemaster_add(t_jcom_receivemaster *x, t_symbol *name, t_object *obj)
124 {
125  t_linklist *list = NULL;
126 
127  hashtab_lookup(s_receive_lists, name, (t_object **)&list); // 1. Look up the correct linklist in the hashtab
128  if (!list) {
129  list = (t_linklist *)linklist_new(); // If there isn't a linklist for this name yet,
130  hashtab_store(s_receive_lists, name, (t_object *)list); // then we make one and store it in the hashtab
131  }
132  linklist_append(list, obj); // 2. We add the object to the appropriate linklist
133 }
134 
135 
136 // TODO: When we switch to Max5 then remove these function definitions
137 #if 1
138 /*
139 long linklist_match(void *a, void *b)
140 {
141  return a == b;
142 }
143 
144 void linklist_chuckobject(t_linklist *x, void *o)
145 {
146  void *obj;
147 
148  long index = linklist_findfirst(x, &obj, linklist_match, o);
149  if (index != -1)
150  linklist_chuckindex(x, index);
151 }
152  */
153 #endif
154 
155 
156 void receivemaster_remove(t_jcom_receivemaster *x, t_symbol *name, t_object *obj)
157 {
158  t_linklist *list = NULL;
159 
160  hashtab_lookup(s_receive_lists, name, (t_object **)&list); // 1. Look up the correct linklist in the hashtab
161  linklist_chuckobject(list, obj);
162  if (!linklist_getsize(list))
163  hashtab_chuckkey(s_receive_lists, name); // 2. Chuck the key if there are no more objects with this name
164 }
void receivemaster_remove(t_jcom_receivemaster *x, t_symbol *name, t_object *obj)
Remove an object from the linked list of receiving objects associated with a certain name...
void receivemaster_add(t_jcom_receivemaster *x, t_symbol *name, t_object *obj)
Add an object to a linked list of receiving objects associated with a certain name.
void receivemaster_free(t_jcom_receivemaster *x)
Method called when the object is freed.
void * receivemaster_new(t_symbol *msg, long argc, t_atom *argv)
This method is called when a object is instantiated.
void receivemaster_dispatch(t_jcom_receivemaster *x, t_symbol *name, t_symbol *msg, long argc, t_atom *argv)
Send message to an object by remote communiction.