TTErr makeInternals_sender(TTPtr self, TTAddress address, TTSymbol name, TTObject& returnedSender, TTBoolean appendNameAsAttribute) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTValue v; TTAddress adrs; // check the internals do not exist yet if (!x->internals->lookup(name, v)) { returnedSender = v[0]; JamomaDebug object_post((t_object*)x, "makeInternals_sender : \"%s\" internal already exists", name.c_str()); return kTTErrNone; } returnedSender = TTObject(kTTSym_Sender); // edit address if (appendNameAsAttribute) adrs = address.appendAttribute(name); else adrs = address.appendAddress(TTAddress(name.c_str())); // default registration case : store object only (see in unregister method) x->internals->append(name, returnedSender); // set address attribute returnedSender.set(kTTSym_address, adrs); JamomaDebug object_post((t_object*)x, "makes internal \"%s\" sender to bind on : %s", name.c_str(), adrs.c_str()); return kTTErrNone; }
void init_subscribe(t_init *x) { TTValue v, args, none; TTAddress contextAddress = kTTAdrsEmpty; TTAddress returnedAddress; TTNodePtr returnedNode = NULL; TTNodePtr returnedContextNode = NULL; TTObject returnAddressCallback, returnValueCallback, empty; // for relative address if (x->address.getType() == kAddressRelative) { if (!jamoma_subscriber_create((t_object*)x, empty, x->address, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode)) { // get the context address to make // a receiver on the contextAddress:initialized attribute x->subscriberObject.get("contextAddress", v); contextAddress = v[0]; } // bind on the /model:address parameter (view patch) or return (model patch) if (contextAddress != kTTAdrsEmpty) { // Make a TTReceiver object returnAddressCallback = TTObject("callback"); returnAddressCallback.set(kTTSym_baton, TTPtr(x)); returnAddressCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_address)); args.append(returnAddressCallback); returnValueCallback = TTObject("callback"); returnValueCallback.set(kTTSym_baton, TTPtr(x)); returnValueCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value)); args.append(returnValueCallback); x->initReceiver = TTObject(kTTSym_Receiver, args); x->initReceiver.set(kTTSym_address, contextAddress.appendAttribute(kTTSym_initialized)); } // while the context node is not registered : try to binds again :( // (to -- this is not a good way todo. For binding we should make a subscription // to a notification mechanism and each time an TTObjet subscribes to the namespace // using jamoma_subscriber_create we notify all the externals which have used // jamoma_subscriber_create with NULL object to bind) else { // release the subscriber x->subscriberObject = TTObject(); // The following must be deferred because we have to interrogate our box, // and our box is not yet valid until we have finished instantiating the object. // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6) defer_low((t_object*)x, (method)init_subscribe, NULL, 0, 0); } } else object_error((t_object*)x, "can't bind because %s is not a relative address", x->address.c_str()); }
TTErr TTProtocol::ReceiveSetRequest(TTSymbol from, TTAddress address, const TTValue& newValue) { TTValue v, none; TTErr err; // set the an object in the namespace if (address.getAttribute() == NO_ATTRIBUTE) address = address.appendAttribute(kTTSym_value); v.append(address); v.append((TTPtr)&newValue); err = mApplicationManager.send("ApplicationSet", v); // TODO : test error and send notification if error return err; }
TTErr TTProtocol::ReceiveGetRequest(TTSymbol from, TTAddress address) { TTErr err; TTValue returnedValue; if (!mRunning) return kTTErrGeneric; // discover the namespace if (address.getAttribute() == NO_ATTRIBUTE) address = address.appendAttribute(kTTSym_value); err = mApplicationManager.send("ApplicationGet", address, returnedValue); return SendGetAnswer(from, address, returnedValue, err); }
TTErr makeInternals_receiver(TTPtr self, TTAddress address, TTSymbol name, t_symbol *callbackMethod, TTObject& returnedReceiver, TTBoolean deferlow, TTBoolean appendNameAsAttribute) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTValue v, args, baton; TTObject returnValueCallback, empty; TTAddress adrs; // check the internals do not exist yet if (!x->internals->lookup(name, v)) { returnedReceiver = v[0]; JamomaDebug object_post((t_object*)x, "makeInternals_receiver : \"%s\" internal already exists", name.c_str()); returnedReceiver.send("Get"); return kTTErrNone; } // prepare arguments // we don't want the address back args.append(empty); returnValueCallback = TTObject("callback"); baton = TTValue(TTPtr(x), TTPtr(callbackMethod), deferlow); returnValueCallback.set(kTTSym_baton, baton); returnValueCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value)); args.append(returnValueCallback); returnedReceiver = TTObject(kTTSym_Receiver, args); // edit address if (appendNameAsAttribute) adrs = address.appendAttribute(name); else adrs = address.appendAddress(TTAddress(name.c_str())); // default registration case : store object only (see in unregister method) x->internals->append(name, returnedReceiver); // set address attribute (after registration as the value can be updated in the same time) returnedReceiver.set(kTTSym_address, adrs); JamomaDebug object_post((t_object*)x, "makes internal \"%s\" receiver to bind on : %s", name.c_str(), adrs.c_str()); return kTTErrNone; }
TTErr TTProtocol::ReceiveListenAnswer(TTSymbol from, TTAddress address, const TTValue& newValue) { TTValue v, none; TTErr err; TTValue dummy; if (address.getAttribute() == NO_ATTRIBUTE) address = address.appendAttribute(kTTSym_value); v.append(from); v.append(address); v.append((TTPtr)&newValue); err = mApplicationManager.send("ApplicationListenAnswer", v); if (err && mRunning) return SendListenAnswer(from, address, dummy, err); return kTTErrGeneric; }
TTErr TTProtocol::ReceiveListenRequest(TTSymbol from, TTAddress address, TTBoolean enable) { TTValue v, none; TTErr err; // listen an object or the namespace if (address.getAttribute() == NO_ATTRIBUTE) address = address.appendAttribute(kTTSym_value); v.append(mName); // the name of the protocol is needed for feed back notifications v.append(from); v.append(address); v.append(enable); err = mApplicationManager.send("ApplicationListen", v); if (err && mRunning) return SendListenAnswer(from, address, none, err); return kTTErrGeneric; }
TTErr TTProtocolListenAttributeCallback(const TTValue& baton, const TTValue& data) { TTObject aProtocol; TTSymbol anApplicationName; TTAddress anAddress; TTSymbol attribute; TTBoolean enable; // unpack baton aProtocol = baton[0]; anApplicationName = baton[1]; anAddress = baton[2]; // unpack data attribute = data[0]; enable = data[1]; // send a listen request if (TTProtocolPtr(aProtocol.instance())->mRunning) return TTProtocolPtr(aProtocol.instance())->SendListenRequest(anApplicationName, anAddress.appendAttribute(attribute), enable); else return kTTErrGeneric; }
TTErr TTProtocolSendMessageCallback(const TTValue& baton, const TTValue& data) { TTValuePtr value; TTObject aProtocol; TTSymbol anApplicationName; TTAddress anAddress; TTSymbol message; // unpack baton aProtocol = baton[0]; anApplicationName = baton[1]; anAddress = baton[2]; // unpack data message = data[0]; value = TTValuePtr((TTPtr)data[1]); // send a set request if (TTProtocolPtr(aProtocol.instance())->mRunning) return TTProtocolPtr(aProtocol.instance())->SendSetRequest(anApplicationName, anAddress.appendAttribute(message), *value); else return kTTErrGeneric; }
TTErr TTProtocolDirectoryCallback(const TTValue& baton, const TTValue& data) { TTObject aProtocol; TTSymbol anApplicationName; TTAddress anAddress; TTNodePtr aNode; TTUInt8 flag; TTObject anObserver; TTValue v; // unpack baton aProtocol = baton[0]; anApplicationName = baton[1]; // unpack data (anAddress, aNode, flag, anObserver) anAddress = data[0]; aNode = TTNodePtr((TTPtr)data[1]); flag = data[2]; anObserver = data[3]; if (flag == kAddressCreated) { if (aNode->getObject().valid()) v.append(aNode->getObject().name()); else v.append(kTTSym_none); } else if (flag == kAddressDestroyed) { v.append(TTSymbol("delete")); } if (TTProtocolPtr(aProtocol.instance())->mRunning) return TTProtocolPtr(aProtocol.instance())->SendListenAnswer(anApplicationName, anAddress.appendAttribute(TTSymbol("life")), v); else return kTTErrGeneric; }