Jamoma API  0.6.0.a19
Max/source/j.remote/j.remote.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.remote : Bind to a parameter value
6  *
7  * @details Useful when designing views and more.
8  *
9  * @authors Théo de la Hogue, Trond Lossius
10  *
11  * @copyright © 2010 by Théo de la Hogue @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
18 
19 // those stuffes are needed for handling patchers without using the pcontrol object
20 #include "jpatcher_api.h"
21 typedef struct dll {
22  t_object d_ob;
23  struct dll *d_next;
24  struct dll *d_prev;
25  void *d_x1;
26 } t_dll;
27 
28 typedef struct outlet {
29  struct tinyobject o_ob;
30  struct dll *o_dll;
31 } t_outlet;
32 
33 // This is used to store extra data
34 typedef struct extra {
35  TTAddress name; ///< the name to use for subscription
36  TTPtr ui_qelem; ///< to output "qlim'd" data for ui object
37  t_object* connected; // our ui object
38  long x; // our ui object x presentation
39  long y; // our ui object y presentation
40  long w; // our ui object width presentation
41  long h; // our ui object heigth presentation
42  t_object* label; // label to display selection state
43  t_atom* color0; // label color for selection state == 0
44  t_atom* color1; // label color for selection state == 1
45  TTBoolean setting; // a flag to know if the remote is updated by a set message
46 } t_extra;
47 #define EXTRA ((t_extra*)x->extra)
48 
49 #define set_out 0
50 #define value_out 1
51 #define attach_out 2
52 #define dump_out 3
53 
54 // Definitions
55 void WrapTTViewerClass(WrappedClassPtr c);
56 void WrappedViewerClass_new(TTPtr self, long argc, t_atom *argv);
57 void WrappedViewerClass_free(TTPtr self);
58 void WrappedViewerClass_anything(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
59 
60 void remote_assist(TTPtr self, void *b, long msg, long arg, char *dst);
61 
62 void remote_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
63 void remote_return_model_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
64 void remote_return_description(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
65 
66 void remote_bang(TTPtr self);
67 void remote_int(TTPtr self, long value);
68 void remote_float(TTPtr self, double value);
69 TTErr remote_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
70 
71 void remote_set(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
72 
73 void remote_address(TTPtr self, t_symbol *address);
74 
75 void remote_attach(TTPtr self, int attach_output_id);
76 void remote_mousemove(TTPtr self, t_object *patcherview, t_pt pt, long modifiers);
77 void remote_mouseleave(TTPtr self, t_object *patcherview, t_pt pt, long modifiers);
78 void remote_mousedown(TTPtr self, t_object *patcherview, t_pt pt, long modifiers);
79 
80 void remote_subscribe(TTPtr self);
81 
82 void remote_ui_queuefn(TTPtr self);
83 
84 int C74_EXPORT main(void)
85 {
86  ModularSpec *spec = new ModularSpec;
87  spec->_wrap = &WrapTTViewerClass;
88  spec->_new = &WrappedViewerClass_new;
89  spec->_free = &WrappedViewerClass_free;
90  spec->_any = &WrappedViewerClass_anything;
91 
92  return wrapTTModularClassAsMaxClass(kTTSym_Viewer, "j.remote", NULL, spec);
93 }
94 
95 void WrapTTViewerClass(WrappedClassPtr c)
96 {
97  class_addmethod(c->maxClass, (method)remote_assist, "assist", A_CANT, 0L);
98 
99  class_addmethod(c->maxClass, (method)remote_mousemove, "mousemove", A_CANT, 0);
100  class_addmethod(c->maxClass, (method)remote_mouseleave, "mouseleave", A_CANT, 0);
101  class_addmethod(c->maxClass, (method)remote_mousedown, "mousedown", A_CANT, 0);
102 
103  class_addmethod(c->maxClass, (method)remote_return_value, "return_value", A_CANT, 0);
104  class_addmethod(c->maxClass, (method)remote_return_model_address, "return_model_address", A_CANT, 0);
105  class_addmethod(c->maxClass, (method)remote_return_description, "return_description", A_CANT, 0);
106 
107  class_addmethod(c->maxClass, (method)remote_bang, "bang", 0L);
108  class_addmethod(c->maxClass, (method)remote_int, "int", A_LONG, 0L);
109  class_addmethod(c->maxClass, (method)remote_float, "float", A_FLOAT, 0L);
110  class_addmethod(c->maxClass, (method)remote_list, "list", A_GIMME, 0L);
111 
112  class_addmethod(c->maxClass, (method)remote_set, "set", A_GIMME, 0L);
113 
114  class_addmethod(c->maxClass, (method)remote_address, "address", A_SYM, 0);
115 }
116 
117 void WrappedViewerClass_new(TTPtr self, long argc, t_atom *argv)
118 {
120  t_symbol *address;
121  long attrstart = attr_args_offset(argc, argv); // support normal arguments
122 
123  // read the address to bind from the first argument
124  if (attrstart > 0 && argv)
125  address = atom_getsym(argv);
126  else
127  address = _sym_nothing;
128 
129  x->address = TTAddress(jamoma_parse_dieze((t_object*)x, address)->s_name);
130  x->index = 0; // the index member is usefull to count how many time the external tries to bind
131 
132  // Prepare extra data
133  x->extra = (t_extra*)malloc(sizeof(t_extra));
134 
135  // read the name to use for subscription from the first argument
136  if (attrstart == 2 && argv)
137  EXTRA->name = TTAddress(atom_getsym(argv+1)->s_name);
138  else
139  EXTRA->name = kTTAdrsEmpty;
140 
141  EXTRA->connected = NULL;
142  EXTRA->label = NULL;
143 
144  EXTRA->color0 = (t_atom*)sysmem_newptr(sizeof(t_atom) * 4);
145  atom_setfloat(EXTRA->color0, 0);
146  atom_setfloat(EXTRA->color0+1, 0.);
147  atom_setfloat(EXTRA->color0+2, 0.);
148  atom_setfloat(EXTRA->color0+3, 1.);
149 
150  EXTRA->color1 = (t_atom*)sysmem_newptr(sizeof(t_atom) * 4);
151  atom_setfloat(EXTRA->color1, 0.62);
152  atom_setfloat(EXTRA->color1+1, 0.);
153  atom_setfloat(EXTRA->color1+2, 0.36);
154  atom_setfloat(EXTRA->color1+3, 0.70);
155 
156  EXTRA->setting = NO;
157 
158  jamoma_viewer_create((t_object*)x, x->wrappedObject);
159 
160  // Make two outlets
161  x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr) * 3);
162  x->outlets[attach_out] = outlet_new(x, NULL); // anything outlet to select ui
163  x->outlets[value_out] = outlet_new(x, NULL); // anything outlet to output data
164  x->outlets[set_out] = outlet_new(x, NULL); // anything outlet to output qlim data
165 
166  // Make qelem object
167  EXTRA->ui_qelem = qelem_new(x, (method)remote_ui_queuefn);
168 
169  // clear support for qelem value
170  x->argc = 0;
171  x->argv = NULL;
172 
173  // handle attribute args
174  attr_args_process(x, argc, argv);
175 
176  // The following must be deferred because we have to interrogate our box,
177  // and our box is not yet valid until we have finished instantiating the object.
178  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
179  defer_low((t_object*)x, (method)remote_subscribe, NULL, 0, 0);
180 }
181 
182 // Method for Assistance Messages
183 void remote_assist(TTPtr self, void *b, long msg, long arg, char *dst)
184 {
185  if (msg==1) // Inlet
186  strcpy(dst, "input: forwarded to node");
187  else { // Outlets
188  switch(arg) {
189  case set_out:
190  strcpy(dst, "set: connect to ui object");
191  break;
192  case value_out:
193  strcpy(dst, "value");
194  break;
195  case attach_out:
196  strcpy(dst, "attach: connect this outlet to ui object if the set or the value outlets are not directly connected to it");
197  break;
198  case dump_out:
199  strcpy(dst, "dumpout");
200  break;
201  }
202  }
203 }
204 
205 void WrappedViewerClass_free(TTPtr self)
206 {
208 
209  qelem_free(EXTRA->ui_qelem);
210 
211  x->wrappedObject.set(kTTSym_address, kTTAdrsEmpty);
212 
213  free(EXTRA);
214 }
215 
216 void remote_subscribe(TTPtr self)
217 {
219  TTValue v;
220  t_atom a[1];
221  TTAddress contextAddress = kTTAdrsEmpty;
222  TTAddress absoluteAddress, returnedAddress;
223  TTNodePtr returnedNode = NULL;
224  TTNodePtr returnedContextNode = NULL;
225  TTObject anObject, empty;
226  TTErr err;
227 
228  if (x->address == kTTAdrsEmpty)
229  return;
230 
231  // attach the j.remote to connected ui object
232  // TODO : this should be done when the an object is connected to one of the j.remote outlet
233  // (but this means we need to unsubscribe then subscribe with the new name)
234  remote_attach(self, set_out);
235 
236  // for absolute address we only bind the given address but we don't subscribe the remote into the namespace
237  if (x->address.getType() == kAddressAbsolute) {
238 
239  x->wrappedObject.set(kTTSym_address, x->address);
240 
241  // observe :description attribute
242  if (x->internals->lookup(TTSymbol(":description"), v))
243 
244  makeInternals_receiver(x, absoluteAddress, TTSymbol(":description"), gensym("return_description"), anObject, YES);
245 
246  else {
247  anObject = v[0];
248  anObject.set(kTTSym_address, absoluteAddress.appendAttribute(kTTSym_description));
249  }
250 
251  return;
252  }
253 
254  // for relative address
256 
257  // if no name is provided or can be edited in remote_attach() : use the address
258  if (EXTRA->name == kTTAdrsEmpty)
259  EXTRA->name = x->address;
260 
261  // if there is a context
262  if (x->patcherContext != kTTSymEmpty) {
263 
264  // Do we subscribe the Viewer ?
265  // View patcher case :
266  if (x->patcherContext == kTTSym_view) {
267 
268  // if the address refer to the j.model (only :attributeName) don't subscribe the Viewer
269  if (x->address.getParent() == NO_PARENT &&
270  x->address.getName() == NO_NAME &&
271  x->address.getInstance() == NO_INSTANCE &&
272  x->address.getAttribute() != NO_ATTRIBUTE)
273  err = jamoma_subscriber_create((t_object*)x, empty, x->address, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode);
274 
275  // if the address refer to the "model" node don't subscribe the Viewer (to not have model.1)
276  else if (x->address.getName() == TTSymbol("model"))
277  err = jamoma_subscriber_create((t_object*)x, empty, x->address, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode);
278 
279  // else try to subscribe the Viewer with its name
280  else
281  err = jamoma_subscriber_create((t_object*)x, x->wrappedObject, EXTRA->name, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode);
282 
283  }
284  // Model patcher case :
285  // try to binds on the parameter|message|return of the model without subscribing the Viewer
286  else if (x->patcherContext == kTTSym_model)
287  err = jamoma_subscriber_create((t_object*)x, empty, x->address, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode);
288 
289  // Any other case : give up
290  else
291  return;
292 
293  // if the subscription is succesfull
294  if (!err) {
295 
296  // get the context address to make
297  // a viewer on the contextAddress/model:address attribute
298  x->subscriberObject.get("contextAddress", v);
299  contextAddress = v[0];
300 
301  // observe model:address attribute (in view patcher : deferlow return_model_address)
302  makeInternals_receiver(x, contextAddress, TTSymbol("model:address"), gensym("return_model_address"), anObject, x->patcherContext == kTTSym_view);
303 
304  return;
305  }
306  }
307  // else, if no context, set address directly
308  else {
309  contextAddress = kTTAdrsRoot;
310  absoluteAddress = contextAddress.appendAddress(x->address);
311  x->wrappedObject.set(kTTSym_address, absoluteAddress);
312 
313  atom_setsym(a, gensym((char*)absoluteAddress.c_str()));
314  object_obex_dumpout((t_object*)x, gensym("address"), 1, a);
315 
316  // observe :description attribute
317  if (x->internals->lookup(TTSymbol(":description"), v))
318 
319  makeInternals_receiver(x, absoluteAddress, TTSymbol(":description"), gensym("return_description"), anObject, YES);
320 
321  else {
322  anObject = v[0];
323  anObject.set(kTTSym_address, absoluteAddress.appendAttribute(kTTSym_description));
324  }
325 
326  return;
327  }
328 
329  // otherwise while the context node is not registered : try to binds again :(
330  // (to -- this is not a good way todo. For binding we should make a subscription
331  // to a notification mechanism and each time an TTObjet subscribes to the namespace
332  // using jamoma_subscriber_create we notify all the externals which have used
333  // jamoma_subscriber_create with NULL object to bind)
334 
335  // release the subscriber
336  x->subscriberObject = TTObject();
337 
338  x->index++; // the index member is usefull to count how many time the external tries to bind
339  if (x->index > 100) {
340  object_error((t_object*)x, "couldn't bind to j.parameter %s", x->address.c_str());
341  object_obex_dumpout((t_object*)x, gensym("error"), 0, NULL);
342  return;
343  }
344 
345  // The following must be deferred because we have to interrogate our box,
346  // and our box is not yet valid until we have finished instantiating the object.
347  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
348  defer_low((t_object*)x, (method)remote_subscribe, NULL, 0, 0);
349 }
350 
351 void remote_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
352 {
354 
355  // a gate to not output the value if it have been set by this j.remote
356  if (EXTRA->setting) {
357  EXTRA->setting = NO;
358  return;
359  }
360 
361  // avoid blank before data
362  if (msg == _sym_nothing)
363  outlet_atoms(x->outlets[value_out], argc, argv);
364  else
365  outlet_anything(x->outlets[value_out], msg, argc, argv);
366 
367  // Copy msg and atom in order to avoid losing data
368  copy_msg_argc_argv(self, msg, argc, argv);
369 
370  qelem_set(EXTRA->ui_qelem);
371 }
372 
373 void remote_ui_queuefn(TTPtr self)
374 {
376 
377  if (x->argc && x->argv)
378  outlet_anything(x->outlets[set_out], _sym_set, x->argc, x->argv);
379 }
380 
381 void remote_bang(TTPtr self)
382 {
383  remote_list(self, _sym_bang, 0, NULL);
384 }
385 
386 void remote_int(TTPtr self, long value)
387 {
388  t_atom a;
389 
390  atom_setlong(&a, value);
391  remote_list(self, _sym_int, 1, &a);
392 }
393 
394 void remote_float(TTPtr self, double value)
395 {
396  t_atom a;
397 
398  atom_setfloat(&a, value);
399  remote_list(self, _sym_float, 1, &a);
400 }
401 
402 TTErr remote_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
403 {
405 
406  return jamoma_viewer_send(x->wrappedObject, msg, argc, argv);
407 }
408 
409 void remote_set(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
410 {
412 
413  EXTRA->setting = YES;
414 
415  if (remote_list(self, _sym_nothing, argc, argv))
416 
417  EXTRA->setting = NO;
418 }
419 
420 void WrappedViewerClass_anything(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
421 {
423  TTValue v;
424 
425  jamoma_viewer_send(x->wrappedObject, msg, argc, argv);
426 }
427 
428 void remote_return_model_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
429 {
431  TTAddress absoluteAddress;
432  TTObject anObject;
433  t_atom a[1];
434  TTSymbol service;
435  TTValue v;
436 
437  if (argc && argv && x->wrappedObject.valid()) {
438 
439  // set address attribute of the wrapped Viewer object
440  absoluteAddress = TTAddress(atom_getsym(argv)->s_name).appendAddress(x->address);
441  x->wrappedObject.set(kTTSym_address, absoluteAddress);
442  x->index = 0; // the index member is usefull to count how many time the external tries to bind
443 
444  // observe :description attribute
445  if (x->internals->lookup(TTSymbol(":description"), v))
446 
447  makeInternals_receiver(x, absoluteAddress, TTSymbol(":description"), gensym("return_description"), anObject, YES);
448 
449  else {
450  anObject = v[0];
451  anObject.set(kTTSym_address, absoluteAddress.appendAttribute(kTTSym_description));
452  }
453 
454  atom_setsym(a, gensym((char*)absoluteAddress.c_str()));
455  object_obex_dumpout((t_object*)x, gensym("address"), 1, a);
456 
457  JamomaDebug object_post((t_object*)x, "binds on %s", absoluteAddress.c_str());
458  }
459 }
460 
461 void remote_return_description(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
462 {
464 
465  // if an ui object is connected
466  if (EXTRA->connected)
467 
468  // set its annotation attribute
469  object_attr_setvalueof(EXTRA->connected, _sym_annotation , argc, argv);
470 }
471 
472 void remote_address(TTPtr self, t_symbol *address)
473 {
475 
476  x->address = TTAddress(jamoma_parse_dieze((t_object*)x, address)->s_name);
477 
478  // unsubscribe the remote before
479  if (x->subscriberObject.valid())
480  x->subscriberObject = TTObject();
481 
482  remote_subscribe(self);
483 }
484 
485 void remote_attach(TTPtr self, int attach_output_id)
486 {
488  t_outlet *myoutlet = NULL;
489  t_dll *connecteds = NULL;
490  t_object *object, *box;
491  t_symbol *maxclass = NULL;
492  long ac;
493  t_atom *av;
494 
495  // get the first object connected to the given outlet
496  object_obex_lookup(x, _sym_pound_B, &box);
497 
498  myoutlet = (t_outlet*)jbox_getoutlet((t_jbox*)box, attach_output_id);
499  if (myoutlet)
500  connecteds = (t_dll*)myoutlet->o_dll;
501 
502  if (connecteds) {
503 
504  object = (t_object*)connecteds->d_x1;
505 
506  // check object class
507  if (object)
508  maxclass = object_attr_getsym(object, _sym_maxclass);
509 
510  EXTRA->connected = object;
511  if (EXTRA->connected && maxclass) {
512 
513  // get presentation object size
514  ac = 0;
515  av = NULL;
516  object_attr_getvalueof(EXTRA->connected, _sym_presentation_rect , &ac, &av);
517  if (ac && av) {
518  EXTRA->x = atom_getlong(av+0);
519  EXTRA->y = atom_getlong(av+1);
520  EXTRA->w = atom_getlong(av+2);
521  EXTRA->h = atom_getlong(av+3);
522  }
523 
524  // if no name is provided : edit the name.instance part of the address and the name of the ui object
525  if (EXTRA->name == kTTAdrsEmpty) {
526 
527  TTString editName = x->address.c_str();
528  editName += "(";
529  editName += maxclass->s_name;
530  editName += ")";
531 
532  EXTRA->name = TTAddress(editName);
533  }
534  }
535  }
536 
537  // if no ui object are connected to :
538  if (!connecteds || !object || !maxclass) {
539 
540  // the set outlet
541  if (attach_output_id == set_out)
542 
543  // try to see at the data outlet
544  return remote_attach(self, value_out);
545 
546  // the value outlet
547  else if (attach_output_id == value_out)
548 
549  // try to see at the attach outlet
550  return remote_attach(self, attach_out);
551 
552  // the attach outlet
553  else
554 
555  // give up
556  return;
557  }
558 }
559 
560 // When the mouse is moving on the j.ui (not our remote object !)
561 void remote_mousemove(TTPtr self, t_object *patcherview, t_pt pt, long modifiers)
562 {
564  TTValue v;
565  TTBoolean selected;
566  t_object *patcher;
567  long ac;
568  t_atom *av;
569  t_atom a;
570 
571  if (EXTRA->connected) {
572 
573  // if the control key is pressed
574  if (modifiers & eShiftKey) {
575 
576  // hide gui
577  atom_setlong(&a, 1);
578  object_attr_setvalueof(EXTRA->connected, _sym_hidden, 1, &a);
579 
580  // create a comment object
581  if (!EXTRA->label) {
582  patcher = NULL;
583  ac = 0;
584  av = NULL;
585  object_obex_lookup(x, gensym("#P"), &patcher);
586  EXTRA->label = newobject_sprintf(patcher, "@maxclass comment @presentation 1 @textcolor 1. 1. 1. 1.");
587  object_attr_getvalueof(EXTRA->connected, _sym_presentation_rect , &ac, &av);
588  if (ac && av && EXTRA->label) {
589  object_method_long(EXTRA->label, _sym_fontsize, 10, &a);
590  object_method_sym(EXTRA->label, _sym_set, gensym((char*)x->address.c_str()), &a);
591  object_method_typed(EXTRA->label, _sym_presentation_rect, ac, av, &a);
592  }
593  }
594 
595  // display selected attribute by changing background color if selected
596  x->wrappedObject.get(kTTSym_highlight, v);
597  selected = v[0];
598 
599  if (EXTRA->label) {
600  if (selected)
601  object_attr_setvalueof(EXTRA->label, _sym_bgcolor, 4, (t_atom*)EXTRA->color1);
602  else
603  object_attr_setvalueof(EXTRA->label, _sym_bgcolor, 4, (t_atom*)EXTRA->color0);
604  }
605  }
606  // else set default color
607  // TODO : do this only one time !!!
608  else {
609 
610  // show gui
611  atom_setlong(&a, 0);
612  object_attr_setvalueof(EXTRA->connected, _sym_hidden, 1, &a);
613 
614  // delete label
615  if (EXTRA->label) {
616  object_free(EXTRA->label);
617  EXTRA->label = NULL;
618  }
619  }
620  }
621 }
622 
623 // When the mouse is leaving on the j.ui (not our remote object !)
624 void remote_mouseleave(TTPtr self, t_object *patcherview, t_pt pt, long modifiers)
625 {
627  t_atom a;
628 
629  // if mouse leaves j.ui maybe it is on our object
630  if (pt.x > EXTRA->x && pt.x < EXTRA->x+EXTRA->w && pt.y > EXTRA->y && pt.y < EXTRA->y+EXTRA->h)
631  return;
632 
633  // else the mouse leaves outside the j.ui
634  else {
635 
636  // show gui
637  atom_setlong(&a, 0);
638  object_attr_setvalueof(EXTRA->connected, _sym_hidden, 1, &a);
639 
640  // delete label
641  if (EXTRA->label) {
642  object_free(EXTRA->label);
643  EXTRA->label = NULL;
644  }
645  }
646 }
647 
648 void remote_mousedown(TTPtr self, t_object *patcherview, t_pt pt, long modifiers)
649 {
651  TTValue v;
652  TTBoolean selected;
653 
654  // if the control key is pressed
655  if (modifiers & eShiftKey) {
656 
657  // if mouse leave j.ui maybe it is on our object
658  if (pt.x > EXTRA->x && pt.x < EXTRA->x+EXTRA->w && pt.y > EXTRA->y && pt.y < EXTRA->y+EXTRA->h) {
659 
660  x->wrappedObject.get(kTTSym_highlight, v);
661  selected = v[0];
662 
663  // reverse selected attribute and change color
664  if (EXTRA->label) {
665  if (selected) {
666  x->wrappedObject.set(kTTSym_highlight, NO);
667  object_attr_setvalueof(EXTRA->label, _sym_bgcolor, 4, (t_atom*)EXTRA->color0);
668  }
669  else {
670  x->wrappedObject.set(kTTSym_highlight, YES);
671  object_attr_setvalueof(EXTRA->label, _sym_bgcolor, 4, (t_atom*)EXTRA->color1);
672  }
673  }
674  }
675  }
676 }
TTErr JAMOMA_EXPORT jamoma_patcher_get_info(t_object *obj, t_object **returnedPatcher, TTSymbol &returnedContext, TTSymbol &returnedClass, TTSymbol &returnedName)
Get all context info from an object (his patcher and the context, the class and the name of his patch...
TTAddress appendAddress(const TTAddress &toAppend)
Return a new TTAddress with the appended part.
Definition: TTAddress.h:167
TTObject subscriberObject
The instance of a TTSubscriber object used to register the wrapped object in the tree structure...
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
TTSymbol & getInstance()
Get the instance part.
Definition: TTAddress.h:124
TTAddress appendAttribute(TTSymbol anAttribute)
Return a new TTAddress with attribute part.
Definition: TTAddress.h:161
TTHandle outlets
an array of outlet
TTErr wrapTTModularClassAsMaxClass(TTSymbol &ttblueClassName, const char *maxClassName, WrappedClassPtr *c, ModularSpec *specificities)
Wrap a Jamoma class as a Max class.
TTErr lookup(const TTSymbol key, TTValue &value)
Find the value for the given key.
Definition: TTHash.cpp:76
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
TTAddress address
sometime external needs to store an address (e.g. send, receive, view, ...)
int C74_EXPORT main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
TTAddress getParent()
Get a pointer to the parent address.
Definition: TTAddress.h:112
TTSymbol patcherClass
the patcher class in which the external is
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
Data structure for storing extra data.
void * extra
used to keep very specific things
t_object * patcherPtr
the patcher in which the external is (ignoring subpatcher)
TTHashPtr internals
An hash table to store any internal TTObjectBases (like TTData, TTViewer, ...)
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
TTErr get(const TTSymbol aName, T &aReturnedValue) const
Get an attribute value for an object.
TTAddress name
the name to use for subscription
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
void copy_msg_argc_argv(TTPtr self, t_symbol *msg, long argc, const t_atom *argv)
tools to copy msg, argc and argv into the member msg, argc and argv of the WrappedModularInstance ...
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTPtr ui_qelem
to output "qlim'd" data for ui object
TTObject wrappedObject
The instance of the Jamoma object we are wrapping.
TTSymbol & getAttribute()
Get the attribute part.
Definition: TTAddress.h:130
this flag means that an address have a leading slash
Definition: TTAddressBase.h:65
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
Data Structure for this object.
TTErr JAMOMA_EXPORT jamoma_viewer_create(t_object *x, TTObject &returnedViewer)
Create a #TTViewer object.
TTAddressType getType()
Get the type.
Definition: TTAddress.h:136
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
Wraps Jamoma Core classes as objects for Max/MSP.
TTSymbol patcherContext
the patcher context in which the external is (model, view)
TTSymbol patcherName
the patcher name in which the external is
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...
The TTString class is used to represent a string.
Definition: TTString.h:34
long index
index of the inlet used
TTBoolean valid() const
Determine if the object contained by this TTObject is truly ready for use.
Definition: TTObject.cpp:179
TTSymbol & getName()
Get the name part.
Definition: TTAddress.h:118
TTErr JAMOMA_EXPORT jamoma_viewer_send(TTObject &aViewer, t_symbol *msg, long argc, const t_atom *argv)
Send Max data using a #TTViewer object.
WrappedModularInstance * WrappedModularInstancePtr
Pointer to a wrapped instance of our object.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34