// Demonstration Script for companion patches illustrating how to communicate between two instances of "the same" // javascript object where each instance exists in its own top level patcher (or one sub patcher down in a bPatcher, // for example, of a top level patcher) // Console postings are very verbose by default for demonstration, comment out the informational posts for actual // patching use inlets = 1; outlets = 1; var mySpecialName; var myVarname; var maxObjA; var maxObjB; function initA() { maxObjA = this.box; mySpecialName = "A"; myVarname = "patcherAjs"; maxObjA.varname = myVarname; if (!maxObjB) { // the js object (this.box) in patcher B only exists after patcher B opens and initB() runs findMaxObjB(); } } function findMaxObjB() { var foundObj = getMaxobjReference("patcherBjs", mySpecialName); if (foundObj && foundObj.valid) { maxObjB = foundObj; } } findMaxObjB.local = 1; function initB() { maxObjB = this.box; mySpecialName = "B"; myVarname = "patcherBjs"; maxObjB.varname = myVarname; if (!maxObjA) { // the js object (this.box) in patcher A only exists after patcher A opens and initA() runs findMaxObjA(); } } function findMaxObjA() { var foundObj = getMaxobjReference("patcherAjs", mySpecialName); if (foundObj && foundObj.valid) { maxObjA = foundObj; } } findMaxObjA.local = 1; function fromA(msg) { if (mySpecialName === "B" && !(maxObjA && maxObjA.valid)) { // since A is calling, and "return" callout reference not valid, update callout reference findMaxObjA(); } outlet(0, msg); } fromA.local = 1; function fromB(msg) { if (mySpecialName === "A" && !(maxObjB && maxObjB.valid)) { findMaxObjB();// since B is calling... } outlet(0, msg); } fromB.local = 1; function reportOut(msg) { var caller = this.box === maxObjA ? "maxObjA" : "maxObjB"; var callee = caller === "maxObjA" ? "maxObjB" : "maxObjA"; post("reportOut:", msg); post(); if (this.box === maxObjA) { if (!(maxObjB && maxObjB.valid)) { post("reportOut:", caller, "reference to callee", callee, "not valid, retrying"); post(); findMaxObjB();// since callout reference not valid, try updating } var fnA = "fromA"; if (maxObjB && maxObjB.valid) { maxObjB.js[fnA](msg); post("reportOut: *msg sent!"); post(); } else { post("reportOut:", caller, "function connection issue", fnA, "call cannot be completed to", callee); post(); } } else if (this.box === maxObjB) { if (!(maxObjA && maxObjA.valid)) { post("reportOut:", caller, "reference to callee", callee, "not valid, retrying"); post(); findMaxObjA(); } var fnB = "fromB"; if (maxObjA && maxObjA.valid) { maxObjA.js[fnB](msg); post("reportOut: *msg sent!"); post(); } else { post("reportOut:", caller, "function connection issue", fnB, "call cannot be completed to", callee); post(); } } else { post("reportOut:", caller, "js assumption issue", callee); post(); } } function getMaxobjReference(scriptingName, caller) { var topPatcher = max.frontpatcher; var topPatcherCount = 1; var rtn; var keepLooking = true; var m = ["getMaxobjReference:", caller, "looking for maxobj with scriptingName", scriptingName, "at max.time", max.time].join(" "); post(m);post(); while (topPatcher && keepLooking) { m = ["getMaxobjReference:", caller, "top patcher", topPatcherCount, "at filepath", topPatcher.filepath, "contains", topPatcher.count, "maxobj objects"].join(" "); post(m);post(); var maxObj = topPatcher.getnamed(scriptingName); if (maxObj) { rtn = maxObj;// "this" js Maxobj with scripting name "patcherAjs" for example m = ["getMaxobjReference:", caller, "maxobj with scriptingName", scriptingName, "found by getnamed in top-patcher", topPatcherCount].join(" "); post(m);post(); break; } else { maxObj = topPatcher.firstobject; var maxObjCount = 1; while (maxObj) { m = ["getMaxobjReference:", caller, "max object", maxObjCount, "in patcher has varname", maxObj.varname ? maxObj.varname : "undefined", "and name", maxObj.name ? maxObj.name : "undefined"].join(" "); post(m);post(); var bPatcher = maxObj.subpatcher(); if (bPatcher) { m = ["getMaxobjReference:", caller, "sub patcher name", bPatcher.name ? bPatcher.name : "undefined", "and varname", bPatcher.varname ? bPatcher.varname : "undefined", "of top patcher", topPatcherCount].join(" "); post(m); post(); var bMaxObj = bPatcher.getnamed(scriptingName); if (bMaxObj) { rtn = bMaxObj; m = ["getMaxobjReference:", caller, "maxobj with scriptingName", scriptingName, "found by getnamed in sub-patcher found at maxobjCount", maxObjCount].join(" "); post(m);post(); keepLooking = false;// break outer loop too (necessary?) break; } } else { // redundant check here, if a valid reference exists, the topPatcher.getnamed(scriptingName) // call above should have already found this object reference by scriptingName (before iterating // over all patcher maxobjects individually) if (maxObj.varname === scriptingName && maxObj.valid) { rtn = maxObj;// "this" js Maxobj with scripting name "patcherBjs" for example m = ["getMaxobjReference:", caller, "maxobj with scriptingName", scriptingName, "found by iterating objects? in top-patcher at maxobjCount", maxObjCount].join(" "); post(m);post(); keepLooking = false; break; } } maxObj = maxObj.nextobject; maxObjCount++; } } var patcherWind = topPatcher.wind; var nextWindow = patcherWind.next; topPatcher = nextWindow ? nextWindow.assoc : undefined; topPatcherCount++; } return rtn; } getMaxobjReference.local = 1;