Merge branch 'master' of https://scm.cri.ensmp.fr/git/Faustine
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / architecture / osclib / faust / src / nodes / MessageDriven.cpp
1 /*
2
3 Copyright (C) 2011 Grame
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
20 research@grame.fr
21
22 */
23
24 #include <iostream>
25 #include <sstream>
26
27 #include "Message.h"
28 #include "MessageDriven.h"
29 #include "OSCAddress.h"
30 #include "OSCFError.h"
31 #include "OSCRegexp.h"
32
33 using namespace std;
34 namespace oscfaust
35 {
36
37 static const char * kGetMsg = "get";
38
39 //--------------------------------------------------------------------------
40 void MessageDriven::processMessage( const Message* msg )
41 {
42 const string addr = msg->address();
43
44 // create a regular expression
45 OSCRegexp r (OSCAddress::addressFirst(addr).c_str());
46 // and call propose with this regexp and with the dest osc address tail
47 propose (msg, &r, OSCAddress::addressTail (addr));
48
49 if (addr != "/*") {
50 // search for alias root (fixme : could be stored in a field)
51 MessageDriven * aliasroot = 0;
52 for (int i=0; i<size(); i++) {
53 if (subnode(i)->name() == "alias") {
54 aliasroot = subnode(i);
55 }
56 }
57
58 // if we have aliases in the tree
59 // we need to check if the message if for an alias address
60 if (aliasroot != 0) {
61 OSCRegexp r2 ("alias");
62
63 if (msg->size() == 1) {
64 aliasroot->propose (msg, &r2, addr);
65 } else if (msg->size() > 1) {
66 // we simulated several messages
67 for (int i=0; i< msg->size(); i++) {
68 ostringstream as; as << addr << '/' << i;
69 string a(as.str());
70 Message m(a);
71 float v;
72
73 msg->param(i, v);
74 m.add(v);
75 aliasroot->propose (&m, &r2, a);
76 }
77 }
78 }
79 }
80 }
81
82 //--------------------------------------------------------------------------
83 // the full OSC address is simply the prefix + '/' + name
84 string MessageDriven::getOSCAddress() const
85 {
86 string address(fOSCPrefix);
87 address += "/";
88 address += fName;
89 return address;
90 }
91
92 //--------------------------------------------------------------------------
93 // terminal nodes should override the get method
94 void MessageDriven::get (unsigned long ipdest) const
95 {
96 // basic get handler propagates the get call to subnodes
97 for (vector<SMessageDriven>::const_iterator i = fSubNodes.begin(); i != fSubNodes.end(); i++)
98 (*i)->get (ipdest);
99 }
100
101 //--------------------------------------------------------------------------
102 bool MessageDriven::accept( const Message* msg )
103 {
104 string val;
105 // the basic accept method only checks for the 'get' message
106 if ((msg->size() == 1) && (msg->param(0, val)) && (val == kGetMsg)) {
107 get (msg->src());
108 return true;
109 }
110 return false;
111 }
112
113 //--------------------------------------------------------------------------
114 void MessageDriven::propose( const Message* msg, const OSCRegexp* r, const std::string addrTail)
115 {
116 if (r->match(getName())) { // try to match the regular expression with the object name.
117 if (addrTail.empty()) { // it matches and the tail is empty
118 accept(msg); // then call accept()
119 }
120 else { // it matches but the tail is not empty
121 OSCRegexp rtail (OSCAddress::addressFirst(addrTail).c_str());
122 for (vector<SMessageDriven>::iterator i = fSubNodes.begin(); i != fSubNodes.end(); i++) {
123 // then propagate propose() to subnodes with a new regexp and a new tail
124 (*i)->propose (msg, &rtail, OSCAddress::addressTail(addrTail));
125 }
126 }
127 }
128 }
129
130 } // end namespoace