Jamoma API  0.6.0.a19
Max/source/j.model/j.model.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.model / j.view - The main control center of Jamoma model and view patcher
6  *
7  * @details
8  *
9  * @authors Tim Place, Théo de la Hogue, Trond Lossius
10  *
11  * @copyright Copyright © 2010 by Tim Place and 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 
17 #include "j.model.h"
18 
19 int C74_EXPORT main(void)
20 {
21  ModularSpec *spec = new ModularSpec;
22  spec->_wrap = &WrapTTContainerClass;
23  spec->_new = &WrappedContainerClass_new;
24  spec->_free = &WrappedContainerClass_free;
25  spec->_any = &WrappedContainerClass_anything;
26 
27  TTModelInfo::registerClass();
28 
29 #ifndef JCOM_VIEW
30  return wrapTTModularClassAsMaxClass(kTTSym_Container, "j.model", NULL, spec);
31 #else
32  return wrapTTModularClassAsMaxClass(kTTSym_Container, "j.view", NULL, spec);
33 #endif
34 }
35 
36 void WrapTTContainerClass(WrappedClassPtr c)
37 {
38  class_addmethod(c->maxClass, (method)model_assist, "assist", A_CANT, 0L);
39 
40  class_addmethod(c->maxClass, (method)model_share_patcher_info, "share_patcher_info", A_CANT, 0);
41  class_addmethod(c->maxClass, (method)model_share_patcher_node, "share_patcher_node", A_CANT, 0);
42 
43  class_addmethod(c->maxClass, (method)model_return_address, "return_address", A_CANT, 0);
44  class_addmethod(c->maxClass, (method)model_return_value, "return_value", A_CANT, 0);
45 
46  class_addmethod(c->maxClass, (method)model_return_upper_view_model_address,"return_upper_view_model_address", A_CANT, 0);
47 
48  class_addmethod(c->maxClass, (method)model_address, "model_address", A_CANT, 0);
49 
50  class_addmethod(c->maxClass, (method)model_reference_write, "reference_write", A_CANT, 0);
51 
52  class_addmethod(c->maxClass, (method)model_preset_return_names, "return_names", A_CANT, 0);
53  class_addmethod(c->maxClass, (method)model_preset_filechanged, "filechanged", A_CANT, 0);
54 
55  class_addmethod(c->maxClass, (method)model_preset_read, "preset_read", A_CANT, 0);
56  class_addmethod(c->maxClass, (method)model_preset_write, "preset_write", A_CANT, 0);
57 
58  class_addmethod(c->maxClass, (method)model_preset_read_again, "preset_read_again", A_CANT, 0);
59  class_addmethod(c->maxClass, (method)model_preset_write_again, "preset_write_again", A_CANT, 0);
60 
61  class_addmethod(c->maxClass, (method)model_preset_edit, "dblclick", A_CANT, 0);
62  class_addmethod(c->maxClass, (method)model_preset_edclose, "edclose", A_CANT, 0);
63 #ifndef JCOM_VIEW
64  class_addmethod(c->maxClass, (method)model_preset_read, "preset:read", A_GIMME, 0);
65  class_addmethod(c->maxClass, (method)model_preset_write, "preset:write", A_GIMME, 0);
66  class_addmethod(c->maxClass, (method)model_preset_edit, "preset:edit", A_GIMME, 0);
67 
68  class_addmethod(c->maxClass, (method)model_preset_read_again, "preset:read/again", 0);
69  class_addmethod(c->maxClass, (method)model_preset_write_again, "preset:write/again", 0);
70 #endif
71  class_addmethod(c->maxClass, (method)model_signal_amenities, "input_created", A_CANT, 0);
72  class_addmethod(c->maxClass, (method)model_signal_amenities, "output_created", A_CANT, 0);
73 
74  class_addmethod(c->maxClass, (method)model_signal_return_data_active, "return_data_active", A_CANT, 0);
75  class_addmethod(c->maxClass, (method)model_signal_return_data_bypass, "return_data_bypass", A_CANT, 0);
76 
77  class_addmethod(c->maxClass, (method)model_signal_return_audio_mute, "return_audio_mute", A_CANT, 0);
78  class_addmethod(c->maxClass, (method)model_signal_return_audio_bypass, "return_audio_bypass", A_CANT, 0);
79  class_addmethod(c->maxClass, (method)model_signal_return_audio_mix, "return_audio_mix", A_CANT, 0);
80  class_addmethod(c->maxClass, (method)model_signal_return_audio_gain, "return_audio_gain", A_CANT, 0);
81 
82  CLASS_ATTR_ATOM(c->maxClass, "amenities", 0, WrappedModularInstance, extra);
83  CLASS_ATTR_DEFAULT(c->maxClass, "amenities", 0, "all");
84  CLASS_ATTR_ACCESSORS(c->maxClass, "amenities", model_get_amenities, model_set_amenities);
85  CLASS_ATTR_STYLE(c->maxClass, "amenities", 0, "text");
86 
87  CLASS_ATTR_ATOM(c->maxClass, "presets", 0, WrappedModularInstance, extra);
88  CLASS_ATTR_DEFAULT(c->maxClass, "presets", 0, "none");
89  CLASS_ATTR_ACCESSORS(c->maxClass, "presets", model_preset_get_presets, model_preset_set_presets);
90  CLASS_ATTR_STYLE(c->maxClass, "presets", 0, "text");
91 }
92 
93 void WrappedContainerClass_new(TTPtr self, long argc, t_atom *argv)
94 {
96  TTValue none;
97  t_object *aPatcher;
98 
99  // is there already a j.model or j.view in the patcher ?
100  jamoma_patcher_get_model_or_view(jamoma_patcher_get((t_object*)x), &aPatcher);
101 
102  if (aPatcher) {
103  object_error((t_object*)x, "can't have two models or views in the same patcher");
104  return;
105  }
106 
107  // create a container
108  jamoma_container_create((t_object*)x, x->wrappedObject);
109 
110 #ifndef JCOM_VIEW
111  x->patcherContext = kTTSym_model;
112  x->wrappedObject.set(kTTSym_service, kTTSym_model);
113 #else
114  x->patcherContext = kTTSym_view;
115  x->wrappedObject.set(kTTSym_service, kTTSym_view);
116 #endif
117 
118  // Make two outlets
119  x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr) * 1);
120  x->outlets[data_out] = outlet_new(x, NULL); // anything outlet to output data
121 
122  // Prepare extra data
123  x->extra = (t_extra*)malloc(sizeof(t_extra));
124  EXTRA->modelInfo = new TTObject();
125  EXTRA->containerAddress = kTTAdrsEmpty;
126  EXTRA->argAddress = kTTAdrsEmpty;
127  EXTRA->text = NULL;
128  EXTRA->textEditor = NULL;
129  EXTRA->presetManager = new TTObject();
130  EXTRA->attr_presets = kTTSym_none;
131  EXTRA->filewatcher = NULL;
132  EXTRA->toEdit = new TTObject();
133  *EXTRA->toEdit = x->wrappedObject;
134  EXTRA->presetName = kTTSymEmpty;
135  EXTRA->attr_amenities = new TTHash();
136  EXTRA->all_amenities = NO;
137  EXTRA->no_amenities = NO;
138 
139  EXTRA->attr_amenities->append(TTSymbol("all"), none);
140 
141  // handle attribute args
142  attr_args_process(x, argc, argv);
143 
144  // The following must be deferred because we have to interrogate our box,
145  // and our box is not yet valid until we have finished instantiating the object.
146  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
147  defer_low((t_object*)x, (method)model_subscribe, NULL, 0, 0);
148 }
149 
151 {
153  TTAddress modelAddress, presetAddress;
154  TTValue v, none;
155 
156  if (!EXTRA)
157  return;
158 
159  if (EXTRA->modelInfo->valid()) {
160 
161  modelAddress = EXTRA->containerAddress.appendAddress(TTAddress("model"));
162 
163  // remove the model node
164  JamomaApplication.send("ObjectUnregister", modelAddress, none);
165  }
166  delete EXTRA->modelInfo;
167 
168  if (EXTRA->presetManager->valid()) {
169 
170  presetAddress = EXTRA->containerAddress.appendAddress(TTAddress("preset"));
171 
172  // remove the preset node
173  JamomaApplication.send("ObjectUnregister", presetAddress, none);
174  }
175  delete EXTRA->presetManager;
176 
177  // delete filewatcher
178  if (EXTRA->filewatcher) {
179  filewatcher_stop(EXTRA->filewatcher);
180  object_free(EXTRA->filewatcher);
181  }
182 
183  delete EXTRA->toEdit;
184 
185  // unbind the container
186  x->wrappedObject.set(kTTSym_address, kTTSymEmpty);
187 
188  free(EXTRA);
189 }
190 
192 {
194  TTValue v, args, none;
195  TTNodePtr returnedNode = NULL;
196  TTNodePtr returnedContextNode = NULL;
197  TTObject aReceiver;
198  TTObject aTextHandler;
199  TTBoolean isSubModel;
200  TTAddress returnedAddress, adrs;
201  TTSymbol description;
202  long ac;
203  t_atom* av;
204  t_atom a;
205  t_object* aPatcher = jamoma_patcher_get((t_object*)x);
206 
207  // if the subscription is successful
208  if (!jamoma_subscriber_create((t_object*)x, x->wrappedObject, kTTAdrsEmpty, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode)) {
209 
210  // get all info relative to our patcher
212 
213  // set the address attribute of the Container
214  x->wrappedObject.set(kTTSym_address, returnedAddress);
215 
216  // keep the address for model_free (because the wrappedObject will be freed before)
217  EXTRA->containerAddress = returnedAddress;
218 
219  // set annotation attribute of the patcher using description attribute
220  x->wrappedObject.get(kTTSym_description, v);
221  description = v[0];
222  atom_setsym(&a, gensym(description.c_str()));
223  object_attr_setvalueof(jpatcher_get_box(x->patcherPtr), _sym_annotation , 1, &a);
224 
225  // if the j.model|j.view is well subscribed
226  if (aPatcher == x->patcherPtr && x->patcherContext != kTTSymEmpty) {
227 
228  // create a model object (for j.view too !)
229  *EXTRA->modelInfo = TTObject("ModelInfo", (TTPtr)x);
230 
231  // set his class attribute
232  EXTRA->modelInfo->set("class", x->patcherClass);
233 
234  // suscribe it under a model node
235  adrs = returnedAddress.appendAddress(TTAddress("model"));
236  args = TTValue(adrs, *EXTRA->modelInfo, x->patcherPtr);
237 
238  if (JamomaApplication.send("ObjectRegister", args, none))
239  object_error((t_object*)x, "can't subscribe model object");
240 
241  // In model patcher : set model:address with the model address
242  if (x->patcherContext == kTTSym_model) {
243 
244  EXTRA->modelInfo->set(kTTSym_address, returnedAddress);
245 
246  // then set the address attribute readOnly
247  TTModelInfoPtr(EXTRA->modelInfo->instance())->setAddressReadOnly(YES);
248  }
249 
250  // Get patcher arguments
251  ac = 0;
252  av = NULL;
253 
254  // If x is in a bpatcher, the patcher is NULL
255  // AV : aPatcher can't be NULL since it's checked in the if statement above
256  // TODO fixme
257  if (!aPatcher)
258  aPatcher = object_attr_getobj(x, _sym_parentpatcher);
259 
260  jamoma_patcher_get_args(aPatcher, &ac, &av);
261 
262  // check if it's a sub model
263  isSubModel = atom_getsym(av) == _sym_p;
264 
265  // in subpatcher :
266  if (jamoma_patcher_get_hierarchy(aPatcher) == _sym_subpatcher) {
267 
268  // remove first 'p' or 'patcher'
269  if (ac > 0 && av) {
270  if (atom_getsym(av) == _sym_p || atom_getsym(av) == _sym_patcher) {
271  ac--;
272  av++;
273  }
274  }
275 
276  // remove the next argument because it is the class
277  ac--;
278  av++;
279  }
280 
281  // j.model case :
282  if (x->patcherContext == kTTSym_model) {
283 
284  // use patcher arguments to setup the model attributes (like @priority and @amenities)
285  if (ac && av)
286  attr_args_process(x, ac, av);
287 
288  // Create internal TTTextHandler (for documention and preset management)
289  aTextHandler = TTObject(kTTSym_TextHandler);
290  x->internals->append(kTTSym_TextHandler, aTextHandler);
291 
292  if (!EXTRA->attr_amenities->lookup(TTSymbol("all"), v))
293  EXTRA->all_amenities = YES;
294 
295  if (!EXTRA->attr_amenities->lookup(TTSymbol("none"), v))
296  EXTRA->no_amenities = YES;
297 
298  // Add amenities relative to preset informations
299  if (model_test_amenities(self, TTSymbol("preset")))
300 
301  // add preset managment features
303 
304  // Add amenities relative to signal informations
305  if (model_test_amenities(self, TTSymbol("data")) || model_test_amenities(self, TTSymbol("audio"))) {
306 
307  // look at model's content to create signal in/out datas
308  model_signal_amenities(self, _sym_nothing, 0, NULL);
309 
310  }
311  }
312 
313  // In view patcher : see in model_subscribe_view
314  if (x->patcherContext == kTTSym_view)
315  model_subscribe_view(self, _sym_nothing, ac, av);
316 
317  // output node address
318  t_atom a;
319  x->subscriberObject.get("nodeAddress", v);
320 
321  if (v.size() == 1) {
322  returnedAddress = v[0];
323  atom_setsym(&a, gensym((char*)returnedAddress.c_str()));
324  object_obex_dumpout(self, gensym("address"), 1, &a);
325  }
326 
327  // init the model (but not subModel) or any model registered under the root
328  if (!isSubModel || returnedContextNode->getParent()->getContext() == accessApplicationLocalDirectory->getRoot()->getContext())
329  defer_low(x, (method)model_init, 0, 0, 0L);
330  }
331  }
332 }
333 
334 void model_subscribe_view(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
335 {
337  TTObject aReceiver;
338  t_symbol* hierarchy;
339  t_object* aPatcher;
340  TTList whereToSearch;
341  TTBoolean isThere;
342  TTNodePtr firstTTNode;
343  TTAddress modelAdrs, argAdrs, viewAdrs;
344  TTValue v;
345 
346  // look at hierarchy
348 
349  // if args exists, the first argument of the patcher is the model:address value
350  if (argc > 0 && atom_gettype(argv) == A_SYM) {
351 
352  argAdrs = TTAddress(atom_getsym(argv)->s_name);
353 
354  // in poly case : use the same instance as the container address
355  if (hierarchy == gensym("poly"))
356  if (argAdrs.getInstance() == kTTSymEmpty)
357  argAdrs = argAdrs.appendInstance(EXTRA->containerAddress.getInstance());
358 
359  // if the address is absolute : use it directly
360  if (argAdrs.getType() == kAddressAbsolute) {
361 
362  // set the model:address attribute to notify all observers
363  EXTRA->modelInfo->set(kTTSym_address, argAdrs);
364  return;
365  }
366 
367  // in case of relative address : try to use the upper view patcher model:address (else use root)
368  else {
369 
370  // if there is a parent view address : get the upper view address
371  if (EXTRA->containerAddress.getParent() != kTTAdrsRoot) {
372 
373  // keep the argument address
374  EXTRA->argAddress = argAdrs;
375 
376  // observe the selected view model:address attribute
377  makeInternals_receiver(self, EXTRA->containerAddress.getParent(), TTAddress("model:address"), gensym("return_upper_view_model_address"), aReceiver, YES); // we need to deferlow to avoid lock crash on TTContainer content
378  }
379  // use the argument address as an absolute address
380  else {
381 
382  // set the model:address attribute to notify all observers
383  EXTRA->modelInfo->set(kTTSym_address, kTTAdrsRoot.appendAddress(argAdrs));
384  return;
385  }
386  }
387  }
388  // else look around the patcher for model of the same class
389  else {
390 
391  // look for a model of the same class into the patcher of the bpatcher to get his model:address
393 
394  // if a model exists
395  if (aPatcher) {
396 
397  // is there a container (e.g. a j.model) registered with the same context in this model patcher ?
398  whereToSearch.append(accessApplicationLocalDirectory->getRoot());
399  accessApplicationLocalDirectory->IsThere(&whereToSearch, &testNodeContext, (TTPtr)aPatcher, &isThere, &firstTTNode);
400 
401  if (isThere) {
402 
403  firstTTNode->getAddress(modelAdrs);
404 
405  // set the model:address attribute to notify all observers
406  EXTRA->modelInfo->set(kTTSym_address, modelAdrs);
407  return;
408  }
409 
410  // deferlow to try another time because the model patcher is maybe not ready
411  else {
412 
413  defer_low((t_object*)x, (method)model_subscribe_view, _sym_nothing, argc, argv);
414  return;
415  }
416  }
417  }
418 
419  // check if the model address have been filled or not (see in model_return_upper_view_model_address)
420  EXTRA->modelInfo->get(kTTSym_address, v);
421  modelAdrs = v[0];
422 
423  // if the model:address is still empty : the view is not binding a model for instant
424  if (modelAdrs == kTTSymEmpty)
425  modelAdrs = TTAddress("/no_model_address");
426 
427  // set the model:address attribute to notify all observers
428  EXTRA->modelInfo->set(kTTSym_address, modelAdrs);
429 }
430 
431 void model_return_upper_view_model_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
432 {
434  TTAddress upperViewModelAddress;
435  TTValue v, o, out;
436 
437  jamoma_ttvalue_from_Atom(v, msg, argc, argv);
438  upperViewModelAddress = v[0];
439 
440  // append argAddress stored in model_view_subscribe
441  if (upperViewModelAddress != kTTSymEmpty)
442  upperViewModelAddress = upperViewModelAddress.appendAddress(EXTRA->argAddress);
443  else
444  upperViewModelAddress = kTTAdrsRoot.appendAddress(EXTRA->argAddress);
445 
446  // set the model:address attribute to notify all observers
447  EXTRA->modelInfo->set(kTTSym_address, upperViewModelAddress);
448 }
449 
450 void model_init(TTPtr self)
451 {
453  TTBoolean initialized;
454  TTValue v;
455 
456  // Check if the model has not been initialized by a upper model
457  x->wrappedObject.get(kTTSym_initialized, v);
458  initialized = v[0];
459  if (!initialized)
460  x->wrappedObject.send(kTTSym_Init);
461 }
462 
463 // Method for Assistance Messages
464 void model_assist(TTPtr self, void *b, long msg, long arg, char *dst)
465 {
467 
468  if (msg==1) // Inlets
469  strcpy(dst, "");
470  else { // Outlets
471  switch(arg) {
472  case data_out:
473  if (x->patcherContext == kTTSym_model)
474  strcpy(dst, "model feeback");
475  else if (x->patcherContext == kTTSym_view)
476  strcpy(dst, "view feeback");
477  else
478  strcpy(dst, "feeback");
479  break;
480  case dump_out:
481  strcpy(dst, "dumpout");
482  break;
483  }
484  }
485 }
486 
488 {
490  patcherInfo->clear();
491 
492  if (x->patcherPtr && x->patcherContext != kTTSymEmpty && x->patcherClass != kTTSymEmpty && x->patcherName != kTTSymEmpty) {
493  patcherInfo->append((TTPtr)x->patcherPtr);
494  patcherInfo->append(x->patcherContext);
495  patcherInfo->append(x->patcherClass);
496  patcherInfo->append(x->patcherName);
497  }
498 }
499 
500 void model_share_patcher_node(TTPtr self, TTNodePtr *patcherNode)
501 {
503  TTValue v;
504 
505  if (x->subscriberObject.valid()) {
506  x->subscriberObject.get("contextNode", v);
507  *patcherNode = TTNodePtr((TTPtr)v[0]);
508  }
509 }
510 
511 void WrappedContainerClass_anything(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
512 {
514 
515  // the msg have to contains a relative address
516  jamoma_container_send(x->wrappedObject, msg, argc, argv);
517 }
518 
519 void model_return_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
520 {
522 
523  // store the address temporary into msg member to use it into model_return_value()
524  x->msg = msg;
525 }
526 
527 void model_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
528 {
530 
531  // using the temporay address stored previously into msg member in model_return_address()
532  outlet_anything(x->outlets[data_out], x->msg, argc, argv);
533 }
534 
535 void model_reference_write(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
536 {
537  defer(self, (method)model_reference_dowrite, msg, argc, argv);
538 }
539 
540 void model_reference_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
541 {
543  char filename[MAX_FILENAME_CHARS];
544  TTSymbol fullpath;
545  TTValue o, v, none;
546  TTObject aTextHandler;
547  TTErr tterr;
548 
549  if (x->wrappedObject.valid()) {
550 
551  // Default HTML file name
552  snprintf(filename, MAX_FILENAME_CHARS, DocumentationFormat->data(), x->patcherClass.c_str());
553  fullpath = jamoma_file_write((t_object*)x, argc, argv, filename);
554  v.append(fullpath);
555 
556  tterr = x->internals->lookup(kTTSym_TextHandler, o);
557 
558  if (!tterr) {
559  aTextHandler = o[0];
560 
561  aTextHandler.set(kTTSym_object, x->wrappedObject);
562 
563  critical_enter(0);
564  aTextHandler.send(kTTSym_Write, v, none);
565  critical_exit(0);
566  }
567  }
568 }
569 
570 void model_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
571 {
573 
574  // In view patcher only
575  if (x->patcherContext == kTTSym_view) {
576 
577  if (atom_gettype(argv) == A_SYM) {
578 
579  TTAddress modelAdrs = TTAddress(atom_getsym(argv)->s_name);
580 
581  // set the model:address attribute to notify all observers
582  EXTRA->modelInfo->set(kTTSym_address, modelAdrs);
583  }
584  }
585 }
586 
587 t_max_err model_get_amenities(TTPtr self, TTPtr attr, long *ac, t_atom **av)
588 {
590  TTValue keys;
591 
592  EXTRA->attr_amenities->getKeysSorted(keys);
593 
594  if ((*ac)&&(*av)) {
595  //memory passed in, use it
596  } else {
597 
598  //otherwise allocate memory
599  *ac = keys.size();
600  if (!(*av = (t_atom*)getbytes(sizeof(t_atom)*(*ac)))) {
601  *ac = 0;
602  return MAX_ERR_OUT_OF_MEM;
603  }
604  }
605 
606  jamoma_ttvalue_to_Atom(keys, ac, av);
607 
608  return MAX_ERR_NONE;
609 }
610 
611 t_max_err model_set_amenities(TTPtr self, TTPtr attr, long ac, t_atom *av)
612 {
614  TTValue keys, none;
615  TTSymbol key;
616 
617  EXTRA->attr_amenities->clear();
618 
619  if (ac&&av) {
620 
621  jamoma_ttvalue_from_Atom(keys, _sym_nothing, ac, av);
622 
623  for (TTUInt8 i = 0; i < keys.size(); i++) {
624 
625  key = keys[i];
626  EXTRA->attr_amenities->append(key, none);
627  }
628  }
629  else
630  EXTRA->attr_amenities->append(TTSymbol("all"), none); // default all
631 
632  return MAX_ERR_NONE;
633 }
634 
636 {
638  TTValue v;
639 
640  return !EXTRA->no_amenities && (EXTRA->all_amenities || !EXTRA->attr_amenities->lookup(name, v));
641 }
void JAMOMA_EXPORT jamoma_patcher_get_args(t_object *patcher, long *argc, t_atom **argv)
Convenient method to get the patcher argument easily.
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...
void model_signal_return_audio_mix(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
TTAddress appendAddress(const TTAddress &toAppend)
Return a new TTAddress with the appended part.
Definition: TTAddress.h:167
t_max_err model_preset_set_presets(TTPtr self, TTPtr attr, long ac, const t_atom *av)
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
void WrappedContainerClass_new(TTPtr self, long argc, t_atom *argv)
Constructor: Initiate the wrapped object instance.
TTErr send(const TTSymbol aName)
Send a message to this object with no arguments.
Definition: TTObject.cpp:135
TTSymbol & getInstance()
Get the instance part.
Definition: TTAddress.h:124
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.
void model_return_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void model_preset_return_names(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
TTErr lookup(const TTSymbol key, TTValue &value)
Find the value for the given key.
Definition: TTHash.cpp:76
void model_signal_amenities(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
We build a directory of TTNodes, and you can request a pointer for any TTNode, or add an observer to ...
Definition: TTNode.h:59
TTSymbol patcherClass
the patcher class in which the external is
TTPtr getContext()
Get a pointer to the context of this node.
Definition: TTNode.cpp:473
void model_preset_amenities(TTPtr self)
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 model_preset_edclose(TTPtr self, char **text, long size)
void model_reference_write(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
size_type size() const noexcept
Return the number of elements.
TTErr JAMOMA_EXPORT jamoma_container_send(TTObject &aContainer, t_symbol *relativeAddressAndAttribute, long argc, const t_atom *argv)
Send Max data to a node (e.g., a j.parameter object) using a TTContainer object.
Data structure for storing extra data.
void model_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void * extra
used to keep very specific things
TTAddress appendInstance(const TTSymbol anInstance)
Return a new TTAddress with a instance part.
Definition: TTAddress.h:173
t_object JAMOMA_EXPORT * jamoma_patcher_get(t_object *obj)
Convenient method to get the patcher easily.
t_object * patcherPtr
the patcher in which the external is (ignoring subpatcher)
void model_preset_edit(TTPtr self, t_symbol *msg, long argc, const t_atom *argv)
void model_signal_return_audio_mute(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
TTHashPtr internals
An hash table to store any internal TTObjectBases (like TTData, TTViewer, ...)
void WrappedContainerClass_anything(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void model_share_patcher_node(TTPtr self, TTNodePtr *patcherNode)
Maintain a collection of TTValue objects indexed by TTSymbol pointers.
Definition: TTHash.h:36
void model_subscribe(TTPtr self)
void model_signal_return_audio_gain(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
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.
void WrappedContainerClass_free(TTPtr self)
Deconstructor: Destroy the object and free memory assigned to it.
void JAMOMA_EXPORT jamoma_ttvalue_to_Atom(const TTValue &v, long *argc, t_atom **argv)
Make an Atom array from a TTValue.
t_max_err model_set_amenities(TTPtr self, TTPtr attr, long ac, t_atom *av)
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTSymbol JAMOMA_EXPORT jamoma_file_write(t_object *x, long argc, const t_atom *argv, char *default_filename)
Get BOOT style filepath from args or, if no args open a dialog to write a file.
void model_preset_write_again(TTPtr self)
TTObject wrappedObject
The instance of the Jamoma object we are wrapping.
void model_preset_read_again(TTPtr self)
this flag means that an address have a leading slash
Definition: TTAddressBase.h:65
void model_assist(TTPtr self, void *b, long msg, long arg, char *dst)
Display assist messages for inlets and outlets in Max.
void model_subscribe_view(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
TTErr JAMOMA_EXPORT jamoma_container_create(t_object *x, TTObject &returnedContainer)
Create a TTContainer object.
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
void WrapTTContainerClass(WrappedClassPtr c)
Set up what methods (Max messages) that the wrapped class is to respond to.
TTBoolean model_test_amenities(TTPtr self, TTSymbol name)
void JAMOMA_EXPORT jamoma_ttvalue_from_Atom(TTValue &v, t_symbol *msg, long argc, const t_atom *argv)
Make a TTValue from Atom array.
j.model / j.view - The main control center of Jamoma model and view patcher
void clear()
Clear all values from the vector, leaving with size of 0.
Definition: TTValue.h:131
void model_preset_filechanged(TTPtr self, char *filename, short path)
t_max_err model_preset_get_presets(TTPtr self, TTPtr attr, long *ac, t_atom **av)
int C74_EXPORT main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
void model_preset_write(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
TTErr getAddress(TTAddress &returnedAddress, TTAddress from=kTTAdrsEmpty)
Get the address of the node.
Definition: TTNode.cpp:478
Data Structure for this 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
TTSymbol patcherContext
the patcher context in which the external is (model, view)
A base class for Jamoma models.
void model_init(TTPtr self)
void model_signal_return_data_active(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void JAMOMA_EXPORT jamoma_patcher_get_model_patcher(t_object *patcher, TTSymbol modelClass, t_object **returnedModelPatcher)
Get the "aClass.model" external in the patcher.
t_symbol JAMOMA_EXPORT * jamoma_patcher_get_hierarchy(t_object *patcher)
Get the hierarchy of the patcher : bpatcher, subpatcher or toplevel.
TTSymbol patcherName
the patcher name in which the external is
void model_share_patcher_info(TTPtr self, TTValuePtr patcherInfo)
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...
void model_signal_return_audio_bypass(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void model_preset_read(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void model_signal_return_data_bypass(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void model_reference_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
TTBoolean valid() const
Determine if the object contained by this TTObject is truly ready for use.
Definition: TTObject.cpp:179
void model_return_upper_view_model_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
WrappedModularInstance * WrappedModularInstancePtr
Pointer to a wrapped instance of our object.
#define accessApplicationLocalDirectory
Access to the local application directory.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
t_max_err model_get_amenities(TTPtr self, TTPtr attr, long *ac, t_atom **av)
TTNodePtr getParent()
Get a pointer to the parent node of the node.
Definition: TTNode.cpp:296
void model_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void JAMOMA_EXPORT jamoma_patcher_get_model_or_view(t_object *patcher, t_object **returnedModelOrView)
Get j.model or j.view of a patcher.
unsigned char TTUInt8
8 bit unsigned integer (char)
Definition: TTBase.h:174