Jamoma API  0.6.0.a19
JamomaModularForPd.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationPdLibrary
4  *
5  * @brief JamomaModular For Max Shared Library
6  *
7  * @details Functions and resources based on Modular framework used by Max objects
8  *
9  * @authors Théo de la Hogue, Tim Place, Trond Lossius, Antoine Villeret
10  *
11  * @copyright © 2013, Théo de la Hogue & Tim Place @n
12  * Copyright © 2015, Antoine Villeret@n
13  * This code is licensed under the terms of the "New BSD License" @n
14  * http://creativecommons.org/licenses/BSD/
15  */
16 
17 #include "JamomaModularForPd.h"
18 
19 /***********************************************************************************
20 *
21 * C EXTERN METHODS
22 *
23 ************************************************************************************/
24 
25 // prototypes
26 void jamoma_subscriber_fill_list(TTList& listToFill, TTAddress address, TTPtr pointer);
27 
28 
29 // Method to deal with TTSubscriber
30 ///////////////////////////////////////////////////////////////////////
31 
32 TTErr jamoma_subscriber_create(t_eobj *x, TTObject& anObject, TTAddress relativeAddress, TTObject& returnedSubscriber, TTSymbol& returnedAddress, TTNodePtr *returnedNode, TTNodePtr *returnedContextNode)
33 {
34  TTValue v, args;
35  TTList aContextList;
36  TTAddress newRelativeAddress, newContextAddress;
37  TTBoolean newInstance, newContextInstance;
38  TTErr err;
39 
40  // prepare arguments
41  args.append(anObject);
42  args.append(relativeAddress);
43 
44  returnedSubscriber = TTObject(kTTSym_Subscriber, args);
45 
46  // Get all Context above the object and their name
47  jamoma_subscriber_get_patcher_list(x, aContextList);
48  args = TTValue((TTPtr)&aContextList);
49 
50  *returnedNode = NULL;
51  err = returnedSubscriber.send(kTTSym_Subscribe, args, v);
52 
53  if (v.size() == 2) {
54  *returnedNode = TTNodePtr((TTPtr)v[0]);
55  *returnedContextNode = TTNodePtr((TTPtr)v[1]);
56  }
57 
58  // Check if the subscription is ok (or the binding in case of NULL object)
59  if (!err && *returnedNode) {
60 
61  if (anObject.valid()) {
62 
63  // Is a new instance have been created ?
64  returnedSubscriber.get("newInstanceCreated", v);
65  newInstance = v[0];
66 
67  // Is a new context instance have been created ?
68  returnedSubscriber.get("newContextInstanceCreated", v);
69  newContextInstance = v[0];
70 
71  // warn the user he has an object with duplicate instance
72  if (newInstance) {
73 
74  returnedSubscriber.get("relativeAddress", v);
75  newRelativeAddress = v[0];
76  verbose(PD_LOG_WARN, "Jamoma cannot register multiple objects with the same OSC identifier (%s). Using %s instead.", relativeAddress.c_str(), newRelativeAddress.c_str());
77  }
78 
79  // check why a new context instance have been created
80  if (newContextInstance) {
81 
82  returnedSubscriber.get("contextAddress", v);
83  newContextAddress = v[0];
84 
85  t_canvas *patcher;
86  TTSymbol patcherContext;
87  TTSymbol patcherClass;
88  TTSymbol patcherName;
89  TTAddress patcherArg;
90  TTString newPatcherArgument;
91  long argc = 0;
92  t_atom * argv = NULL;
93 
94  // get patcher info
95  jamoma_patcher_get_info(x->o_canvas, &patcher, patcherContext, patcherClass, patcherName);
96 
97  // get patcher argument (dedicated for the name)
98  jamoma_patcher_get_args(patcher, &argc, &argv);
99 
100  if (patcherContext == kTTSym_model && argc == 1) {
101 
102  if ((argv+1)->a_type == A_SYMBOL)
103  patcherArg = TTAddress(atom_getsymbol(argv+1)->s_name);
104  }
105  else if (patcherContext == kTTSym_view && argc == 2) {
106 
107  if ((argv+2)->a_type == A_SYMBOL)
108  patcherArg = TTAddress(atom_getsymbol(argv+2)->s_name);
109  }
110 
111  // free args
112  free(argv);
113 
114  // warn the user that it should provide unique name
115 
116  // if no name has been provided
117  if (patcherArg == kTTAdrsEmpty && patcherContext == kTTSym_model)
118  verbose(PD_LOG_WARN, "No name provided to %s %s. Using %s.", patcherClass.c_str(), patcherContext.c_str(), newContextAddress.getNameInstance().c_str());
119 
120  // if a duplicate name.instance was passed in argument
121  else
122  verbose(PD_LOG_WARN, "Duplicate name provided to %s %s (%s). Using %s.", patcherClass.c_str(), patcherContext.c_str(), patcherArg.c_str(), newContextAddress.getNameInstance().c_str());
123 
124  }
125 
126  returnedSubscriber.get(kTTSym_nodeAddress, v);
127  returnedAddress = v[0];
128 
129  JamomaDebug post("registers at %s", returnedAddress.c_str());
130  }
131 
132  return kTTErrNone;
133  }
134 
135  if (anObject.valid())
136  pd_error(x, "Jamoma cannot registers %s", relativeAddress.c_str());
137  else
138  // don't display this message because the objects can try many times before to binds
139  ; //pd_error(x, "Jamoma cannot binds %s", relativeAddress->s_name);
140 
141  return kTTErrGeneric;
142 }
143 
144 
145 /** Get the hierarchy of the patcher : bpatcher, subpatcher or top level one*/
146 t_symbol *jamoma_patcher_get_hierarchy(t_canvas *canvas)
147 {
148  if ( canvas->gl_owner == NULL )
149  return _sym_topmost;
150  else if ( canvas->gl_isgraph )
151  return _sym_bpatcher;
152  else return _sym_subpatcher;
153 }
154 
155 /** Parse #N inside address and replace them by parent patcher arguments if there are */
156 t_symbol *jamoma_parse_dieze(t_canvas *x, t_symbol *address)
157 {
158  TTString diezeStr, argsStr, addressStr = address->s_name;
159  t_symbol *hierarchy;
160  t_canvas *patcher = x;
161  /* TODO : use a TTRegex for this parsing
162  char dieze[5];
163  char args[64];
164  size_t found = 0;
165  long i, sd, sa;
166  */
167  long i;
168  long ac = 0;
169  t_atom *av = NULL;
170 
171  // If x is in a bpatcher, the patcher is NULL
172  if (!patcher){
173  patcher = (t_canvas*)object_attr_getobj(x, _sym_parentpatcher);
174  }
175 
176  if (patcher) {
177 
178  hierarchy = jamoma_patcher_get_hierarchy(patcher);
179 
180  // Try to get the patcher arguments
181  jamoma_patcher_get_args(patcher, &ac, &av);
182  if (hierarchy == _sym_subpatcher) {
183 
184  // remove first 'pd'
185  if (ac > 0 && av) {
186  if (atom_getsym(av) == _sym_pd) {
187  ac--;
188  av++;
189  }
190  }
191 
192  av++;
193  ac--;
194  }
195 
196  // if there are arguments
197  if (ac > 0 && av) {
198 
199  i = 1;
200 
201  //object_post(x, "in jamoma_parse_dieze : TODO : use a TTRegex for this parsing");
202  /* TODO : use a TTRegex for this parsing
203  do {
204 
205  // prepare to parse #i
206  snprintf(dieze, sizeof(dieze), "#%li", i);
207  found = addressStr.find(dieze);
208 
209  // if #i found
210  if (found != string::npos) {
211 
212  // get av+i atom
213  if (i-1 < ac) {
214 
215  if (atom_gettype(av+i-1) == A_LONG)
216  snprintf(args, sizeof(args), "%li", atom_getlong(av+i-1));
217  else if (atom_gettype(av+i-1) == A_SYM)
218  snprintf(args, sizeof(args), "%s", atom_getsym(av+i-1)->s_name);
219  else {
220  i++;
221  continue;
222  }
223 
224  diezeStr = dieze;
225  argsStr = args;
226  sd = diezeStr.size();
227  sa = argsStr.size();
228  addressStr.replace(found, sd, args, sa);
229  }
230  }
231  i++;
232 
233  } while (i-1 < ac); // while there are argument
234  */
235 
236  return gensym((char*)addressStr.data());
237  }
238  }
239 
240  return address;
241 }
242 
243 void jamoma_subscriber_get_patcher_list(t_eobj *x, TTList& aContextListToFill)
244 {
245  TTValue v;
246  t_canvas *objPtr = x->o_canvas;
247  t_canvas *patcherPtr = NULL;
248  TTSymbol patcherContext;
249  TTSymbol patcherName;
250  TTSymbol patcherClass;
251  TTSymbol lowerContext;
252 
253  // Edit the list of all patcher's name and pointer
254  // above the object x looking at all parent patcher
255  do {
256  // get all info from the current object
257  jamoma_patcher_get_info(objPtr, &patcherPtr, patcherContext, patcherClass, patcherName);
258 
259  if (patcherName && patcherPtr) {
260  /* théo - when commenting this part we allow to subscribe view into model and model into view
261  // check if the patcher have the same context than lower patchers
262  if (patcherContext == lowerContext || lowerContext == kTTSymEmpty) {
263 
264  // keep it as lowerContext
265  lowerContext = patcherContext;
266  */
267  // store each name.instance part of the patcherName (level.i/sub.j/name.k)
268  jamoma_subscriber_fill_list(aContextListToFill, TTAddress(patcherName), patcherPtr);
269 
270  // replace current object by his parent patcher
271  objPtr = patcherPtr->gl_owner;
272  /* théo - when commenting this part we allow to subscribe view into model and model into view
273  }
274  else {
275 
276  // skip the patcher to go directly to an upper one
277  objPtr = patcherPtr;
278  }
279  */
280  }
281  else
282  break;
283 
284  } while (jamoma_patcher_get_hierarchy(patcherPtr) != _sym_topmost);
285 }
286 
287 void jamoma_subscriber_fill_list(TTList& listToFill, TTAddress address, TTPtr pointer)
288 {
289  TTSymbol level = address.getNameInstance();
290  TTValue v(level, pointer);
291  listToFill.insert(0, v);
292 
293  TTAddress parent = address.getParent();
294  if (parent != kTTAdrsEmpty)
295  jamoma_subscriber_fill_list(listToFill, parent, pointer);
296 }
297 
298 // Method to deal with TTContainer
299 ///////////////////////////////////////////////////////////////////////
300 
301 /** Create a container object */
302 TTErr jamoma_container_create(t_object *x, TTObject& returnedContainer)
303 {
304  TTValue args, none;
305  TTObject returnAddressCallback, returnValueCallback;
306 
307  // prepare arguments
308  returnAddressCallback = TTObject("callback");
309  returnAddressCallback.set(kTTSym_baton, TTPtr(x));
310  returnAddressCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_address));
311  args.append(returnAddressCallback);
312 
313  returnValueCallback = TTObject("callback");
314  returnValueCallback.set(kTTSym_baton, TTPtr(x));
315  returnValueCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
316  args.append(returnValueCallback);
317 
318  returnedContainer = TTObject(kTTSym_Container, args);
319 
320  return kTTErrNone;
321 }
322 
323 /** Send Max data to a node (e.g., a j.parameter object) using a container object. */
324 TTErr jamoma_container_send(TTObject& aContainer, t_symbol *relativeAddressAndAttribute, long argc, const t_atom *argv)
325 {
326  TTAddress anAddress;
327  TTValue v, data, none;
328 
329  if (aContainer.valid()) {
330 
331  anAddress = relativeAddressAndAttribute->s_name;
332 
333  if (anAddress.getType() != kAddressRelative) {
334  error("%s is an absolute address", relativeAddressAndAttribute->s_name);
335  return kTTErrGeneric;
336  }
337 
338  // Are we to send a message to an attribute of the node? If not we'll send the message to the value attribute of the node, so that the node value gets updated.
339  if (anAddress.getAttribute() == NO_ATTRIBUTE)
340  anAddress = anAddress.appendAttribute(kTTSym_value);
341  else
342  anAddress = anAddress.appendAttribute(ToTTName(anAddress.getAttribute()));
343 
344  data.append(anAddress);
345 
346  jamoma_ttvalue_from_Atom(v, _sym_nothing, argc, argv);
347  data.append((TTPtr)&v);
348 
349  // data is [address, attribute, [x, x, ,x , ...]]
350  return aContainer.send(kTTSym_Send, data, none);
351  }
352 
353  return kTTErrGeneric;
354 }
355 
356 // Method to deal with #TTNodeInfo
357 ///////////////////////////////////////////////////////////////////////
358 
359 TTErr JAMOMA_EXPORT jamoma_node_info_create(t_object *x, TTObject& returnedNodeInfo)
360 {
361  returnedNodeInfo = TTObject(kTTSym_NodeInfo);
362  return kTTErrNone;
363 }
364 
365 // Method to deal with TTData
366 ///////////////////////////////////////////////////////////////////////
367 
368 /** Create a data object */
369 TTErr jamoma_data_create(t_object *x, TTObject& returnedData, TTSymbol service)
370 {
371  // create a data
372  returnedData = TTObject(kTTSym_Data, service);
373 
374  // prepare its callback
375  returnedData.set(kTTSym_baton, TTPtr(x));
376  returnedData.set(kTTSym_function, TTPtr(&jamoma_callback_return_value_typed));
377  returnedData.set(TTSymbol("rampDriveDefault"), TTSymbol("max"));
378 
379  return kTTErrNone;
380 }
381 
382 /** Send Max data command */
383 TTErr jamoma_data_command(TTObject& aData, t_symbol *msg, long argc, const t_atom *argv)
384 {
385  TTValue v, none;
386 
387  if (aData.valid()) {
388 
389  jamoma_ttvalue_from_Atom(v, msg, argc, argv);
390 
391  aData.send(kTTSym_Command, v, none);
392  return kTTErrNone;
393  } else {
394  error("jamoma_data_command : invalid TTObject");
395  }
396  return kTTErrGeneric;
397 }
398 
399 // Method to deal with TTSender
400 ///////////////////////////////////////////////////////////////////////
401 
402 /** Create a sender object */
403 TTErr jamoma_sender_create(t_object *x, TTObject& returnedSender)
404 {
405  returnedSender = TTObject(kTTSym_Sender);
406  return kTTErrNone;
407 }
408 
409 /** Create a sender object for audio signal */
410 TTErr jamoma_sender_create_audio(t_object *x, TTObject& returnedSender)
411 {
412  TTObject audio;
413 
414  // prepare arguments
415  audio = TTObject(kTTSym_audiosignal, 1);
416 
417  returnedSender = TTObject(kTTSym_Sender, audio);
418  return kTTErrNone;
419 }
420 
421 /** Send Max data using a sender object */
422 TTErr jamoma_sender_send(TTObject& aSender, t_symbol *msg, long argc, const t_atom *argv)
423 {
424  TTValue v, none;
425 
426  if (aSender.valid()) {
427 
428  jamoma_ttvalue_from_Atom(v, msg, argc, argv);
429 
430  return aSender.send(kTTSym_Send, v, none);
431  }
432 
433  return kTTErrGeneric;
434 }
435 
436 // Method to deal with TTReceiver
437 ///////////////////////////////////////////////////////////////////////
438 
439 /** Create a receiver object */
440 TTErr jamoma_receiver_create(t_object *x, TTObject& returnedReceiver)
441 {
442  TTValue args;
443  TTObject returnAddressCallback, returnValueCallback;
444 
445  // prepare arguments
446  returnAddressCallback = TTObject("callback");
447  returnAddressCallback.set(kTTSym_baton, TTPtr(x));
448  returnAddressCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_address));
449  args.append(returnAddressCallback);
450 
451  returnValueCallback = TTObject("callback");
452  returnValueCallback.set(kTTSym_baton, TTPtr(x));
453  returnValueCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value_typed));
454  args.append(returnValueCallback);
455 
456  returnedReceiver = TTObject(kTTSym_Receiver, args);
457  return kTTErrNone;
458 }
459 
460 /** Create a receiver object for audio signal */
461 TTErr jamoma_receiver_create_audio(t_object *x, TTObject& returnedReceiver)
462 {
463  TTValue args;
464  TTObject returnAddressCallback, audio, empty;
465 
466  // prepare arguments
467  returnAddressCallback = TTObject("callback");
468  returnAddressCallback.set(kTTSym_baton, TTPtr(x));
469  returnAddressCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_address));
470  args.append(returnAddressCallback);
471 
472  args.append(empty); // no return value callback
473 
474  audio = TTObject(kTTSym_audiosignal, 1);
475  args.append(audio);
476 
477  returnedReceiver = TTObject(kTTSym_Receiver, args);
478  return kTTErrNone;
479 }
480 
481 // Method to deal with TTPresetManager
482 ///////////////////////////////////////////////////////////////////////
483 
484 /** Create a preset manager object */
485 TTErr jamoma_presetManager_create(t_object *x, TTObject& returnedPresetManager)
486 {
487  TTObject returnLineCallback;
488 
489  // prepare arguments
490  returnLineCallback = TTObject("callback");
491  returnLineCallback.set(kTTSym_baton, TTPtr(x));
492  returnLineCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
493 
494  returnedPresetManager = TTObject(kTTSym_PresetManager, returnLineCallback);
495  return kTTErrNone;
496 }
497 
498 /** Create a cue manager object */
499 TTErr jamoma_cueManager_create(t_object *x, TTObject& returnedCueManager)
500 {
501  TTObject returnLineCallback;
502 
503  // prepare arguments
504  returnLineCallback = TTObject("callback");
505  returnLineCallback.set(kTTSym_baton, TTPtr(x));
506  returnLineCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
507 
508  returnedCueManager = TTObject(kTTSym_CueManager, returnLineCallback);
509  return kTTErrNone;
510 }
511 
512 // Method to deal with TTInput
513 ///////////////////////////////////////////////////////////////////////
514 
515 /** Create an input object for any signal */
516 TTErr jamoma_input_create(t_object *x, TTObject& returnedInput)
517 {
518  TTValue baton;
519  TTObject signalOutCallback;
520 
521  // prepare arguments
522  signalOutCallback = TTObject("callback");
523  baton = TTValue(TTPtr(x), TTPtr(jps_return_signal));
524  signalOutCallback.set(kTTSym_baton, baton);
525  signalOutCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value_typed));
526 
527  returnedInput = TTObject(kTTSym_Input, signalOutCallback);
528  returnedInput.set("type", TTSymbol("control"));
529  return kTTErrNone;
530 }
531 
532 /** Create an input object for audio signal */
533 TTErr jamoma_input_create_audio(t_object *x, TTObject& returnedInput)
534 {
535  returnedInput = TTObject("Input.audio");
536  return kTTErrNone;
537 }
538 
539 /** Send any signal to an input object */
540 TTErr jamoma_input_send(TTObject& anInput, t_symbol *msg, long argc, const t_atom *argv)
541 {
542  TTValue v, none;
543 
544  if (anInput.valid()) {
545 
546  jamoma_ttvalue_from_Atom(v, msg, argc, argv);
547 
548  return anInput.send(kTTSym_Send, v, none);
549  }
550 
551  return kTTErrGeneric;
552 }
553 
554 
555 // Method to deal with TTOutput
556 ///////////////////////////////////////////////////////////////////////
557 
558 /** Create an output object for signal */
559 TTErr jamoma_output_create(t_object *x, TTObject& returnedOutput)
560 {
561  TTValue baton;
562  TTObject signalOutCallback;
563 
564  // prepare arguments
565  signalOutCallback = TTObject("callback");
566  baton = TTValue(TTPtr(x), TTPtr(jps_return_signal));
567  signalOutCallback.set(kTTSym_baton, baton);
568  signalOutCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value_typed));
569 
570  returnedOutput = TTObject(kTTSym_Output, signalOutCallback);
571  returnedOutput.set("type", TTSymbol("control"));
572  return kTTErrNone;
573 }
574 
575 /** Create an output object for audio signal */
576 TTErr jamoma_output_create_audio(t_object *x, TTObject& returnedOutput)
577 {
578  // prepare arguments
579  returnedOutput = TTObject("Output.audio");
580  return kTTErrNone;
581 }
582 
583 /** Send any signal to an output object */
584 TTErr jamoma_output_send(TTObject& anOutput, t_symbol *msg, long argc, const t_atom *argv)
585 {
586  TTValue v, none;
587 
588  if (anOutput.valid()) {
589 
590  jamoma_ttvalue_from_Atom(v, msg, argc, argv);
591 
592  return anOutput.send(kTTSym_Send, v, none);
593  }
594 
595  return kTTErrGeneric;
596 }
597 
598 
599 // Method to deal with TTMapper
600 ///////////////////////////////////////////////////////////////////////
601 
602 /** Create a mapper object */
603 TTErr jamoma_mapper_create(t_object *x, TTObject& returnedMapper)
604 {
605  TTValue args, baton, none;
606  TTObject returnValueCallback, returnInputGoingDownCallback, returnInputGoingUpCallback, returnOutputGoingDownCallback, returnOutputGoingUpCallback;
607 
608  // prepare arguments
609  returnValueCallback = TTObject("callback");
610  returnValueCallback.set(kTTSym_baton, TTPtr(x));
611  returnValueCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
612  args.append(returnValueCallback);
613 
614  returnInputGoingDownCallback = TTObject("callback");
615  baton = TTValue(TTPtr(x), TTPtr(gensym("return_input_going_down")));
616  returnInputGoingDownCallback.set(kTTSym_baton, baton);
617  returnInputGoingDownCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
618  args.append(returnInputGoingDownCallback);
619 
620  returnInputGoingUpCallback = TTObject("callback");
621  baton = TTValue(TTPtr(x), TTPtr(gensym("return_input_going_up")));
622  returnInputGoingUpCallback.set(kTTSym_baton, baton);
623  returnInputGoingUpCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
624  args.append(returnInputGoingUpCallback);
625 
626  returnOutputGoingDownCallback = TTObject("callback");
627  baton = TTValue(TTPtr(x), TTPtr(gensym("return_output_going_down")));
628  returnOutputGoingDownCallback.set(kTTSym_baton, baton);
629  returnOutputGoingDownCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
630  args.append(returnOutputGoingDownCallback);
631 
632  returnOutputGoingUpCallback = TTObject("callback");
633  baton = TTValue(TTPtr(x), TTPtr(gensym("return_output_going_up")));
634  returnOutputGoingUpCallback.set(kTTSym_baton, baton);
635  returnOutputGoingUpCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
636  args.append(returnOutputGoingUpCallback);
637 
638  returnedMapper = TTObject(kTTSym_Mapper, args);
639 
640  return kTTErrNone;
641 }
642 
643 
644 // Method to deal with TTViewer
645 ///////////////////////////////////////////////////////////////////////
646 
647 /** Create a viewer object */
648 TTErr jamoma_viewer_create(t_object *x, TTObject& returnedViewer)
649 {
650  returnedViewer = TTObject(kTTSym_Viewer);
651 
652  returnedViewer.set(kTTSym_baton, TTPtr(x));
653  returnedViewer.set(kTTSym_function, TTPtr(&jamoma_callback_return_value_typed));
654 
655  return kTTErrNone;
656 }
657 
658 /** Send Max data using a viewer object */
659 TTErr jamoma_viewer_send(TTObject& aViewer, t_symbol *msg, long argc, const t_atom *argv)
660 {
661  TTValue v, none;
662 
663  if (aViewer.valid()) {
664 
665  jamoma_ttvalue_from_Atom(v, msg, argc, argv);
666 
667  return aViewer.send(kTTSym_Send, v, none);
668  }
669 
670  return kTTErrGeneric;
671 }
672 
673 
674 // Method to deal with TTExplorer
675 ///////////////////////////////////////////////////////////////////////
676 
677 /** Create an explorer object */
678 TTErr jamoma_explorer_create(t_object *x, TTObject& returnedExplorer)
679 {
680  TTValue args, baton;
681  TTObject returnValueCallback, returnSelectionCallback;
682 
683  // prepare arguments
684  returnValueCallback = TTObject("callback");
685  returnValueCallback.set(kTTSym_baton, TTPtr(x));
686  returnValueCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
687  args.append(returnValueCallback);
688 
690 
691  returnSelectionCallback = TTObject("callback");
692  baton = TTValue(TTPtr(x), (TTPtr)gensym("return_selection"));
693  returnSelectionCallback.set(kTTSym_baton, baton);
694  returnSelectionCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
695  args.append(returnSelectionCallback);
696 
697  returnedExplorer = TTObject(kTTSym_Explorer, args);
698 
699  return kTTErrNone;
700 }
701 
703 {
704  TTHashPtr defaultFilterBank = new TTHash();
705  TTDictionaryBasePtr aFilter;
706 
707  // Create some ready-made filters
708 
709  // to look for any data (parameter | message | return)
710  aFilter = new TTDictionaryBase;
711  aFilter->setSchema(kTTSym_filter);
712  aFilter->append(kTTSym_object, kTTSym_Data);
713  aFilter->append(kTTSym_mode, kTTSym_include);
714  defaultFilterBank->append(TTSymbol("data"), (TTPtr)aFilter);
715 
716  // to look for j.parameter
717  aFilter = new TTDictionaryBase;
718  aFilter->setSchema(kTTSym_filter);
719  aFilter->append(kTTSym_object, kTTSym_Data);
720  aFilter->append(kTTSym_attribute, kTTSym_service);
721  aFilter->append(kTTSym_value, kTTSym_parameter);
722  aFilter->append(kTTSym_mode, kTTSym_include);
723  defaultFilterBank->append(TTSymbol("parameter"), (TTPtr)aFilter);
724 
725  // to look for j.message
726  aFilter = new TTDictionaryBase;
727  aFilter->setSchema(kTTSym_filter);
728  aFilter->append(kTTSym_object, kTTSym_Data);
729  aFilter->append(kTTSym_attribute, kTTSym_service);
730  aFilter->append(kTTSym_value, kTTSym_message);
731  aFilter->append(kTTSym_mode, kTTSym_include);
732  defaultFilterBank->append(TTSymbol("message"), (TTPtr)aFilter);
733 
734  // to look for j.return
735  aFilter = new TTDictionaryBase;
736  aFilter->setSchema(kTTSym_filter);
737  aFilter->append(kTTSym_object, kTTSym_Data);
738  aFilter->append(kTTSym_attribute, kTTSym_service);
739  aFilter->append(kTTSym_value, kTTSym_return);
740  aFilter->append(kTTSym_mode, kTTSym_include);
741  defaultFilterBank->append(TTSymbol("return"), (TTPtr)aFilter);
742 
743  // to look for j.model
744  aFilter = new TTDictionaryBase;
745  aFilter->setSchema(kTTSym_filter);
746  aFilter->append(kTTSym_object, kTTSym_Container);
747  aFilter->append(kTTSym_attribute, kTTSym_service);
748  aFilter->append(kTTSym_value, kTTSym_model);
749  aFilter->append(kTTSym_mode, kTTSym_include);
750  defaultFilterBank->append(TTSymbol("model"), (TTPtr)aFilter);
751 
752  // to look for j.view
753  aFilter = new TTDictionaryBase;
754  aFilter->setSchema(kTTSym_filter);
755  aFilter->append(kTTSym_object, kTTSym_Container);
756  aFilter->append(kTTSym_attribute, kTTSym_service);
757  aFilter->append(kTTSym_value, kTTSym_view);
758  aFilter->append(kTTSym_mode, kTTSym_include);
759  defaultFilterBank->append(TTSymbol("view"), (TTPtr)aFilter);
760 
761  // to look for empty nodes
762  aFilter = new TTDictionaryBase;
763  aFilter->setSchema(kTTSym_filter);
764  aFilter->append(kTTSym_object, TTSymbol("none"));
765  aFilter->append(kTTSym_mode, kTTSym_include);
766  defaultFilterBank->append(TTSymbol("none"), (TTPtr)aFilter);
767 
768  // to look for j.remote
769  aFilter = new TTDictionaryBase;
770  aFilter->setSchema(kTTSym_filter);
771  aFilter->append(kTTSym_object, kTTSym_Viewer);
772  aFilter->append(kTTSym_mode, kTTSym_include);
773  defaultFilterBank->append(TTSymbol("remote"), (TTPtr)aFilter);
774 
775  // to look for user-defined object
776  aFilter = new TTDictionaryBase;
777  aFilter->setSchema(kTTSym_filter);
778  aFilter->append(kTTSym_attribute, kTTSym_tags);
779  aFilter->append(kTTSym_value, kTTSym_generic);
780  aFilter->append(kTTSym_mode, kTTSym_exclude);
781  defaultFilterBank->append(TTSymbol("noGenericTag"), (TTPtr)aFilter);
782 
783  // to look for generic tagged object
784  aFilter = new TTDictionaryBase;
785  aFilter->setSchema(kTTSym_filter);
786  aFilter->append(kTTSym_attribute, kTTSym_tags);
787  aFilter->append(kTTSym_value, kTTSym_generic);
788  aFilter->append(kTTSym_mode, kTTSym_restrict);
789  defaultFilterBank->append(TTSymbol("genericTag"), (TTPtr)aFilter);
790 
791  return defaultFilterBank;
792 }
793 
794 
795 // Method to deal with TTRamp
796 ///////////////////////////////////////////////////////////////////////
797 TTErr jamoma_ramp_create(t_object *x, TTObject& returnedRamp)
798 {
799  TTValue args;
800 
801  // prepare arguments
803  args.append((TTPtr)x);
804 
805  returnedRamp = TTObject(kTTSym_Ramp, args);
806  return kTTErrNone;
807 }
808 
809 void JAMOMA_EXPORT jamoma_callback_return_ramped_value(void *o, TTUInt32 n, TTFloat64 *v)
810 {
811  t_object *x = (t_object*)o;
812  long i, argc = n;
813  t_atom *argv = NULL;
814 
815  if (!argc)
816  return;
817 
818  // copy the array of ramped float value into an atom
819  argv = (t_atom*)malloc(sizeof(t_atom) * argc);
820 
821  for (i = 0; i < argc; i++)
822  atom_setfloat(argv+i, v[i]);
823 
824  // send the atom to the object using return_value method
825  if (argc == 1)
826  object_method_typed(x, jps_return_value, _sym_float, argc, argv);
827  else
828  object_method_typed(x, jps_return_value, _sym_list, argc, argv);
829 
830  free(argv);
831 }
832 
833 // Method to return data
834 ///////////////////////////////////////////////////////////////////////
835 
836 void jamoma_callback_return_address(const TTValue& baton, const TTValue& v)
837 {
838  t_object *x;
839  TTSymbol address;
840 
841  // unpack baton (a t_object *and the name of the method to call)
842  x = (t_object*)((TTPtr)baton[0]);
843 
844  if (v.size() == 1) {
845 
846  if (v[0].type() == kTypeSymbol) {
847 
848  // unpack data (address)
849  address = v[0];
850 
851  // send data to a data using the return_value method
852  object_method_typed(x, jps_return_address, SymbolGen(address.c_str()), 0, 0);
853  }
854  }
855 }
856 
857 /** Return the value to a j. external as _sym_nothing, argc, argv */
858 void jamoma_callback_return_value(const TTValue& baton, const TTValue& v)
859 {
860  t_object *x;
861  t_symbol *s_method;
862  TTBoolean deferlow = NO;
863  long argc = 0;
864  t_atom *argv = NULL;
865  method p_method = NULL;
866 
867  // unpack baton (a t_object *and the name of the method to call (default : jps_return_value))
868 
869  // get object
870  x = (t_object*)((TTPtr)baton[0]);
871 
872  // get method
873  if (baton.size() >= 2) {
874 
875  s_method = (t_symbol*)((TTPtr)baton[1]);
876 
877  if (s_method == NULL || s_method == _sym_nothing)
878  return;
879 
880  // do we need to deferlow it ?
881  if (baton.size() == 3)
882  deferlow = baton[2];
883  }
884  else
885  s_method = jps_return_value;
886 
887  jamoma_ttvalue_to_Atom(v, &argc, &argv);
888 
889  // send data to an external
890  if (!deferlow)
891  object_method_typed(x, s_method, _sym_nothing, argc, argv);
892 
893  else {
894 
895  p_method = object_getmethod(x, s_method);
896 
897  if (p_method)
898  p_method(x, _sym_nothing, argc, argv);
899  }
900 
901  sysmem_freeptr(argv);
902 }
903 
904 /** Return the value to a j. external as msg, argc, argv */
905 // TODO #556 : merge this function into jamoma_callback_return_value
906 // TODO : why don't we pass a #TTDictionary into the baton
908 {
909  t_object *x;
910  t_symbol *msg, *s_method;
911  TTBoolean deferlow = NO;
912  long argc = 0;
913  t_atom *argv = NULL;
914  method p_method = NULL;
915  TTBoolean shifted = false;
916 
917  // unpack baton (a t_object *and the name of the method to call (default : jps_return_value))
918 
919  // get Max wrapper object that was passed in
920  x = (t_object*)((TTPtr)baton[0]);
921 
922  // get name of the method to call
923  if (baton.size() >= 2) {
924 
925  s_method = (t_symbol*)((TTPtr)baton[1]);
926 
927  if (s_method == NULL || s_method == _sym_nothing)
928  return;
929 
930  // do we need to deferlow it ?
931  if (baton.size() == 3)
932  deferlow = baton[2];
933  }
934  // by default we call "return_value" method
935  else
936  s_method = jps_return_value;
937 
938  // convert TTValue into a typed atom array
939  jamoma_ttvalue_to_typed_Atom(v, &msg, &argc, &argv, shifted);
940 
941  // send data to an external
942  if (!deferlow)
943  object_method_typed(x, s_method, msg, argc, argv);
944 
945  else {
946 
947  p_method = object_getmethod(x, s_method);
948 
949  if (p_method)
950  p_method(x, msg, argc, argv);
951  }
952 
953  if (shifted)
954  argv--;
955  sysmem_freeptr(argv);
956 }
957 
958 /** Return any signal */
959 void jamoma_callback_return_signal(const TTValue& baton, const TTValue& v)
960 {
961  t_object *x;
962  long argc = 0;
963  t_atom *argv = NULL;
964 
965  // unpack baton (a t_object*)
966  x = (t_object*)((TTPtr)baton[0]);
967 
968  jamoma_ttvalue_to_Atom(v, &argc, &argv);
969 
970  // send signal using the return_signal method
971  object_method_typed(x, jps_return_signal, _sym_nothing, argc, argv);
972 
973  sysmem_freeptr(argv);
974 }
975 
976 /** Return audio signal */
977 /** disable audio support for now
978 void jamoma_callback_return_signal_audio(const TTValue& baton, const TTValue& v)
979 {
980  t_object *x;
981  TTPtr signal;
982  long i, argc = 0;
983  t_atom *argv = NULL;
984 
985  // unpack baton (a t_object*)
986  x = (t_object*)((TTPtr)baton[0]);
987 
988  // unpack data (signal)
989  argc = v.size();
990  argv = (t_atom*)sysmem_newptr(sizeof(t_atom) * argc);
991  for (i = 0; i < argc; i++) {
992  signal = v[i];
993  atom_setobj(argv+i, signal);
994  }
995 
996  // send signal using the return_signal method
997  object_method(x, jps_return_signal, _sym_nothing, argc, argv);
998 
999  sysmem_freeptr(argv);
1000 }
1001 **/
1002 
1003 // Method to deal with TTValue
1004 /////////////////////////////////////////
1005 
1006 /** Make a typed Atom array from a TTValue (!!! this method allocate memory for the Atom array ! free it after ! */
1007 void jamoma_ttvalue_to_typed_Atom(const TTValue& v, t_symbol **msg, long *argc, t_atom **argv, TTBoolean& shifted)
1008 {
1009  long i;
1010  TTFloat64 f;
1011  TTSymbol s;
1012 
1013  *msg = _sym_nothing;
1014  *argc = v.size();
1015 
1016  if (!(*argv)) // otherwise use memory passed in
1017  *argv = (t_atom*)sysmem_newptr(sizeof(t_atom) * (*argc));
1018 
1019  if (*argc && v.size() > 0) {
1020 
1021  for (i = 0; i < *argc; i++) {
1022 
1023  if(v[i].type() == kTypeSymbol){
1024  s = v[i];
1025  if (s == kTTSymEmpty || s == kTTAdrsEmpty)
1026  atom_setsym((*argv)+i, _sym_bang);
1027  else
1028  atom_setsym((*argv)+i, gensym((char*)s.c_str()));
1029  //*msg = _sym_symbol;
1030  }
1031  else{ // assume int
1032  f = v[i];
1033  atom_setfloat((*argv)+i, f);
1034  *msg = _sym_float;
1035  }
1036  }
1037 
1038  if (i>0) {
1039 
1040  if (atom_gettype(*argv) == A_SYM) {
1041 
1042  *msg = atom_getsym(*argv);
1043  *argc = (*argc)-1;
1044  *argv = (*argv)+1;
1045  shifted = true;
1046  }
1047  else if (i>1)
1048  *msg = _sym_list;
1049  }
1050  }
1051  else {
1052 
1053  *msg = _sym_bang;
1054  *argc = 0;
1055  *argv = NULL;
1056  }
1057 }
1058 
1059 /** Make an Atom array from a TTValue (!!! this method allocate memory for the Atom array ! free it after ! */
1060 void jamoma_ttvalue_to_Atom(const TTValue& v, long *argc, t_atom **argv)
1061 {
1062  long i;
1063  TTFloat64 f;
1064  TTSymbol s;
1065 
1066  *argc = v.size();
1067 
1068  if (*argc == 0 || v.size() == 0)
1069  return;
1070 
1071  if (!(*argv)) // otherwise use memory passed in
1072  *argv = (t_atom*)sysmem_newptr(sizeof(t_atom) * (*argc));
1073 
1074  for (i = 0; i < v.size(); i++)
1075  {
1076  if (v[i].type() == kTypeSymbol)
1077  {
1078  s = v[i];
1079  if (s == kTTSymEmpty)
1080  atom_setsym((*argv)+i, _sym_bang); // because empty symbol can't be filtered in Max
1081  else
1082  atom_setsym((*argv)+i, gensym((char*)s.c_str()));
1083  }
1084  else
1085  {
1086  f = v[i];
1087  atom_setfloat((*argv)+i, f);
1088  }
1089  }
1090 }
1091 
1092 /** Make a TTValue from Atom array */
1093 void jamoma_ttvalue_from_Atom(TTValue& v, t_symbol *msg, long argc, const t_atom *argv)
1094 {
1095  long i, start;
1096 
1097  if ((msg == _sym_bang || msg == _sym_nothing) && argc == 0)
1098  v.clear();
1099  else
1100  {
1101  // add msg to the value
1102  if (msg && msg != _sym_nothing && msg != _sym_int && msg != _sym_float && msg != _sym_symbol && msg != _sym_list)
1103  {
1104  v.resize(argc+1);
1105  v[0] = TTSymbol(msg->s_name);
1106  start = 1;
1107  }
1108  else
1109  {
1110  v.resize(argc);
1111  start = 0;
1112  }
1113 
1114  // convert Atom to TTValue
1115  for (i = 0; i < argc; i++)
1116  {
1117  if (atom_gettype(argv+i) == A_SYMBOL){
1118  if ( atom_getsym((t_atom*)argv+i)->s_name[0] == '"'){
1119  std::string concatSym = std::string(atom_getsym((t_atom*)argv+i)->s_name+1);
1120  int j = i;
1121  i++;
1122  for (;i < argc; i++){
1123  if (argv[i].a_type == A_SYMBOL) {
1124  char* sym = atom_getsym((t_atom*)argv+i)->s_name;
1125  concatSym += std::string(" ");
1126  char* c = strchr(sym,'"');
1127  if (c) {
1128  concatSym+=sym;
1129  break;
1130  }
1131  concatSym+=sym;
1132  } else if ( argv[i].a_type == A_FLOAT ) {
1133  concatSym += std::string(" ");
1134  concatSym+= std::to_string(atom_getfloat((t_atom*)argv+i));
1135  }
1136  }
1137  v[j+start] = TTSymbol(concatSym.substr(0,concatSym.size()-1));
1138  }
1139  else
1140  v[i+start] = TTSymbol(atom_getsym((t_atom*)argv+i)->s_name);
1141  }
1142  else
1143  v[i+start] = (TTFloat64)atom_getfloat((t_atom*)argv+i);
1144  }
1145  }
1146 }
1147 
1148 /** Convert a TTSymbol "MyObjectMessage" into a t_symbol *"my/object/message"
1149  or return NULL if the TTSymbol doesn't begin by an uppercase letter */
1151 {
1152  TTSymbol AppName;
1153  TTAddress anAddress;
1154  TTErr err;
1155 
1156  AppName = ToAppName(TTName);
1157 
1158  if (AppName == kTTSymEmpty)
1159  err = convertUpperCasedNameInAddress(TTName, anAddress);
1160  else
1161  err = convertUpperCasedNameInAddress(AppName, anAddress);
1162 
1163  if (!err)
1164  return gensym((char*)anAddress.c_str());
1165  else
1166  return NULL;
1167 }
1168 
1169 /** Load an external for internal use. Returns true if successful */
1170 /* AV - seems to be unused
1171 TTBoolean jamoma_extern_load(t_symbol *objectname, long argc, t_atom *argv, t_object **object)
1172 {
1173  t_class *c = NULL;
1174  t_object *p = NULL;
1175 
1176  c = class_findbyname(jps_box, objectname);
1177  if (!c) {
1178  p = (t_object *)newinstance(objectname, 0, NULL);
1179  if (p) {
1180  c = class_findbyname(jps_box, objectname);
1181  freeobject(p);
1182  p = NULL;
1183  }
1184  else {
1185  error("jamoma: could not load extern (%s) within the core", objectname->s_name);
1186  return false;
1187  }
1188  }
1189 
1190  if (*object != NULL) { // if there was an object set previously, free it first...
1191  object_free(*object);
1192  *object = NULL;
1193  }
1194 
1195  *object = (t_object*)object_new_typed(CLASS_BOX, objectname, argc, argv);
1196  return true;
1197 }
1198 */
1199 
1200 // Don't pass memory in for this function! It will allocate what it needs
1201 // -- then the caller is responsible for freeing
1202 void jamoma_patcher_get_args(t_canvas *canvas, long *argc, t_atom **argv)
1203 {
1204  t_binbuf *b = NULL;
1205 
1206  b = canvas->gl_obj.te_binbuf;
1207 
1208  if(b)
1209  {
1210  long ac = binbuf_getnatom(b);
1211  t_atom* av = binbuf_getvec(b);
1212  if(atom_gettype(av) == A_SYM && atom_getsym(av) == gensym("pd"))
1213  {
1214  ac--;
1215  av++;
1216  }
1217  *argc = ac;
1218  *argv = av;
1219  } else {
1220  *argc = 0;
1221  *argv = NULL;
1222  }
1223 }
1224 
1225 /** Get the context from the upper j.model|view in the patcher or from patcher's name */
1226 void jamoma_patcher_get_context(t_canvas *patcher, TTSymbol& returnedContext)
1227 {
1228  t_symbol *hierarchy, *_sym_j_context;
1229  t_canvas *upperPatcher;
1230  TTBoolean found = NO;
1231 
1232  t_gobj *obj=patcher->gl_list;
1233 
1234  for ( ; obj ; obj = obj->g_next )
1235  {
1236  _sym_j_context = obj->g_pd->c_name;
1237  if (_sym_j_context == _sym_j_model ){
1238 
1239  returnedContext = kTTSym_model;
1240  found = YES;
1241  break;
1242 
1243  } else if ( _sym_j_context == _sym_j_view ) {
1244 
1245  returnedContext = kTTSym_view;
1246  found = YES;
1247  break;
1248  }
1249  }
1250 
1251  // if no context
1252  if (!found) {
1253 
1254  // in subpatcher look upper
1255  hierarchy = jamoma_patcher_get_hierarchy(patcher);
1256  if (hierarchy == _sym_subpatcher || hierarchy == _sym_bpatcher || hierarchy == SymbolGen("poly")) {
1257 
1258  // get the patcher where is the patcher to look for the context one step upper
1259  upperPatcher = patcher->gl_owner;
1260 
1261  jamoma_patcher_get_context(upperPatcher, returnedContext);
1262 
1263  // keep the upperPatcher if no j.model|view around
1264  // because it is where the context is defined
1265  patcher = upperPatcher;
1266  }
1267  // default case : a patcher has no type
1268  else if (hierarchy == _sym_topmost)
1269  returnedContext = kTTSymEmpty;
1270  }
1271 }
1272 
1273 /** Get the class of the patcher from the file name (removing .model and .view convention name if they exist) */
1274 void jamoma_patcher_get_class(t_canvas *patcher, TTSymbol context, TTSymbol& returnedClass)
1275 {
1276  t_symbol *patcherName, *hierarchy;
1277  t_canvas *upperPatcher;
1278  TTString s_toParse;
1279  TTStringIter begin, end;
1280  TTBoolean intoHelp = NO;
1281 
1282  // extract class from the file name
1283  if(patcher->gl_name)
1284  patcherName = patcher->gl_name;
1285  else
1286  patcherName = _sym_nothing;
1287 
1288  if (patcherName != _sym_nothing) {
1289 
1290  s_toParse = patcherName->s_name;
1291 
1292  begin = s_toParse.begin();
1293  end = s_toParse.end();
1294 
1295  // parse .maxpat
1296  if (!ttRegexForPdpat->parse(begin, end)) {
1297  s_toParse = TTString(begin, ttRegexForPdpat->begin());
1298  begin = s_toParse.begin();
1299  end = s_toParse.end();
1300  }
1301  // parse .maxhelp
1302  else if (!ttRegexForPdhelp->parse(begin, end)) {
1303  s_toParse = TTString(begin, ttRegexForPdhelp->begin());
1304  begin = s_toParse.begin();
1305  end = s_toParse.end();
1306 
1307  intoHelp = YES;
1308  }
1309 
1310  // parse jmod.
1311  if (!ttRegexForJmod->parse(begin, end)) {
1312 
1313  pd_error(patcher, "jmod. prefix in %s is a 0.5 convention. Please use .module suffix instead", patcherName->s_name);
1314 
1315  s_toParse = TTString(ttRegexForJmod->end(), end);
1316  begin = s_toParse.begin();
1317  end = s_toParse.end();
1318  }
1319  // parse j.
1320  else if (!ttRegexForJcom->parse(begin, end)) {
1321 
1322  s_toParse = TTString(ttRegexForJcom->end(), end);
1323  begin = s_toParse.begin();
1324  end = s_toParse.end();
1325  }
1326 
1327  // parse .module or if not parse context (model or view)
1328  if (!ttRegexForModule->parse(begin, end)) {
1329  s_toParse = TTString(begin, ttRegexForModule->begin());
1330  begin = s_toParse.begin();
1331  end = s_toParse.end();
1332  }
1333  else if (context == kTTSym_model) {
1334 
1335  if (!ttRegexForModel->parse(begin, end)) {
1336  s_toParse = TTString(begin, ttRegexForModel->begin());
1337  begin = s_toParse.begin();
1338  end = s_toParse.end();
1339  }
1340  }
1341  else if (context == kTTSym_view) {
1342 
1343  if (!ttRegexForView->parse(begin, end)) {
1344  s_toParse = TTString(begin, ttRegexForView->begin());
1345  begin = s_toParse.begin();
1346  end = s_toParse.end();
1347  }
1348  }
1349 
1350  // in help patcher : append _help to the class to clarify the namespace
1351  if (intoHelp)
1352  s_toParse += "_help";
1353 
1354  returnedClass = TTSymbol(s_toParse);
1355  }
1356  else {
1357 
1358  // in subpatcher : look to the name else look upper
1359  hierarchy = jamoma_patcher_get_hierarchy(patcher);
1360  if (hierarchy == _sym_subpatcher) {
1361 
1362  long ac = 0;
1363  t_atom *av = NULL;
1364 
1365  jamoma_patcher_get_args(patcher, &ac, &av);
1366 
1367  // remove first 'pd'
1368  if (ac > 0 && av) {
1369  if (atom_getsym(av) == _sym_pd) {
1370  ac--;
1371  av++;
1372  }
1373  }
1374 
1375  // is there still arguments ?
1376  if (ac > 0 && av) {
1377 
1378  // the first argument is the class
1379  returnedClass = TTSymbol(atom_getsym(av)->s_name);
1380  }
1381  else {
1382 
1383  // get the patcher where is the patcher to look for the class one step upper
1384  upperPatcher = patcher->gl_owner;
1385 
1386  jamoma_patcher_get_class(upperPatcher, context, returnedClass);
1387  }
1388  }
1389  // in bpatcher : look upper
1390  else if (hierarchy == _sym_bpatcher) {
1391 
1392  // get the patcher where is the patcher to look for the class one step upper
1393  upperPatcher = patcher->gl_owner;
1394 
1395  jamoma_patcher_get_class(upperPatcher, context, returnedClass);
1396  }
1397  // default case : a patcher has no class
1398  else if (hierarchy == _sym_topmost)
1399  returnedClass = kTTSymEmpty;
1400  }
1401 }
1402 
1403 /** Get the name of the patcher from his arguments */
1404 void jamoma_patcher_get_name(t_canvas *patcher, TTSymbol context, TTSymbol& returnedName)
1405 {
1406  long ac = 0;
1407  t_atom *av = NULL;
1408  t_symbol *hierarchy, *argName = _sym_nothing;
1409 
1410  // returnedName = TTSymbol(canvas->gl_name->s_name);
1411  returnedName = kTTSymEmpty;
1412 
1413  // try to get context name from the patcher arguments
1414  hierarchy = jamoma_patcher_get_hierarchy(patcher);
1415  jamoma_patcher_get_args(patcher, &ac, &av);
1416 
1417  // for subpatcher :
1418  if (hierarchy == _sym_subpatcher) {
1419 
1420  // remove first 'pd'
1421  if (ac > 0 && av) {
1422  if (atom_getsym(av) == _sym_pd) {
1423  ac--;
1424  av++;
1425  }
1426  }
1427 
1428  // remove the next argument because it is the class
1429  ac--;
1430  av++;
1431  }
1432 
1433  // is there still arguments ?
1434  if (ac > 0 && av) {
1435 
1436  // notice we have to test view case before model case
1437  // because a j.view can be in subpatcher too
1438 
1439  // for view : the second argument is the name
1440  // (the first is reserved for the model:address)
1441  if (context == kTTSym_view) {
1442  if (ac > 1)
1443  argName = atom_getsym(av+1);
1444 
1445  // for model : the first argument is the name
1446  } else if (context == kTTSym_model || hierarchy == _sym_subpatcher)
1447  argName = atom_getsym(av);
1448 
1449  // if the argname begin by a @ ignore it
1450  if (argName->s_name[0] == '@')
1451  argName = _sym_nothing;
1452 
1453  if (argName != _sym_nothing)
1454  returnedName = TTSymbol(jamoma_parse_dieze(patcher, argName)->s_name);
1455  }
1456 }
1457 
1458 /** Get all context info from the root j.model|view in the patcher */
1459 void jamoma_patcher_share_info(t_canvas *patcher, t_canvas **returnedPatcher, TTSymbol& returnedContext, TTSymbol& returnedClass, TTSymbol& returnedName)
1460 {
1461  TTValue patcherInfo;
1462  t_symbol *_sym_j_context;
1463 
1464  t_gobj *obj=patcher->gl_list;
1465 
1466  for ( ; obj ; obj = obj->g_next )
1467  {
1468  _sym_j_context = obj->g_pd->c_name;
1469  if (_sym_j_context == _sym_j_model || _sym_j_context == _sym_j_view) {
1470 
1471  t_ret_method _method = (t_ret_method)zgetfn(&obj->g_pd,_sym_share_patcher_info);
1472  if ( _method )
1473  _method(&obj->g_pd, &patcherInfo);
1474 
1475  if (patcherInfo.size() == 4) {
1476  *returnedPatcher = (t_canvas*)((TTPtr)patcherInfo[0]);
1477  returnedContext = patcherInfo[1];
1478  returnedClass = patcherInfo[2];
1479  returnedName = patcherInfo[3];
1480  break;
1481  }
1482  }
1483  }
1484 
1485 }
1486 
1487 /** Get j.model or j.view of a patcher */
1488 void jamoma_patcher_get_model_or_view(t_canvas *patcher, t_object **returnedModelOrView)
1489 {
1490  TTValue patcherInfo;
1491  t_symbol *_sym_j_context;
1492 
1493  *returnedModelOrView = NULL;
1494 
1495  t_gobj *obj=patcher->gl_list; // objects list
1496 
1497  for ( ; obj ; obj = obj->g_next )
1498  {
1499  _sym_j_context = obj->g_pd->c_name;
1500  if (_sym_j_context == _sym_j_model || _sym_j_context == _sym_j_view) {
1501 
1502  *returnedModelOrView = (t_object*) obj;
1503  break;
1504  }
1505  }
1506 
1507  return (void)returnedModelOrView;
1508 }
1509 
1510 /** Look for input and output (data and audio) */
1511 void jamoma_patcher_get_input_output(t_canvas *patcher, TTBoolean& dataInput, TTBoolean& dataOutput, TTBoolean& audioInput, TTBoolean& audioOutput)
1512 {
1513  TTValue patcherInfo;
1514  t_symbol *_sym_jcomcontext;
1515 
1516  dataInput = NO;
1517  dataOutput = NO;
1518  audioInput = NO;
1519  audioOutput = NO;
1520 
1521  t_gobj *obj=patcher->gl_list; // pointer to the first object
1522 
1523  for ( ; obj ; obj = obj->g_next )
1524  {
1525  _sym_jcomcontext = obj->g_pd->c_name;
1526 
1527  dataInput = dataInput || _sym_jcomcontext == _sym_j_in;
1528  dataOutput = dataOutput || _sym_jcomcontext == _sym_j_out;
1529  audioInput = audioInput || _sym_jcomcontext == _sym_j_intilda;
1530  audioOutput = audioOutput || _sym_jcomcontext == _sym_j_outtilda;
1531  }
1532 }
1533 
1534 /** Is there a j.ui object */
1536 {
1537  t_symbol *_sym_j_context;
1538  TTBoolean uiObject = NO;
1539 
1540  t_gobj *obj=patcher->gl_list;
1541 
1542  for ( ; obj ; obj = obj->g_next )
1543  {
1544  _sym_j_context = obj->g_pd->c_name;
1545  uiObject = _sym_j_context == _sym_j_ui;
1546  if ( uiObject ) {
1547  break;
1548  }
1549  }
1550 
1551  return uiObject;
1552 }
1553 
1554 /** Get the "aClass.model" external in the patcher */
1555 void jamoma_patcher_get_model_patcher(t_canvas *patcher, TTSymbol modelClass, t_object **returnedModelPatcher)
1556 {
1557  t_symbol *_sym_modelfilename, *_sym_j_context, *_sym_objfilename;
1558 
1559  jamoma_edit_filename(*ModelPatcherFormat, modelClass, &_sym_modelfilename);
1560 
1561  *returnedModelPatcher = NULL;
1562 
1563  t_gobj *obj=patcher->gl_list; // pointer to the first object
1564 
1565  for ( ; obj ; obj = obj->g_next )
1566  {
1567  _sym_j_context = obj->g_pd->c_name;
1568  if (_sym_j_context == _sym_jpatcher) {
1569 
1570  // look for _sym_modelfilename
1571  _sym_objfilename = patcher->gl_name;
1572  if (_sym_objfilename == _sym_modelfilename) {
1573 
1574  *returnedModelPatcher = (t_object*)obj->g_pd;
1575  break;
1576  }
1577  }
1578  }
1579 }
1580 
1581 /** Get patcher's node from the root j.model|view in the patcher */
1582 void jamoma_patcher_share_node(t_canvas *patcher, TTNodePtr *patcherNode)
1583 {
1584  t_symbol *_sym_j_context;
1585 
1586  *patcherNode = NULL;
1587 
1588  t_gobj *obj=patcher->gl_list; // pointer to the first object
1589 
1590 // obj = (t_object*)object_attr_getobj(patcher, _sym_firstobject);
1591  for ( ; obj ; obj = obj->g_next )
1592  {
1593  _sym_j_context = obj->g_pd->c_name;
1594 
1595  if (_sym_j_context == _sym_j_model || _sym_j_context == _sym_j_view) {
1596  t_ret_method _method = (t_ret_method)zgetfn(&obj->g_pd,_sym_share_patcher_info);
1597  if ( _method )
1598  _method(&obj->g_pd, patcherNode);
1599  if (*patcherNode)
1600  break;
1601  }
1602  }
1603 }
1604 
1605 /** Get all context info from an object (his patcher and the context, the class and the name of his patcher) */
1606 TTErr jamoma_patcher_get_info(t_canvas *obj, t_canvas **returnedPatcher, TTSymbol& returnedContext, TTSymbol& returnedClass, TTSymbol& returnedName)
1607 {
1608  TTBoolean canShare;
1609  t_symbol *_sym_j_context;
1610  TTString viewName;
1611  t_canvas *patcher;
1612  t_canvas *sharedPatcher = NULL;
1613  TTSymbol sharedContext;
1614  TTSymbol sharedClass;
1615  TTSymbol sharedName;
1616 
1617  // t_eobj* x = (t_eobj*) obj;
1618  *returnedPatcher = obj;
1619 
1620  _sym_j_context = object_classname(obj);
1621  canShare = _sym_j_context == gensym("j.model") || _sym_j_context == gensym("j.view");
1622 
1623  patcher = *returnedPatcher;
1624 
1625  // Get the context, the class and the name of the patcher
1626  if (*returnedPatcher) {
1627 
1628  // try to get them from a j.model|view around to go faster (except for j.model|view of course)
1629  if (!canShare) {
1630 
1631  jamoma_patcher_share_info(*returnedPatcher, &sharedPatcher, sharedContext, sharedClass, sharedName);
1632 
1633  if (sharedPatcher && sharedContext && sharedClass && sharedName) {
1634 
1635  *returnedPatcher = sharedPatcher;
1636  returnedContext = sharedContext;
1637  returnedClass = sharedClass;
1638  returnedName = sharedName;
1639  return kTTErrNone;
1640  }
1641  }
1642 
1643  // get the context looking for a j.model|view in the patcher
1644  // it will also return a patcher above where a j.model|view has been found
1645  jamoma_patcher_get_context(*returnedPatcher, returnedContext);
1646 
1647  // if still no context : stop the subscription process
1648  if (returnedContext == kTTSymEmpty) {
1649 
1650  returnedName = S_SEPARATOR;
1651  returnedClass = kTTSymEmpty;
1652 
1653  // can't find any j.model|view with a correct context attribute in the patcher
1654  // so this means the object have to be registered under the root
1655  return kTTErrGeneric;
1656  }
1657 
1658  // get the class from the patcher filename
1659  jamoma_patcher_get_class(*returnedPatcher, returnedContext, returnedClass);
1660 
1661  // if no class : set it as "Untitled" to continue the process
1662  if (returnedClass == kTTSymEmpty)
1663  returnedClass = TTSymbol("Untitled");
1664 
1665  // for j.model|view object, use the patcher where it is to get the name
1666  if (canShare)
1667  jamoma_patcher_get_name(patcher, returnedContext, returnedName);
1668  // else get the name from the argument of the patcher
1669  else
1670  jamoma_patcher_get_name(*returnedPatcher, returnedContext, returnedName);
1671 
1672  // if no name
1673  if (returnedName == kTTSymEmpty) {
1674 
1675  // for model : used "class"
1676  if (returnedContext == kTTSym_model)
1677  returnedName = returnedClass;
1678 
1679  // for view : used "class(view)"
1680  else if (returnedContext == kTTSym_view) {
1681  viewName = returnedClass.c_str();
1682  viewName += "(view)";
1683  returnedName = TTSymbol(viewName.data());
1684  }
1685 
1686  // format name coming from class name replacing '.' and ' ' by '_'
1687  TTString s_toParse = returnedName.c_str();
1688  std::replace(s_toParse.begin(), s_toParse.end(), '.', '_');
1689  std::replace(s_toParse.begin(), s_toParse.end(), ' ', '_');
1690 
1691  /*
1692  * AV - there is no poly in pd
1693  // in poly case, the index is used to edit an instance
1694  // according to the voice index of the poly~
1695  if (jamoma_patcher_get_hierarchy(patcher) == gensym("poly")) {
1696 
1697  t_object *assoc = NULL;
1698  method m = NULL;
1699 
1700  object_method(patcher, gensym("getassoc"), &assoc);
1701  if (assoc) {
1702 
1703  m = zgetfn(assoc, gensym("getindex"));
1704  if(m) {
1705 
1706  char *s_num;
1707  long index = (long)(*m)(assoc, patcher);
1708  TTInt32 len;
1709 
1710  s_toParse += ".%d";
1711  len = s_toParse.size() + (TTInt32)log10((TTFloat32)index); // note : %d (lenght = 2) is replaced by 1 character (0::9), 2 charecters (10 :: 99), 3 char...
1712  s_num = (char *)malloc(sizeof(char)*len);
1713  snprintf(s_num, len, s_toParse.c_str(), index);
1714  s_toParse = s_num;
1715  free(s_num);
1716  }
1717  }
1718  }
1719  */
1720 
1721  returnedName = TTSymbol(s_toParse);
1722  }
1723  }
1724  // if no patcher : stop the subscription process
1725  else {
1726  pd_error(obj, "Can't get the patcher. Subscription failed");
1727  return kTTErrGeneric;
1728  }
1729 
1730  return kTTErrNone;
1731 }
1732 
1733 /** returned the N inside "pp/xx.[N]/yyy" and a format string as "pp/xx.%d/yy" and a format string as "pp/xx.%s/yy" */
1734 TTUInt32 jamoma_parse_bracket(t_symbol *s, TTString& si_format, TTString& ss_format)
1735 {
1736  long number = 0;
1737  TTString s_toParse = s->s_name;
1738  TTString s_number;
1739  TTString s_before;
1740  TTString s_after;
1741  TTStringIter begin, end;
1742  TTStringIter beginNumber, endNumber;
1743 
1744  begin = s_toParse.begin();
1745  end = s_toParse.end();
1746 
1747  // parse braket
1748  if (!ttRegexForBracket->parse(begin, end))
1749  {
1750  beginNumber = ttRegexForBracket->begin();
1751  endNumber = ttRegexForBracket->end();
1752 
1753  s_before = TTString(begin, ttRegexForBracket->begin()-1);
1754  s_number = TTString(ttRegexForBracket->begin(), ttRegexForBracket->end());
1755  s_after = TTString(ttRegexForBracket->end()+1, end);
1756 
1757  sscanf(s_number.c_str(), "%ld", &number);
1758 
1759  si_format = s_before;
1760  si_format += "%d";
1761  si_format += s_after;
1762 
1763  ss_format = s_before;
1764  ss_format += "%s";
1765  ss_format += s_after;
1766  }
1767  else {
1768  si_format = "";
1769  ss_format = "";
1770  }
1771 
1772  return number;
1773 }
1774 
1775 /** edit a new instance of the given format address using interger */
1776 void jamoma_edit_numeric_instance(TTString format, t_symbol** returnedName, long i)
1777 {
1778  char *s_num;
1779  TTInt32 len;
1780 
1781  if (i > 0) {
1782  len = format.size() + (TTInt32)log10((TTFloat32)i); // note : %d (lenght = 2) is replaced by 1 character (0::9), 2 charecters (10 :: 99), 3 char...
1783  s_num = (char *)malloc(sizeof(char)*len);
1784  snprintf(s_num, len, format.c_str(), i);
1785  *returnedName = gensym(s_num);
1786  free(s_num);
1787  }
1788 }
1789 
1790 /** edit a new instance of the given format address using string */
1791 void jamoma_edit_string_instance(TTString format, t_symbol** returnedName, TTString s)
1792 {
1793  char *s_str;
1794  long len;
1795 
1796  len = format.size() + s.size();
1797  s_str = (char *)malloc(sizeof(char)*len);
1798  snprintf(s_str, len, format.c_str(), s.c_str());
1799  *returnedName = gensym(s_str);
1800  free(s_str);
1801 }
1802 
1803 /** edit a file name from a given file format and a class name */
1804 void jamoma_edit_filename(TTString format, TTSymbol className, t_symbol **returnedFileName)
1805 {
1806  char *s_str;
1807  long len;
1808 
1809  len = format.size() + className.string().size();
1810  s_str = (char *)malloc(sizeof(char)*len);
1811  snprintf(s_str, len, format.c_str(), className.c_str());
1812  *returnedFileName = gensym(s_str);
1813  free(s_str);
1814 }
1815 
1816 
1817 // Files
1818 ///////////////////////////////////////////////
1819 
1820 
1821 /** Get BOOT style filepath from args or, if no args open a dialog to write a file */
1822 TTSymbol jamoma_file_write(t_object *x, long argc, t_atom *argv, char* default_filename)
1823 {
1824  char fullpath[MAXPDSTRING]; // for storing the absolute path of the file
1825  short err, path; // pathID#, error number
1826 // t_filehandle file_handle; // a reference to our file (for opening it, closing it, etc.)
1827 // t_fourcc filetype = 'TEXT', outtype; // the file type that is actually true
1828  t_symbol *userpath;
1829  TTSymbol result = kTTSymEmpty;
1830 
1831  // Give a path ...
1832  if (argc && argv) {
1833  if (atom_gettype(argv) == A_SYM) {
1834  userpath = atom_getsym(argv);
1835 
1836  if (userpath != _sym_nothing && userpath != _sym_bang) {
1837  // Use BOOT style path
1838  path = 0;
1839 
1840  t_binbuf* buf = binbuf_new();
1841  // path_nameconform(userpath->s_name, fullpath, PATH_STYLE_NATIVE, PATH_TYPE_BOOT);// Copy symbol argument to a local string
1842  canvas_makefilename(((t_eobj*)x)->o_canvas,userpath->s_name,fullpath,MAXPDSTRING);
1843  binbuf_write(buf,fullpath,"",1);
1844  binbuf_free(buf);
1845  // Create a file using Max API
1846  // path_createsysfile(fullpath, path, filetype, &file_handle);
1847 
1848  result = TTSymbol(fullpath);
1849  }
1850  }
1851  }
1852  /* TODO rewrite an open panel for Pd ?
1853  // ... or open a dialog
1854  if (result == kTTSymEmpty) {
1855 
1856  saveas_promptset("Save Preset..."); // Instructional Text in the dialog
1857  err = saveasdialog_extended(default_filename, &path, &outtype, &filetype, 1); // Returns 0 if successful
1858  if (!err) { // User Cancelled
1859  char posixpath[MAX_PATH_CHARS];
1860 
1861  // Create a file using Max API
1862  path_createsysfile(default_filename, path, filetype, &file_handle);
1863 
1864  // Use BOOT style path
1865  path_topathname(path, default_filename, fullpath);
1866  path_nameconform(fullpath, posixpath, PATH_STYLE_NATIVE, PATH_TYPE_BOOT);
1867 
1868  result = TTSymbol(posixpath);
1869  }
1870  }
1871  */
1872 
1873  return result;
1874 }
1875 
1876 /** Get BOOT style filepath from args or, if no args open a dialog to read a file */
1877 TTSymbol jamoma_file_read(t_object *x, long argc, t_atom *argv, t_fourcc filetype)
1878 {
1879  char filepath[MAXPDSTRING]; // for storing the name of the file locally
1880  char fullpath[MAXPDSTRING]; // path and name passed on to the xml parser
1881  char posixpath[MAXPDSTRING];
1882  short path = 0; // pathID#
1883  t_fourcc outtype;
1884  t_symbol *userpath;
1885  TTSymbol result = kTTSymEmpty;
1886 
1887  // Give a path ...
1888  if (argc && argv) {
1889  if (atom_gettype(argv) == A_SYM) {
1890  userpath = atom_getsym(argv);
1891 
1892  if (userpath != _sym_nothing && userpath != _sym_bang) {
1893 
1894  canvas_makefilename(((t_eobj*)x)->o_canvas,userpath->s_name,fullpath,MAXPDSTRING);
1895 
1896  result = TTSymbol(fullpath);
1897 
1898 // strcpy(filepath, userpath->s_name); // must copy symbol before calling locatefile_extended
1899 // if (locatefile_extended(filepath, &path, &outtype, &filetype, 1)) { // Returns 0 if successful
1900 
1901 // pd_error(x, "%s : not found", filepath);
1902 // return result;
1903 // }
1904  }
1905  }
1906  }
1907 
1908  // ... or open a dialog
1909  /* TODO rewrite an open panel for Pd ?
1910  if (!path)
1911  open_dialog(filepath, &path, &outtype, &filetype, 1);
1912  */
1913 
1914  /*
1915  if (path) {
1916 
1917  open_via_path(path,filepath,"",fullpath,posixpath,MAXPDSTRING,0);
1918 // path_topathname(path, filepath, fullpath);
1919 // path_nameconform(fullpath, posixpath, PATH_STYLE_NATIVE, PATH_TYPE_BOOT);
1920  result = TTSymbol(posixpath);
1921  }
1922  */
1923 
1924  return result;
1925 }
TTErr jamoma_input_create(t_object *x, TTObject &returnedInput)
Create an input object for any signal.
TTErr setSchema(const TTSymbol schemaName)
TODO: Add documentation schemaName TODO: Add documentation.
JAMOMA_EXPORT TTRegex * ttRegexForJmod
A global regex to parse jmod. (usefull to detect a 0.5 module)
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
void jamoma_ttvalue_to_typed_Atom(const TTValue &v, t_symbol **msg, long *argc, t_atom **argv, TTBoolean &shifted)
Return audio signal.
TTErr jamoma_sender_send(TTObject &aSender, t_symbol *msg, long argc, const t_atom *argv)
Send Max data using a sender object.
TTErr jamoma_input_send(TTObject &anInput, t_symbol *msg, long argc, const t_atom *argv)
Send any signal to an input object.
TTErr send(const TTSymbol aName)
Send a message to this object with no arguments.
Definition: TTObject.cpp:135
TTErr jamoma_output_create_audio(t_object *x, TTObject &returnedOutput)
Create an output object for audio signal.
TTAddress appendAttribute(TTSymbol anAttribute)
Return a new TTAddress with attribute part.
Definition: TTAddress.h:161
We build a directory of TTNodes, and you can request a pointer for any TTNode, or add an observer to ...
Definition: TTNode.h:59
TTHashPtr jamoma_explorer_default_filter_bank(void)
A type that contains a key and a value.
TTErr jamoma_viewer_create(t_object *x, TTObject &returnedViewer)
Create a viewer object.
t_symbol * jamoma_parse_dieze(t_canvas *x, t_symbol *address)
Parse #N inside address and replace them by parent patcher arguments if there are.
TTAddress getParent()
Get a pointer to the parent address.
Definition: TTAddress.h:112
const char * c_str() const
Return a pointer to the internal C-string.
Definition: TTString.h:83
TTErr jamoma_mapper_create(t_object *x, TTObject &returnedMapper)
Create a mapper object.
TTBoolean jamoma_patcher_get_ui(t_canvas *patcher)
Is there a j.ui object.
TTErr jamoma_container_create(t_object *x, TTObject &returnedContainer)
Create a container object.
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
size_type size() const noexcept
Return the number of elements.
JAMOMA_EXPORT TTRegex * ttRegexForJcom
A global regex to parse j.
void jamoma_callback_return_address(const TTValue &baton, const TTValue &v)
Return an address to a j.
void jamoma_patcher_share_info(t_canvas *patcher, t_canvas **returnedPatcher, TTSymbol &returnedContext, TTSymbol &returnedClass, TTSymbol &returnedName)
Get all context info from the root j.model|view in the patcher.
void JAMOMA_EXPORT jamoma_callback_return_ramped_value(void *o, TTUInt32 n, TTFloat64 *v)
this flag means that an address have no leading slash
Definition: TTAddressBase.h:64
TTErr jamoma_ramp_create(t_object *x, TTObject &returnedRamp)
Create a TTRamp object.
void jamoma_patcher_get_model_patcher(t_canvas *patcher, TTSymbol modelClass, t_object **returnedModelPatcher)
Get the "aClass.model" external in the patcher.
TTErr jamoma_output_create(t_object *x, TTObject &returnedOutput)
Create an output object for signal.
void jamoma_edit_filename(TTString format, TTSymbol className, t_symbol **returnedFileName)
edit a file name from a given file format and a class name
Maintain a collection of TTValue objects indexed by TTSymbol pointers.
Definition: TTHash.h:36
Symbol type.
Definition: TTBase.h:282
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
#define ToAppName(ttName)
Convert a local application TTSymbol into a tt name.
JAMOMA_EXPORT TTRegex * ttRegexForModel
A global regex to parse .model.
TTErr jamoma_cueManager_create(t_object *x, TTObject &returnedCueManager)
Create a cue manager object.
void jamoma_edit_numeric_instance(TTString format, t_symbol **returnedName, long i)
edit a new instance of the given format address using interger
TTSymbol jamoma_file_write(t_object *x, long argc, t_atom *argv, char *default_filename)
Get BOOT style filepath from args or, if no args open a dialog to write a file.
void jamoma_callback_return_value_typed(const TTValue &baton, const TTValue &v)
Return the value to a j.
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 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 container object.
TTErr get(const TTSymbol aName, T &aReturnedValue) const
Get an attribute value for an object.
void jamoma_ttvalue_to_Atom(const TTValue &v, long *argc, t_atom **argv)
Make an Atom array from a TTValue (!!! this method allocate memory for the Atom array ! free it after...
void jamoma_ttvalue_from_Atom(TTValue &v, t_symbol *msg, long argc, const t_atom *argv)
Make a TTValue from Atom array.
void jamoma_callback_return_value(const TTValue &baton, const TTValue &v)
Return the value to a j.
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
TTErr jamoma_sender_create(t_object *x, TTObject &returnedSender)
Create a sender object.
TTErr append(const TTSymbol key, const TTValue &value)
Insert an item into the hash table.
Definition: TTHash.cpp:70
TTErr jamoma_output_send(TTObject &anOutput, t_symbol *msg, long argc, const t_atom *argv)
Send any signal to an output object.
void jamoma_patcher_get_class(t_canvas *patcher, TTSymbol context, TTSymbol &returnedClass)
Get the class of the patcher from the file name (removing .model and .view convention name if they ex...
float TTFloat32
32 bit floating point number
Definition: TTBase.h:187
#define ToTTName(appName)
Convert a tt name TTSymbol into a local application name.
TTErr jamoma_explorer_create(t_object *x, TTObject &returnedExplorer)
Create an explorer object.
JAMOMA_EXPORT TTRegex * ttRegexForModule
A global regex to parse .module.
TTUInt32 jamoma_parse_bracket(t_symbol *s, TTString &si_format, TTString &ss_format)
returned the N inside "pp/xx.[N]/yyy" and a format string as "pp/xx.%d/yy" and a format string as "pp...
TTSymbol & getAttribute()
Get the attribute part.
Definition: TTAddress.h:130
TTSymbol getNameInstance()
Get the name.instance part.
Definition: TTAddress.h:142
TTErr jamoma_presetManager_create(t_object *x, TTObject &returnedPresetManager)
Create a preset manager object.
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
void jamoma_edit_string_instance(TTString format, t_symbol **returnedName, TTString s)
edit a new instance of the given format address using string
TTErr jamoma_receiver_create_audio(t_object *x, TTObject &returnedReceiver)
Create a receiver object for audio signal.
JAMOMA_EXPORT TTRegex * ttRegexForBracket
A global regex to parse [ and ].
JAMOMA_EXPORT TTRegex * ttRegexForPdhelp
A global regex to parse .maxhelp.
Definition: JamomaForPd.cpp:41
void jamoma_patcher_share_node(t_canvas *patcher, TTNodePtr *patcherNode)
Get patcher's node from the root j.model|view in the patcher.
TTErr jamoma_sender_create_audio(t_object *x, TTObject &returnedSender)
Create a sender object for audio signal.
JamomaModular For Max Shared Library.
TTErr jamoma_patcher_get_info(t_canvas *obj, t_canvas **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 clear()
Clear all values from the vector, leaving with size of 0.
Definition: TTValue.h:131
TTErr jamoma_viewer_send(TTObject &aViewer, t_symbol *msg, long argc, const t_atom *argv)
Send Max data using a viewer object.
t_symbol * jamoma_patcher_get_hierarchy(t_canvas *canvas)
Get the hierarchy of the patcher : bpatcher, subpatcher or top level one.
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
Definition: TTBase.h:344
void jamoma_patcher_get_context(t_canvas *patcher, TTSymbol &returnedContext)
Get the context from the upper j.model|view in the patcher or from patcher's name.
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
TTErr append(const TTSymbol key, const TTValue &value)
Insert an item into the hash table.
t_symbol * jamoma_TTName_To_PdName(TTSymbol TTName)
Convert a TTSymbol "MyObjectMessage" into a t_symbol *"my/object/message" or return NULL if the TTSym...
JAMOMA_EXPORT TTRegex * ttRegexForPdpat
A global regex to parse .maxpat.
Definition: JamomaForPd.cpp:40
std::uint32_t TTUInt32
32 bit unsigned integer
Definition: TTBase.h:178
void jamoma_callback_return_signal(const TTValue &baton, const TTValue &v)
Return any signal.
TTErr jamoma_data_create(t_object *x, TTObject &returnedData, TTSymbol service)
Create a data object.
size_t size() const
Find out the length of a string.
Definition: TTString.h:144
TTErr jamoma_receiver_create(t_object *x, TTObject &returnedReceiver)
Create a receiver object.
JAMOMA_EXPORT TTRegex * ttRegexForView
A global regex to parse .view.
void jamoma_patcher_get_name(t_canvas *patcher, TTSymbol context, TTSymbol &returnedName)
Get the name of the patcher from his arguments.
TTErr jamoma_data_command(TTObject &aData, t_symbol *msg, long argc, const t_atom *argv)
Send Max data command.
TTErr JAMOMA_EXPORT jamoma_node_info_create(t_object *x, TTObject &returnedNodeInfo)
Create a TTNodeInfo object.
No Error.
Definition: TTBase.h:343
TTSymbol jamoma_file_read(t_object *x, long argc, t_atom *argv, t_fourcc filetype)
Get BOOT style filepath from args or, if no args open a dialog to read a file.
void jamoma_subscriber_get_patcher_list(t_eobj *x, TTList &aContextListToFill)
Get the list above an external.
The TTString class is used to represent a string.
Definition: TTString.h:34
TTBoolean valid() const
Determine if the object contained by this TTObject is truly ready for use.
Definition: TTObject.cpp:179
void jamoma_patcher_get_input_output(t_canvas *patcher, TTBoolean &dataInput, TTBoolean &dataOutput, TTBoolean &audioInput, TTBoolean &audioOutput)
Look for input and output (data and audio)
void resize(size_type n)
Change the number of elements.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
void jamoma_patcher_get_args(t_canvas *canvas, long *argc, t_atom **argv)
Load an external for internal use.
TTErr jamoma_input_create_audio(t_object *x, TTObject &returnedInput)
Create an input object for audio signal.
TTErr jamoma_subscriber_create(t_eobj *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 jamoma_patcher_get_model_or_view(t_canvas *patcher, t_object **returnedModelOrView)
Get j.model or j.view of a patcher.