void DemoApp::Quit() { TTValue out; TTLogMessage("\n*** Release mApplicationDemo datas ***\n"); ///////////////////////////////////////////////////////////////////// // Unregister the parameter if ( mApplicationDemo.send("ObjectUnregister", "/myParameter", out)) TTLogError("Error : can't unregister data at /myParameter address \n"); // Unregister the message if (mApplicationDemo.send("ObjectUnregister", "/myMessage", out)) TTLogError("Error : can't unregister data at /myMessage address \n"); // Unregister the return if (mApplicationDemo.send("ObjectUnregister", "/myReturn", out)) TTLogError("Error : can't unregister data at /myReturn address \n"); TTLogMessage("\n*** Release application ***\n"); ///////////////////////////////////////////////////////////////////// mApplicationManager.send("ApplicationRelease", "demo", out); // delete the polling thread if (mPollingThread) mPollingThread->wait(); delete mPollingThread; }
void cue_doedit(TTPtr self) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTObject aTextHandler; TTValue o, args; t_atom a; TTErr tterr; // get the buffer handler tterr = x->internals->lookup(kTTSym_TextHandler, o); if (!tterr) { aTextHandler = o[0]; critical_enter(0); tterr = aTextHandler.send(kTTSym_Read, (TTPtr)EXTRA->text); critical_exit(0); // output a flag atom_setsym(&a, gensym("closed")); object_obex_dumpout(self, gensym("editor"), 1, &a); if (tterr) object_obex_dumpout(self, _sym_error, 0, NULL); } delete EXTRA->text; EXTRA->text = NULL; EXTRA->textEditor = NULL; *EXTRA->toEdit = x->wrappedObject; EXTRA->cueName = kTTSymEmpty; }
void cue_dowrite_again(TTPtr self) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTValue o, v; TTObject aTextHandler; TTErr tterr; if (x->wrappedObject.valid()) { tterr = x->internals->lookup(kTTSym_TextHandler, o); if (!tterr) { aTextHandler = o[0]; aTextHandler.set(kTTSym_object, x->wrappedObject); critical_enter(0); tterr = aTextHandler.send(kTTSym_WriteAgain, v); critical_exit(0); if (!tterr) object_obex_dumpout(self, _sym_write, 0, NULL); else object_obex_dumpout(self, _sym_error, 0, NULL); } } }
void cue_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; char filename[MAX_FILENAME_CHARS]; TTSymbol fullpath; TTValue o, v; TTObject aTextHandler; TTErr tterr; if (x->wrappedObject.valid()) { // Default TEXT File Name snprintf(filename, MAX_FILENAME_CHARS, "untitled.cues.txt"); fullpath = jamoma_file_write((t_object*)x, argc, argv, filename); v.append(fullpath); tterr = x->internals->lookup(kTTSym_TextHandler, o); if (!tterr) { aTextHandler = o[0]; aTextHandler.set(kTTSym_object, x->wrappedObject); critical_enter(0); tterr = aTextHandler.send(kTTSym_Write, v); critical_exit(0); if (!tterr) object_obex_dumpout(self, _sym_write, argc, argv); else object_obex_dumpout(self, _sym_error, 0, NULL); } } }
void cue_doread(TTPtr self, t_symbol *msg, long argc, t_atom *argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTValue o, v; TTSymbol fullpath; TTObject aTextHandler; TTErr tterr; if (x->wrappedObject.valid()) { fullpath = jamoma_file_read((t_object*)x, argc, argv, (t_fourcc)'TEXT'); v.append(fullpath); tterr = x->internals->lookup(kTTSym_TextHandler, o); if (!tterr) { aTextHandler = o[0]; aTextHandler.set(kTTSym_object, x->wrappedObject); critical_enter(0); tterr = aTextHandler.send(kTTSym_Read, v); critical_exit(0); if (!tterr) object_obex_dumpout(self, _sym_read, argc, argv); else object_obex_dumpout(self, _sym_error, 0, NULL); } } }
void model_preset_dowrite_again(TTPtr self) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTObject aTextHandler; TTValue o; TTErr tterr; // stop filewatcher if (EXTRA->filewatcher) filewatcher_stop(EXTRA->filewatcher); tterr = x->internals->lookup(kTTSym_TextHandler, o); if (!tterr) { aTextHandler = o[0]; aTextHandler.set(kTTSym_object, *EXTRA->presetManager); critical_enter(0); tterr = aTextHandler.send(kTTSym_WriteAgain); critical_exit(0); if (!tterr) object_obex_dumpout(self, _sym_write, 0, NULL); else object_obex_dumpout(self, _sym_error, 0, NULL); } // start filewatcher if (EXTRA->filewatcher) filewatcher_start(EXTRA->filewatcher); }
void model_preset_doread_again(TTPtr self) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTObject aTextHandler; TTValue o; TTErr tterr; tterr = x->internals->lookup(kTTSym_TextHandler, o); if (!tterr) { aTextHandler = o[0]; aTextHandler.set(kTTSym_object, *EXTRA->presetManager); critical_enter(0); tterr = aTextHandler.send(kTTSym_ReadAgain); critical_exit(0); if (!tterr) object_obex_dumpout(self, _sym_read, 0, NULL); else object_obex_dumpout(self, _sym_error, 0, NULL); } }
void DemoApp::SetMessage(std::string s) { TTSymbol message(s); TTValue out; mDataDemoMessage.send("Command", message, out); }
void DemoApp::SetupScore() { TTValue args, out; TTObject xmlHandler("XmlHandler"); TTLogMessage("\n*** Initialisation of Score environnement ***\n"); ///////////////////////////////////////////////////////////////////// // Init the Score library (passing the folder path where all the dylibs are) TTScoreInit("/usr/local/jamoma"); TTLogMessage("\n*** Reading of an interactive scenario file ***\n"); ///////////////////////////////////////////////////////////////////// // Create an empty Scenario mScenario = TTObject("Scenario"); // Read DemoScenario1.score file to fill mScenario xmlHandler.set("object", mScenario); xmlHandler.send("Read", "../DemoScenario.score", out); TTLogMessage("\n*** Prepare scenario observation ***\n"); ///////////////////////////////////////////////////////////////////// // Create a callback for the "EventStatusChanged" notification sent by each event mEventStatusChangedCallback = TTObject("callback"); mEventStatusChangedCallback.set("baton", TTPtr(this)); mEventStatusChangedCallback.set("function", TTPtr(&DemoAppEventStatusChangedCallback)); mEventStatusChangedCallback.set("notification", TTSymbol("EventStatusChanged")); // Get all events of the scenario and attach a callback to them TTValue timeEvents; mScenario.get("timeEvents", timeEvents); for (TTElementIter it = timeEvents.begin() ; it != timeEvents.end() ; it++) { TTObject event = TTElement(*it); event.registerObserverForNotifications(mEventStatusChangedCallback); } TTLogMessage("\n*** Start scenario execution ***\n"); ///////////////////////////////////////////////////////////////////// // Set the execution speed of the scenario mScenario.set("speed", 2.); // Start the scenario mScenario.send("Start"); // Poll Scenario information mPollingThread = new TTThread(TTThreadCallbackType(DemoAppScenarioPollingThread), this); }
TTErr MinuitSenderManager::send(TTSymbol applicationName, TTSymbol ip, TTUInt16 port, const TTValue& message) { TTValue last; // if nothing is being sent to an application if (mSending.findEquals(applicationName, last)) { // lock application mSending.append(applicationName); TTObject anOscSender; TTErr err = mSenders.lookup(applicationName, last); if (err) { anOscSender = TTObject("osc.send"); anOscSender.set("address", ip); anOscSender.set("port", port); TTValue cache(anOscSender, ip, port); mSenders.append(applicationName, cache); } else { anOscSender = last[0]; TTSymbol lastIp = last[1]; TTUInt16 lastPort = last[2]; if (lastIp == ip && lastPort == port) ; else { anOscSender.set("address", ip); anOscSender.set("port", port); TTValue cache(anOscSender, ip, port); mSenders.remove(applicationName); mSenders.append(applicationName, cache); } } err = anOscSender.send("send", message); // unlock application mSending.remove(applicationName); return kTTErrNone; } return kTTErrGeneric; }
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; }
void model_preset_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; char filename[MAX_FILENAME_CHARS]; TTSymbol fullpath; TTValue o, v, none; TTObject aTextHandler; TTErr tterr; // stop filewatcher if (EXTRA->filewatcher) filewatcher_stop(EXTRA->filewatcher); if (EXTRA->presetManager->valid()) { // Default TEXT File Name snprintf(filename, MAX_FILENAME_CHARS, "%s.%s.presets.txt", x->patcherClass.c_str(), x->patcherContext.c_str()); fullpath = jamoma_file_write((t_object*)x, argc, argv, filename); v.append(fullpath); tterr = x->internals->lookup(kTTSym_TextHandler, o); if (!tterr) { aTextHandler = o[0]; aTextHandler.set(kTTSym_object, *EXTRA->presetManager); critical_enter(0); tterr = aTextHandler.send(kTTSym_Write, v, none); critical_exit(0); if (!tterr) object_obex_dumpout(self, _sym_write, argc, argv); else object_obex_dumpout(self, _sym_error, 0, NULL); } } // start filewatcher if (EXTRA->filewatcher) filewatcher_start(EXTRA->filewatcher); }
void DemoApp::SetupModular() { TTValue args, v, out, none; TTAddress address; TTErr err; TTLogMessage("\n*** Initialisation of Modular environnement ***\n"); ///////////////////////////////////////////////////////////////////// // Init the Modular library (passing the folder path where all the dylibs are) TTModularInit("/usr/local/jamoma"); // Create an application manager mApplicationManager = TTObject("ApplicationManager"); TTLogMessage("\n*** Creation of mApplicationDemo application ***\n"); ///////////////////////////////////////////////////////////////////// // Create a local application called "demo" and get it back err = mApplicationManager.send("ApplicationInstantiateLocal", "demo", out); if (err) { TTLogError("Error : can't create demo application \n"); return; } else mApplicationDemo = out[0]; TTLogMessage("\n*** Creation of mApplicationDemo datas ***\n"); ///////////////////////////////////////////////////////////////////// // Create a parameter data and set its callback function and baton and some attributes mDataDemoParameter = TTObject("Data", "parameter"); // Setup the callback mechanism to get the value back args = TTValue(TTPtr(this), mDataDemoParameter); mDataDemoParameter.set("baton", args); mDataDemoParameter.set("function", TTPtr(&DemoAppDataReturnValueCallback)); // Setup the data attributes depending of its use inside the application mDataDemoParameter.set("type", "decimal"); mDataDemoParameter.set("rangeBounds", TTValue(0., 1.)); mDataDemoParameter.set("rangeClipmode", "low"); mDataDemoParameter.set("description", "any information relative to the state of the application"); // Register the parameter data into mApplicationDemo at an address args = TTValue("/myParameter", mDataDemoParameter); mApplicationDemo.send("ObjectRegister", args, out); // Create a message data and set its callback function and baton and some attributes mDataDemoMessage = TTObject("Data", "message"); // Setup the callback mechanism to get the value back args = TTValue(TTPtr(this), mDataDemoMessage); mDataDemoMessage.set("baton", args); mDataDemoMessage.set("function", TTPtr(&DemoAppDataReturnValueCallback)); // Setup the data attributes depending of its use inside the application mDataDemoMessage.set("type", "string"); mDataDemoMessage.set("description", "any information to provide to the application"); // Register the message data into mApplicationDemo at an address args = TTValue("/myMessage", mDataDemoMessage); mApplicationDemo.send("ObjectRegister", args, out); // Create a return data and set its callback function and baton and some attributes mDataDemoReturn = TTObject("Data", "return"); // Setup the callback mechanism to get the value back args = TTValue(TTPtr(this), mDataDemoReturn); mDataDemoReturn.set("baton", args); mDataDemoReturn.set("function", TTPtr(&DemoAppDataReturnValueCallback)); // Setup the data attributes depending of its use inside the application mDataDemoReturn.set("type", "integer"); mDataDemoReturn.set("defaultValue", 0); mDataDemoReturn.set("description", "any information the application returns back"); // Register the return data into mApplicationDemo at an address args = TTValue("/myReturn", mDataDemoReturn); mApplicationDemo.send("ObjectRegister", args, out); // Initialise the application and all datas inside (using defaultValue attribute) mApplicationDemo.send("Init"); }
void jamoma_init(void) { short outvol = 0; t_fourcc outtype, filetype = 'TEXT'; char name[MAX_PATH_CHARS], fullname[MAX_PATH_CHARS]; if (!initialized) { t_object *max = SymbolGen("max")->s_thing; TTString JamomaConfigurationFilePath; t_atom a[4]; TTValue v, out; TTErr err; if (maxversion() < 1798) { error("Jamoma %s | build %s can't run under Max version ealier than 7.0.6", JAMOMA_MAX_VERSION, JAMOMA_MAX_REV); return; } // Initialize the Modular library TTModularInit(); #ifdef TTSCORE_IMPORT // Initialize the Score framework TTScoreInit(); #endif // Prepare a symbol for Max application kTTSym_Max = TTSymbol("Max"); // Create an application manager MaxApplicationManager = TTObject("ApplicationManager"); // Create a local application called "Max" and get it back err = MaxApplicationManager.send("ApplicationInstantiateLocal", kTTSym_Max, out); if (err) { TTLogError("Error : can't create Jamoma application \n"); return; } else MaxApplication = out[0]; // check if the JamomaConfiguration.xml file exists strncpy_zero(name, "JamomaConfiguration.xml", MAX_PATH_CHARS); if (locatefile_extended(name, &outvol, &outtype, &filetype, 1)) return error("Jamoma not loaded : can't find %s", name); path_topathname(outvol, name, fullname); // MaxApplication have to read JamomaConfiguration.xml TTObject anXmlHandler(kTTSym_XmlHandler); anXmlHandler.set(kTTSym_object, MaxApplication); std::string path = fullname; #if ( __APPLE__ ) // remove drive name prefix size_t pos = path.find(":/"); path = path.substr(pos+1); v = TTSymbol(path); #else v = TTSymbol(fullname); #endif anXmlHandler.send(kTTSym_Read, v, out); // Initialize common symbols common_symbols_init(); jamomaSymbolsInit(); // Initialize common regex ttRegexForJmod = new TTRegex("(jmod.)"); ttRegexForJcom = new TTRegex("(j\\.)"); ttRegexForModel = new TTRegex("(.model)"); ttRegexForModule = new TTRegex("(.module)"); ttRegexForView = new TTRegex("(.view)"); ttRegexForMaxpat = new TTRegex("(.maxpat)"); ttRegexForMaxhelp = new TTRegex("(.maxhelp)"); ttRegexForBracket = new TTRegex("\\[(\\d|\\d\\d|\\d\\d\\d)\\]"); // parse until 999 ModelPatcherFormat = new TTString("%s.model.maxpat"); ModelPresetFormat = new TTString("%s.model.presets.txt"); ViewPresetFormat = new TTString("%s.view.presets.txt"); HelpPatcherFormat = new TTString("%s.model"); RefpageFormat = new TTString("%s.model"); DocumentationFormat = new TTString("%s.model.html"); // Create Required Global Instances hash_modules = (t_hashtab*)hashtab_new(0); // TODO: Use quittask_install() to set up a destructor for this to free it before Max exits // Add Jamoma Key Commands // J -- Jamoma: a new object box with "j." in it atom_setsym(a+0, SymbolGen("k")); atom_setsym(a+1, SymbolGen("patcher")); atom_setsym(a+2, SymbolGen("inserttextobj")); atom_setsym(a+3, SymbolGen("j.")); object_method_typed(max, SymbolGen("definecommand"), 4, a, NULL); // // M -- Module: a new object box with ".model" in it // atom_setsym(a+0, SymbolGen("M")); // atom_setsym(a+1, SymbolGen("patcher")); // atom_setsym(a+2, SymbolGen("inserttextobj")); // atom_setsym(a+3, SymbolGen(".model")); // object_method_typed(max, SymbolGen("definecommand"), 4, a, NULL); // // // B -- BPatcher: a new module in a bpatcher // object_method_parse(max, SymbolGen("definecommand"), (char*)"B patcher inserttextobj \"bpatcher @name .module @args myModule\"", NULL); // // D -- Demo: a new module in a bpatcher, but with the args reverse which is handy for super-fast demos when you don't care about the OSC name // object_method_parse(max, SymbolGen("definecommand"), (char*)"D patcher inserttextobj \"bpatcher @name .module\"", NULL); // // X -- Continuous Mapper module // object_method_parse(max, SymbolGen("definecommand"), (char*)"X patcher insertobj bpatcher @name mapper.module.maxpat @args mapper", NULL); // now the jamoma object { t_symbol *jamomaSymbol = SymbolGen("jamoma"); jamoma_object_initclass(); jamomaSymbol->s_thing = jamoma_object_new(); } post("Jamoma %s | build %s", JAMOMA_MAX_VERSION, JAMOMA_MAX_REV ); initialized = true; } }
void cue_edit(TTPtr self, t_symbol *msg, long argc, const t_atom *argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTString *buffer; char title[MAX_FILENAME_CHARS]; TTObject aTextHandler; TTHashPtr allCues; TTValue v, o; TTSymbol name = kTTSymEmpty; t_atom a; TTErr tterr; // choose object to edit : default the cuelist *EXTRA->toEdit = x->wrappedObject; EXTRA->cueName = kTTSymEmpty; if (argc && argv) { if (atom_gettype(argv) == A_LONG) { TTUInt32 index = atom_getlong(argv); // get cues names x->wrappedObject.get("names", v); if (index > 0 && index <= v.size()) name = v[index-1]; else { object_error((t_object*)x, "%d doesn't exist", atom_getlong(argv)); return; } } else if (atom_gettype(argv) == A_SYM) name = TTSymbol(atom_getsym(argv)->s_name); if (name != kTTSymEmpty) { // get cue object table x->wrappedObject.get("cues", v); allCues = TTHashPtr((TTPtr)v[0]); if (allCues) { // get cue to edit if (!allCues->lookup(name, v)) { // edit a cue *EXTRA->toEdit = v[0]; EXTRA->cueName = name; } else { object_error((t_object*)x, "%s doesn't exist", atom_getsym(argv)->s_name); return; } } } } // only one editor can be open in the same time if (!EXTRA->textEditor) { EXTRA->textEditor = (t_object*)object_new(_sym_nobox, _sym_jed, x, 0); buffer = new TTString(); // get the buffer handler tterr = x->internals->lookup(kTTSym_TextHandler, o); if (!tterr) { aTextHandler = o[0]; critical_enter(0); aTextHandler.set(kTTSym_object, *EXTRA->toEdit); tterr = aTextHandler.send(kTTSym_Write, (TTPtr)buffer); critical_exit(0); } // pass the buffer to the editor object_method(EXTRA->textEditor, _sym_settext, buffer->c_str(), _sym_utf_8); object_attr_setchar(EXTRA->textEditor, gensym("scratch"), 1); snprintf(title, MAX_FILENAME_CHARS, "cuelist editor"); object_attr_setsym(EXTRA->textEditor, _sym_title, gensym(title)); // output a flag atom_setsym(&a, gensym("opened")); object_obex_dumpout(self, gensym("editor"), 1, &a); buffer->clear(); delete buffer; buffer = NULL; } else { object_attr_setchar(EXTRA->textEditor, gensym("visible"), 1); } }