Jamoma API  0.6.0.a19
Max/source/j.init/j.init.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.init - Send bang to initialize something.
6  *
7  * @details Bang source may be global or for just one module
8  *
9  * @authors Tim Place, Trond Lossius
10  *
11  * @copyright Copyright © 2006 by 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 "JamomaForMax.h"
18 
19 
20 #define start_out 0
21 #define end_out 1
22 
23 // Data Structure for this object
24 typedef struct _init{
25  t_object obj;
26  TTNodePtr patcherNode;
27  TTObject initReceiver;
28  TTObject subscriberObject;
29  TTAddress address;
30  TTHandle outlets;
31 } t_init;
32 
33 // Prototypes for methods
34 void *init_new(t_symbol* s, long argc, t_atom* argv); // New Object Creation Method
35 void init_free(t_init *x);
36 void init_assist(t_init *x, void *b, long m, long a, char *s); // Assistance Method
37 void init_subscribe(t_init *x);
38 void init_return_address(t_init *x, t_symbol *msg, long argc, t_atom *argv);
39 void init_return_value(t_init *x, t_symbol *msg, long argc, t_atom *argv);
40 //void init_bang(t_init *x);
41 
42 // Globals
43 t_class *g_init_class; // Required. Global pointing to this class
44 
45 
46 /************************************************************************************/
47 // Main() Function
48 
49 int JAMOMA_EXPORT_MAXOBJ main(void)
50 {
51  t_class *c;
52 
53  jamoma_init();
54  common_symbols_init();
55 
56  // Define our class
57  c = class_new("j.init",(method)init_new, (method)init_free, sizeof(t_init), (method)0L, A_GIMME, 0);
58 
59  // Make methods accessible for our class:
60  //class_addmethod(c, (method)init_bang, "bang", 0L);
61  class_addmethod(c, (method)init_return_address, "return_address", A_CANT, 0);
62  class_addmethod(c, (method)init_return_value, "return_value", A_CANT, 0);
63  class_addmethod(c, (method)init_assist, "assist", A_CANT, 0L);
64 
65  // Finalize our class
66  class_register(CLASS_BOX, c);
67  g_init_class = c;
68 
69  return 0;
70 }
71 
72 
73 /************************************************************************************/
74 // Object Life
75 
76 // Create
77 void *init_new(t_symbol *s, long argc, t_atom *argv)
78 {
79  long attrstart = attr_args_offset(argc, argv); // support normal arguments
80  t_init *x = (t_init *)object_alloc(g_init_class);
81  t_symbol *relativeAddress = _sym_nothing; // could be used to binds on a sub level j.hub
82 
83  if (attrstart && argv)
84  atom_arg_getsym(&relativeAddress, 0, attrstart, argv);
85 
86  if (x) {
87 
88  x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr) * 2);
89  x->outlets[end_out] = bangout(x);
90  x->outlets[start_out] = bangout(x);
91 
92  x->patcherNode = NULL;
93  x->address = TTAddress(jamoma_parse_dieze((t_object*)x, relativeAddress)->s_name);
94 
95  attr_args_process(x, argc, argv); // handle attribute args
96 
97  // The following must be deferred because we have to interrogate our box,
98  // and our box is not yet valid until we have finished instantiating the object.
99  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
100  defer_low((t_object*)x, (method)init_subscribe, NULL, 0, 0);
101  }
102 
103  return (x); // Return the pointer
104 }
105 
106 void init_free(t_init *x)
107 {
108  // release the receiver
109  x->initReceiver.set(kTTSym_address, kTTAdrsEmpty);
110  x->initReceiver = TTObject();
111 
112  // release the subscriber
113  x->subscriberObject = TTObject();
114 }
115 
116 
117 
118 /************************************************************************************/
119 // Methods bound to input/inlets
120 
121 // Method for Assistance Messages
122 void init_assist(t_init *x, void *b, long msg, long arg, char *dst)
123 {
124  if (msg==1) // Inlets
125  strcpy(dst, "");
126  else if (msg==2) { // Outlets
127  if (arg == 0)
128  strcpy(dst, "bang when initialization starts");
129  else
130  strcpy(dst, "bang when initilization is done");
131  }
132 }
133 
134 void init_subscribe(t_init *x)
135 {
136  TTValue v, args, none;
137  TTAddress contextAddress = kTTAdrsEmpty;
138  TTAddress returnedAddress;
139  TTNodePtr returnedNode = NULL;
140  TTNodePtr returnedContextNode = NULL;
141  TTObject returnAddressCallback, returnValueCallback, empty;
142 
143  // for relative address
144  if (x->address.getType() == kAddressRelative) {
145 
146  if (!jamoma_subscriber_create((t_object*)x, empty, x->address, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode)) {
147 
148  // get the context address to make
149  // a receiver on the contextAddress:initialized attribute
150  x->subscriberObject.get("contextAddress", v);
151  contextAddress = v[0];
152  }
153 
154  // bind on the /model:address parameter (view patch) or return (model patch)
155  if (contextAddress != kTTAdrsEmpty) {
156 
157  // Make a TTReceiver object
158  returnAddressCallback = TTObject("callback");
159  returnAddressCallback.set(kTTSym_baton, TTPtr(x));
160  returnAddressCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_address));
161  args.append(returnAddressCallback);
162 
163  returnValueCallback = TTObject("callback");
164  returnValueCallback.set(kTTSym_baton, TTPtr(x));
165  returnValueCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
166  args.append(returnValueCallback);
167 
168  x->initReceiver = TTObject(kTTSym_Receiver, args);
169 
170  x->initReceiver.set(kTTSym_address, contextAddress.appendAttribute(kTTSym_initialized));
171  }
172 
173  // while the context node is not registered : try to binds again :(
174  // (to -- this is not a good way todo. For binding we should make a subscription
175  // to a notification mechanism and each time an TTObjet subscribes to the namespace
176  // using jamoma_subscriber_create we notify all the externals which have used
177  // jamoma_subscriber_create with NULL object to bind)
178  else {
179 
180  // release the subscriber
181  x->subscriberObject = TTObject();
182 
183  // The following must be deferred because we have to interrogate our box,
184  // and our box is not yet valid until we have finished instantiating the object.
185  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
186  defer_low((t_object*)x, (method)init_subscribe, NULL, 0, 0);
187  }
188  }
189  else
190  object_error((t_object*)x, "can't bind because %s is not a relative address", x->address.c_str());
191 }
192 
193 void init_return_address(t_init *x, t_symbol *msg, long argc, t_atom *argv)
194 {
195  ;
196 }
197 
198 // GO !
199 void init_return_value(t_init *x, t_symbol *msg, long argc, t_atom *argv)
200 {
201  if (atom_gettype(argv) == A_LONG) {
202 
203  if (atom_getlong(argv) == 0)
204  outlet_bang(x->outlets[start_out]);
205  else
206  outlet_bang(x->outlets[end_out]);
207 
208  }
209 }
210 
211 /*
212 // BANG !
213 void init_bang(t_init *x)
214 {
215  if (x->contextNode)
216  if (x->contextNode->getObject().valid())
217  x->contextNode->getObject().send("Init");
218 }
219  */
TTAddress appendAttribute(TTSymbol anAttribute)
Return a new TTAddress with attribute part.
Definition: TTAddress.h:161
t_symbol JAMOMA_EXPORT * jamoma_parse_dieze(t_object *x, t_symbol *address)
Parse #N inside address and replace them by parent patcher arguments if there are.
We build a directory of TTNodes, and you can request a pointer for any TTNode, or add an observer to ...
Definition: TTNode.h:59
int JAMOMA_EXPORT_MAXOBJ main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
The TTAddress class is used to represent a string and efficiently pass and compare that string...
Definition: TTAddress.h:29
Create and use Jamoma object instances.
Definition: TTObject.h:29
void JAMOMA_EXPORT jamoma_callback_return_value(const TTValue &baton, const TTValue &v)
Return the value to a j.
this flag means that an address have no leading slash
Definition: TTAddressBase.h:64
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
TTErr get(const TTSymbol aName, T &aReturnedValue) const
Get an attribute value for an object.
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
Various utilities for interfacing with Max that are not specific to JamomaModular as such...
void JAMOMA_EXPORT jamoma_callback_return_address(const TTValue &baton, const TTValue &v)
Return an address to a j.
TTErr JAMOMA_EXPORT jamoma_subscriber_create(t_object *x, TTObject &anObject, TTAddress relativeAddress, TTObject &returnedSubscriber, TTSymbol &returnedAddress, TTNodePtr *returnedNode, TTNodePtr *returnedContextNode)
Create a #TTSubscriber object and register a TTObject into the tree or, if aTTObject is NULL...
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34