Merge branch 'OOP' of https://scm.cri.ensmp.fr/git/Faustine into OOP
[Faustine.git] / interpretor / faust-0.9.47mr3 / architecture / osclib / faust / src / msg / Message.h
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
25 #ifndef __Message__
26 #define __Message__
27
28 #include <string>
29 #include <vector>
30 #include <iostream>
31 #include "smartpointer.h"
32
33 namespace oscfaust
34 {
35
36 class OSCStream;
37 template <typename T> class MsgParam;
38 class baseparam;
39 typedef SMARTP<baseparam> Sbaseparam;
40
41 //--------------------------------------------------------------------------
42 /*!
43 \brief base class of a message parameters
44 */
45 class baseparam : public smartable
46 {
47 public:
48 virtual ~baseparam() {}
49
50 /*!
51 \brief utility for parameter type checking
52 */
53 template<typename X> bool isType() const { return dynamic_cast<const MsgParam<X>*> (this) != 0; }
54 /*!
55 \brief utility for parameter convertion
56 \param errvalue the returned value when no conversion applies
57 \return the parameter value when the type matches
58 */
59 template<typename X> X value(X errvalue) const
60 { const MsgParam<X>* o = dynamic_cast<const MsgParam<X>*> (this); return o ? o->getValue() : errvalue; }
61 /*!
62 \brief utility for parameter comparison
63 */
64 template<typename X> bool equal(const baseparam& p) const
65 {
66 const MsgParam<X>* a = dynamic_cast<const MsgParam<X>*> (this);
67 const MsgParam<X>* b = dynamic_cast<const MsgParam<X>*> (&p);
68 return a && b && (a->getValue() == b->getValue());
69 }
70 /*!
71 \brief utility for parameter comparison
72 */
73 bool operator==(const baseparam& p) const
74 {
75 return equal<float>(p) || equal<int>(p) || equal<std::string>(p);
76 }
77 bool operator!=(const baseparam& p) const
78 {
79 return !equal<float>(p) && !equal<int>(p) && !equal<std::string>(p);
80 }
81
82 virtual SMARTP<baseparam> copy() const = 0;
83 };
84
85 //--------------------------------------------------------------------------
86 /*!
87 \brief template for a message parameter
88 */
89 template <typename T> class MsgParam : public baseparam
90 {
91 T fParam;
92 public:
93 MsgParam(T val) : fParam(val) {}
94 virtual ~MsgParam() {}
95
96 T getValue() const { return fParam; }
97
98 virtual SMARTP<baseparam> copy() const { return new MsgParam<T>(fParam); }
99 };
100
101 //--------------------------------------------------------------------------
102 /*!
103 \brief a message description
104
105 A message is composed of an address (actually an OSC address),
106 a message string that may be viewed as a method name
107 and a list of message parameters.
108 */
109 class Message
110 {
111 public:
112 typedef SMARTP<baseparam> argPtr; ///< a message argument ptr type
113 typedef std::vector<argPtr> argslist; ///< args list type
114
115 private:
116 unsigned long fSrcIP; ///< the message source IP number
117 std::string fAddress; ///< the message osc destination address
118 argslist fArguments; ///< the message arguments
119
120 public:
121 /*!
122 \brief an empty message constructor
123 */
124 Message() {}
125 /*!
126 \brief a message constructor
127 \param address the message destination address
128 */
129 Message(const std::string& address) : fAddress(address) {}
130 /*!
131 \brief a message constructor
132 \param address the message destination address
133 \param args the message parameters
134 */
135 Message(const std::string& address, const argslist& args)
136 : fAddress(address), fArguments(args) {}
137 /*!
138 \brief a message constructor
139 \param msg a message
140 */
141 Message(const Message& msg);
142 virtual ~Message() {} //{ freed++; std::cout << "running messages: " << (allocated - freed) << std::endl; }
143
144 /*!
145 \brief adds a parameter to the message
146 \param val the parameter
147 */
148 template <typename T> void add(T val) { fArguments.push_back(new MsgParam<T>(val)); }
149 /*!
150 \brief adds a float parameter to the message
151 \param val the parameter value
152 */
153 void add(float val) { add<float>(val); }
154 /*!
155 \brief adds an int parameter to the message
156 \param val the parameter value
157 */
158 void add(int val) { add<int>(val); }
159 /*!
160 \brief adds a string parameter to the message
161 \param val the parameter value
162 */
163 void add(const std::string& val) { add<std::string>(val); }
164
165 /*!
166 \brief adds a parameter to the message
167 \param val the parameter
168 */
169 void add( argPtr val ) { fArguments.push_back( val ); }
170
171 /*!
172 \brief sets the message address
173 \param addr the address
174 */
175 void setSrcIP(unsigned long addr) { fSrcIP = addr; }
176
177 /*!
178 \brief sets the message address
179 \param addr the address
180 */
181 void setAddress(const std::string& addr) { fAddress = addr; }
182 /*!
183 \brief print the message
184 \param out the output stream
185 */
186 void print(std::ostream& out) const;
187 /*!
188 \brief send the message to OSC
189 \param out the OSC output stream
190 */
191 void print(OSCStream& out) const;
192 /*!
193 \brief print message arguments
194 \param out the OSC output stream
195 */
196 void printArgs(OSCStream& out) const;
197
198 /// \brief gives the message address
199 const std::string& address() const { return fAddress; }
200 /// \brief gives the message parameters list
201 const argslist& params() const { return fArguments; }
202 /// \brief gives the message parameters list
203 argslist& params() { return fArguments; }
204 /// \brief gives the message source IP
205 unsigned long src() const { return fSrcIP; }
206 /// \brief gives the message parameters count
207 int size() const { return fArguments.size(); }
208
209 bool operator == (const Message& other) const;
210
211
212 /*!
213 \brief gives a message float parameter
214 \param i the parameter index (0 <= i < size())
215 \param val on output: the parameter value when the parameter type matches
216 \return false when types don't match
217 */
218 bool param(int i, float& val) const { val = params()[i]->value<float>(val); return params()[i]->isType<float>(); }
219 /*!
220 \brief gives a message int parameter
221 \param i the parameter index (0 <= i < size())
222 \param val on output: the parameter value when the parameter type matches
223 \return false when types don't match
224 */
225 bool param(int i, int& val) const { val = params()[i]->value<int>(val); return params()[i]->isType<int>(); }
226 /*!
227 \brief gives a message int parameter
228 \param i the parameter index (0 <= i < size())
229 \param val on output: the parameter value when the parameter type matches
230 \return false when types don't match
231 */
232 bool param(int i, unsigned int& val) const { val = params()[i]->value<int>(val); return params()[i]->isType<int>(); }
233 /*!
234 \brief gives a message int parameter
235 \param i the parameter index (0 <= i < size())
236 \param val on output: the parameter value when the parameter type matches
237 \return false when types don't match
238 \note a boolean value is handled as integer
239 */
240 bool param(int i, bool& val) const { int ival = 0; ival = params()[i]->value<int>(ival); val = ival!=0; return params()[i]->isType<int>(); }
241 /*!
242 \brief gives a message int parameter
243 \param i the parameter index (0 <= i < size())
244 \param val on output: the parameter value when the parameter type matches
245 \return false when types don't match
246 */
247 bool param(int i, long int& val) const { val = long(params()[i]->value<int>(val)); return params()[i]->isType<int>(); }
248 /*!
249 \brief gives a message string parameter
250 \param i the parameter index (0 <= i < size())
251 \param val on output: the parameter value when the parameter type matches
252 \return false when types don't match
253 */
254 bool param(int i, std::string& val) const { val = params()[i]->value<std::string>(val); return params()[i]->isType<std::string>(); }
255 };
256
257
258 } // end namespoace
259
260 #endif