Rename interpretor to interpreter.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / architecture / osclib / faust / src / nodes / MessageDriven.cpp
diff --git a/interpreter/preprocessor/faust-0.9.47mr3/architecture/osclib/faust/src/nodes/MessageDriven.cpp b/interpreter/preprocessor/faust-0.9.47mr3/architecture/osclib/faust/src/nodes/MessageDriven.cpp
new file mode 100644 (file)
index 0000000..7f9f21d
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+
+  Copyright (C) 2011 Grame
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
+  research@grame.fr
+
+*/
+
+#include <iostream>
+#include <sstream>
+
+#include "Message.h"
+#include "MessageDriven.h"
+#include "OSCAddress.h"
+#include "OSCFError.h"
+#include "OSCRegexp.h"
+
+using namespace std;
+namespace oscfaust
+{
+
+static const char * kGetMsg = "get";
+
+//--------------------------------------------------------------------------
+void MessageDriven::processMessage( const Message* msg )
+{
+       const string addr = msg->address();
+
+       // create a regular expression
+       OSCRegexp r (OSCAddress::addressFirst(addr).c_str());
+       // and call propose with this regexp and with the dest osc address tail
+       propose (msg, &r, OSCAddress::addressTail (addr));
+       
+       if (addr != "/*") {
+               // search for alias root (fixme : could be stored in a field)
+               MessageDriven * aliasroot = 0;
+               for (int i=0; i<size(); i++) {
+                       if (subnode(i)->name() == "alias") {
+                               aliasroot = subnode(i);
+                       }
+               }
+       
+               // if we have aliases in the tree
+               // we need to check if the message if for an alias address
+               if (aliasroot != 0) {
+                       OSCRegexp r2 ("alias");
+                       
+                       if (msg->size() == 1) {
+                               aliasroot->propose (msg, &r2, addr);
+                       } else if (msg->size() > 1) {
+                               // we simulated several messages
+                               for (int i=0; i< msg->size(); i++) {
+                                       ostringstream   as; as << addr << '/' << i;
+                                       string                  a(as.str());
+                                       Message                 m(a);
+                                       float                   v;
+                                       
+                                       msg->param(i, v);
+                                       m.add(v);
+                                       aliasroot->propose (&m, &r2, a);
+                               }
+                       }
+               }
+       }
+}
+
+//--------------------------------------------------------------------------
+// the full OSC address is simply the prefix + '/' + name
+string MessageDriven::getOSCAddress() const
+{
+       string address(fOSCPrefix);
+       address += "/";
+       address += fName;
+       return address;
+}
+
+//--------------------------------------------------------------------------
+// terminal nodes should override the get method
+void MessageDriven::get (unsigned long ipdest) const
+{
+       // basic get handler propagates the get call to subnodes
+       for (vector<SMessageDriven>::const_iterator i = fSubNodes.begin(); i != fSubNodes.end(); i++)
+               (*i)->get (ipdest);
+}
+
+//--------------------------------------------------------------------------
+bool MessageDriven::accept( const Message* msg )
+{
+       string val;
+       // the basic accept method only checks for the 'get' message
+       if ((msg->size() == 1) && (msg->param(0, val)) && (val == kGetMsg)) {
+               get (msg->src());
+               return true;
+       }
+       return false;
+}
+
+//--------------------------------------------------------------------------
+void MessageDriven::propose( const Message* msg, const OSCRegexp* r, const std::string addrTail)
+{
+       if (r->match(getName())) {                      // try to match the regular expression with the object name. 
+               if (addrTail.empty()) {                 // it matches and the tail is empty
+                       accept(msg);                            // then call accept()
+               }
+               else {                                                  // it matches but the tail is not empty
+                       OSCRegexp rtail (OSCAddress::addressFirst(addrTail).c_str());
+                       for (vector<SMessageDriven>::iterator i = fSubNodes.begin(); i != fSubNodes.end(); i++) {
+                               // then propagate propose() to subnodes with a new regexp and a new tail
+                               (*i)->propose (msg, &rtail, OSCAddress::addressTail(addrTail));
+                       }
+               }
+       }
+}
+
+} // end namespoace