26 typedef struct extra {
31 TTListPtr ui_qelem_list;
37 #define EXTRA ((t_extra*)x->extra)
40 void WrapTTViewerClass(WrappedClassPtr c);
41 void WrappedViewerClass_new(
TTPtr self,
long argc, t_atom *argv);
42 void WrappedViewerClass_free(
TTPtr self);
44 void remote_assist(
TTPtr self,
TTPtr b,
long msg,
long arg,
char *dst);
46 void remote_new_address(
TTPtr self, t_symbol *address);
48 void remote_array_subscribe(
TTPtr self, t_symbol *address);
49 void remote_array_select(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv);
50 void remote_address(
TTPtr self, t_symbol *name);
52 void remote_array_return_value(
const TTValue& baton,
const TTValue& v);
54 void remote_create_model_address_receiver(
TTPtr self);
55 void remote_free_model_address_receiver(
TTPtr self);
56 void remote_return_model_address(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv);
58 void WrappedViewerClass_anything(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv);
59 void remote_bang(
TTPtr self);
60 void remote_int(
TTPtr self,
long value);
61 void remote_float(
TTPtr self,
double value);
62 TTErr remote_list(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv);
64 TTErr remote_array(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv);
66 void remote_set(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv);
67 void remote_set_array(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv);
69 void remote_ui_queuefn(
TTPtr self);
73 ModularSpec *spec =
new ModularSpec;
74 spec->_wrap = &WrapTTViewerClass;
75 spec->_new = &WrappedViewerClass_new;
76 spec->_free = &WrappedViewerClass_free;
77 spec->_any = &WrappedViewerClass_anything;
82 void WrapTTViewerClass(WrappedClassPtr c)
84 class_addmethod(c->maxClass, (method)remote_assist,
"assist", A_CANT, 0L);
85 class_addmethod(c->maxClass, (method)remote_return_model_address,
"return_model_address", A_CANT, 0);
87 class_addmethod(c->maxClass, (method)remote_bang,
"bang", 0L);
88 class_addmethod(c->maxClass, (method)remote_int,
"int", A_LONG, 0);
89 class_addmethod(c->maxClass, (method)remote_float,
"float", A_FLOAT, 0);
90 class_addmethod(c->maxClass, (method)remote_list,
"list", A_GIMME, 0);
92 class_addmethod(c->maxClass, (method)remote_array,
"array", A_GIMME, 0);
94 class_addmethod(c->maxClass, (method)remote_set,
"set", A_GIMME, 0);
95 class_addmethod(c->maxClass, (method)remote_set_array,
"setArray", A_GIMME, 0);
97 class_addmethod(c->maxClass, (method)remote_address,
"address", A_SYM,0);
100 void WrappedViewerClass_new(
TTPtr self,
long argc, t_atom *argv)
103 long attrstart = attr_args_offset(argc, argv);
108 address = _sym_nothing;
109 if (attrstart && argv)
110 if (atom_gettype(argv) == A_SYM)
111 address = atom_getsym(argv);
114 x->
inlets = (TTHandle)sysmem_newptr(
sizeof(
TTPtr) * 1);
121 x->
outlets = (TTHandle)sysmem_newptr(
sizeof(
TTPtr) * 3);
122 x->
outlets[index_out] = outlet_new(x, NULL);
123 x->
outlets[data_out] = outlet_new(x, NULL);
124 x->
outlets[set_out] = outlet_new(x, NULL);
131 x->arrayAddress = kTTAdrsEmpty;
133 x->arrayAttrFormat = gensym(
"single");
138 EXTRA->modelAddressReceiver = NULL;
139 EXTRA->changingAddress = NO;
140 EXTRA->ui_qelem = qelem_new(x, (method)remote_ui_queuefn);
141 EXTRA->ui_qelem_list =
new TTList();
142 EXTRA->countSubscription = 0;
143 EXTRA->values =
new TTList();
147 remote_create_model_address_receiver(
self);
153 attr_args_process(x, argc, argv);
163 defer_low((t_object*)x, (method)remote_new_address, address, 0, NULL);
166 void WrappedViewerClass_free(
TTPtr self)
173 remote_free_model_address_receiver(
self);
175 qelem_free(EXTRA->ui_qelem);
177 delete EXTRA->ui_qelem_list;
179 delete EXTRA->values;
185 void remote_new_address(
TTPtr self, t_symbol *address)
193 t_symbol *instanceAddress;
198 x->arrayAddress = newAddress;
203 if (number && number <= MAX_ARRAY_SIZE) {
208 x->arraySize = number;
210 EXTRA->values->clear();
212 for (i = 1; i <= x->arraySize; i++) {
216 remote_array_create(x, anObject, i);
227 EXTRA->values->insert(0, v);
234 qelem_unset(EXTRA->ui_qelem);
235 EXTRA->ui_qelem_list->clear();
240 attr_args_process(x, argc, argv);
243 remote_array_subscribe(
self, address);
248 else if (number > MAX_ARRAY_SIZE)
249 object_error((t_object*)x,
"the size is greater than the maximum array size (%d)", MAX_ARRAY_SIZE);
258 returnedViewer =
TTObject(kTTSym_Viewer);
263 returnedViewer.
set(kTTSym_baton, baton);
264 returnedViewer.
set(kTTSym_function,
TTPtr(&remote_array_return_value));
267 void remote_array_subscribe(
TTPtr self, t_symbol *address)
270 t_symbol *instanceAddress;
272 TTAddress absoluteAddress, returnedAddress;
288 for (i = 1; i <= x->arraySize; i++) {
292 selectedObject->setAttributeValue(kTTSym_address, x->
cursor);
320 for (i = 1; i <= x->arraySize; i++) {
326 toSubscribe = selectedObject;
330 if (!
jamoma_subscriber_create((t_object*)x, toSubscribe,
TTAddress(instanceAddress->s_name), aSubscriber, returnedAddress, &returnedNode, &returnedContextNode)) {
334 aSubscriber.
get(
"contextAddress", v);
335 contextAddress = v[0];
338 if (aSubscriber.
valid()) {
352 contextAddress = kTTAdrsRoot;
354 selectedObject->setAttributeValue(kTTSym_address, absoluteAddress);
356 atom_setsym(a, gensym((
char*)absoluteAddress.
c_str()));
357 object_obex_dumpout((t_object*)x, gensym(
"address"), 1, a);
369 if (contextAddress != kTTAdrsEmpty) {
372 EXTRA->modelAddressReceiver->set(kTTSym_address, contextAddress.
appendAddress(
TTAddress(
"model:address")));
386 for (i = 1; i <= x->arraySize; i++) {
396 if (aSubscriber.
valid())
412 EXTRA->countSubscription++;
413 if (EXTRA->countSubscription > 100) {
414 object_error((t_object*)x,
"tries to bind too many times on %s", address->s_name);
415 object_obex_dumpout((t_object*)x, gensym(
"error"), 0, NULL);
422 defer_low((t_object*)x, (method)remote_array_subscribe, address, 0, NULL);
425 void remote_address(
TTPtr self, t_symbol *address)
428 t_symbol *instanceAddress;
433 if (!EXTRA->changingAddress) {
435 EXTRA->changingAddress = YES;
438 if (!(x->arrayAddress ==
TTAddress(address->s_name))) {
446 for (i = 1; i <= x->arraySize; i++) {
454 o.
set(kTTSym_address, kTTAdrsEmpty);
466 EXTRA->countSubscription = 0;
468 defer(
self,(method)remote_new_address, address, 0, NULL);
472 EXTRA->changingAddress = NO;
476 object_error((t_object*)x,
"can't change to %s address. Please defer low", address->s_name);
480 void remote_assist(
TTPtr self,
TTPtr b,
long msg,
long arg,
char *dst)
485 strcpy(dst,
"set the value of the selected instance(s)");
488 strcpy(dst,
"index (use * to bind all instances)");
495 strcpy(dst,
"set: connect to ui object");
498 strcpy(dst,
"direct: values");
501 strcpy(dst,
"index");
504 strcpy(dst,
"dumpout");
510 void remote_bang(
TTPtr self)
514 if (x->arraySize > 0)
515 remote_list(
self, _sym_bang, 0, NULL);
517 object_error((t_object*)x,
"bang : the array is empty");
520 void remote_int(
TTPtr self,
long value)
525 if (proxy_getinlet((t_object*)x)) {
526 atom_setlong(&a, value);
527 wrappedModularClass_ArraySelect(
self, _sym_nothing, 1, &a);
530 if (x->arraySize > 0) {
531 atom_setlong(&a, value);
532 remote_list(
self, _sym_int, 1, &a);
535 object_error((t_object*)x,
"int : the array is empty");
539 void remote_float(
TTPtr self,
double value)
544 if (x->arraySize > 0) {
546 atom_setfloat(&a, value);
547 remote_list(
self, _sym_float, 1, &a);
550 object_error((t_object*)x,
"float : the array is empty");
553 TTErr remote_list(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv)
559 if (x->arraySize > 0) {
562 if (x->arrayIndex == 0) {
568 for (
int i = 0; i < keys.
size(); i++) {
589 object_error((t_object*)x,
"list : the array is empty");
594 void WrappedViewerClass_anything(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv)
599 if (proxy_getinlet((t_object*)x))
600 wrappedModularClass_ArraySelect(
self, msg, argc, argv);
602 remote_list(
self, msg, argc, argv);
605 TTErr remote_array(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv)
609 t_symbol *instanceAddress;
613 if (x->arraySize > 0) {
616 d = argc / x->arraySize;
617 if ((d * x->arraySize) == argc) {
623 for (i = 1; i <= x->arraySize; i++) {
639 object_error((t_object*)x,
"array : the array message size have to be a multiple of the array size");
643 object_error((t_object*)x,
"array : the array is empty");
648 void remote_set(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv)
652 EXTRA->setting = YES;
654 if (remote_list(
self, _sym_nothing, argc, argv))
659 void remote_set_array(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv)
663 EXTRA->setting = YES;
665 if (remote_array(
self, _sym_nothing, argc, argv))
670 void remote_array_return_value(
const TTValue& baton,
const TTValue& v)
692 if (x->arrayIndex == 0)
695 outlet_int(x->
outlets[index_out], i);
699 if (x->arrayAttrFormat == gensym(
"array"))
702 if (EXTRA->changingAddress)
709 TTListPtr vlist = EXTRA->values;
712 j = vlist->getSize();
720 vlist->current() = v;
723 TTValue prepend = vlist->current();
739 EXTRA->ui_qelem_list->append(array);
752 EXTRA->ui_qelem_list->append(v);
756 if (msg == _sym_nothing)
757 outlet_atoms(x->
outlets[data_out], argc, argv);
759 outlet_anything(x->
outlets[data_out], msg, argc, argv);
762 qelem_set(EXTRA->ui_qelem);
766 sysmem_freeptr(argv);
769 void remote_ui_queuefn(
TTPtr self)
776 for (EXTRA->ui_qelem_list->begin();
777 EXTRA->ui_qelem_list->end();
778 EXTRA->ui_qelem_list->next()) {
784 if (x->arrayAttrFormat == gensym(
"array"))
785 outlet_anything(x->
outlets[set_out], gensym(
"setlist"), argc, argv);
787 outlet_anything(x->
outlets[set_out], _sym_set, argc, argv);
789 sysmem_freeptr(argv);
792 EXTRA->ui_qelem_list->clear();
795 void remote_create_model_address_receiver(
TTPtr self)
799 TTObject returnValueCallback, empty;
804 returnValueCallback =
TTObject(
"callback");
807 returnValueCallback.
set(kTTSym_baton, baton);
809 args.
append(returnValueCallback);
811 EXTRA->modelAddressReceiver =
new TTObject(kTTSym_Receiver, args);
814 void remote_free_model_address_receiver(
TTPtr self)
818 EXTRA->modelAddressReceiver->set(kTTSym_address, kTTAdrsEmpty);
820 delete EXTRA->modelAddressReceiver;
823 void remote_return_model_address(
TTPtr self, t_symbol *msg,
long argc, t_atom *argv)
826 t_symbol *instanceAddress;
829 TTList returnedNodes;
838 for (i = 1; i <= x->arraySize; i++) {
845 selectedObject->setAttributeValue(kTTSym_address, address);
847 JamomaDebug object_post((t_object*)x,
"binds on %s", address.
c_str());
853 EXTRA->countSubscription = 0;
TTAddress appendAddress(const TTAddress &toAppend)
Return a new TTAddress with the appended part.
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
TTHandle outlets
an array of outlet
TTErr wrapTTModularClassAsMaxClass(TTSymbol &ttblueClassName, const char *maxClassName, WrappedClassPtr *c, ModularSpec *specificities)
Wrap a Jamoma class as a Max class.
TTErr lookup(const TTSymbol key, TTValue &value)
Find the value for the given key.
We build a directory of TTNodes, and you can request a pointer for any TTNode, or add an observer to ...
TTSymbol patcherClass
the patcher class in which the external is
The TTAddress class is used to represent a string and efficiently pass and compare that string...
Create and use Jamoma object instances.
size_type size() const noexcept
Return the number of elements.
void * extra
used to keep very specific things
t_object * patcherPtr
the patcher in which the external is (ignoring subpatcher)
TTErr getKeys(TTValue &hashKeys)
Get an array of all of the keys for the hash table.
TTHashPtr internals
An hash table to store any internal TTObjectBases (like TTData, TTViewer, ...)
void prepend(const TTValue &aValueToPrepend)
Insert another TTValue before the first element.
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
void * TTPtr
A generic pointer.
TTErr get(const TTSymbol aName, T &aReturnedValue) const
Get an attribute value for an object.
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
TTErr append(const TTSymbol key, const TTValue &value)
Insert an item into the hash table.
TTHandle inlets
an array of inlets
TTBoolean iterateInternals
The flag is true when an iteration is done on the internals.
TTBoolean isEmpty()
Return true if the hash has nothing stored in it.
this flag means that an address have a leading slash
const char * c_str() const
Return a pointer to the internal string as a C-string.
std::int32_t TTInt32
32 bit signed integer
TTErr clear()
Remove all items from the hash table.
void clear()
Clear all values from the vector, leaving with size of 0.
void set(const TTUInt16 index, const T &anElementValue)
DEPRECATED.
Data Structure for this object.
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
int C74_EXPORT main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
TTAddressType getType()
Get the type.
TTErr remove(const TTSymbol key)
Remove an item from the hash table.
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Wraps Jamoma Core classes as objects for Max/MSP.
std::uint32_t TTUInt32
32 bit unsigned integer
TTSymbol patcherContext
the patcher context in which the external is (model, view)
TTBoolean useInternals
The hash table can be used as an array of wrappedObject.
TTSymbol patcherName
the patcher name in which the external is
long index
index of the inlet used
TTSymbol cursor
to select an entry in x->internals
TTBoolean valid() const
Determine if the object contained by this TTObject is truly ready for use.
WrappedModularInstance * WrappedModularInstancePtr
Pointer to a wrapped instance of our object.
[doxygenAppendixC_copyExample]