--- /dev/null
+/*
+
+ 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
+
+*/
+
+
+#ifndef __Message__
+#define __Message__
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include "smartpointer.h"
+
+namespace oscfaust
+{
+
+class OSCStream;
+template <typename T> class MsgParam;
+class baseparam;
+typedef SMARTP<baseparam> Sbaseparam;
+
+//--------------------------------------------------------------------------
+/*!
+ \brief base class of a message parameters
+*/
+class baseparam : public smartable
+{
+ public:
+ virtual ~baseparam() {}
+
+ /*!
+ \brief utility for parameter type checking
+ */
+ template<typename X> bool isType() const { return dynamic_cast<const MsgParam<X>*> (this) != 0; }
+ /*!
+ \brief utility for parameter convertion
+ \param errvalue the returned value when no conversion applies
+ \return the parameter value when the type matches
+ */
+ template<typename X> X value(X errvalue) const
+ { const MsgParam<X>* o = dynamic_cast<const MsgParam<X>*> (this); return o ? o->getValue() : errvalue; }
+ /*!
+ \brief utility for parameter comparison
+ */
+ template<typename X> bool equal(const baseparam& p) const
+ {
+ const MsgParam<X>* a = dynamic_cast<const MsgParam<X>*> (this);
+ const MsgParam<X>* b = dynamic_cast<const MsgParam<X>*> (&p);
+ return a && b && (a->getValue() == b->getValue());
+ }
+ /*!
+ \brief utility for parameter comparison
+ */
+ bool operator==(const baseparam& p) const
+ {
+ return equal<float>(p) || equal<int>(p) || equal<std::string>(p);
+ }
+ bool operator!=(const baseparam& p) const
+ {
+ return !equal<float>(p) && !equal<int>(p) && !equal<std::string>(p);
+ }
+
+ virtual SMARTP<baseparam> copy() const = 0;
+};
+
+//--------------------------------------------------------------------------
+/*!
+ \brief template for a message parameter
+*/
+template <typename T> class MsgParam : public baseparam
+{
+ T fParam;
+ public:
+ MsgParam(T val) : fParam(val) {}
+ virtual ~MsgParam() {}
+
+ T getValue() const { return fParam; }
+
+ virtual SMARTP<baseparam> copy() const { return new MsgParam<T>(fParam); }
+};
+
+//--------------------------------------------------------------------------
+/*!
+ \brief a message description
+
+ A message is composed of an address (actually an OSC address),
+ a message string that may be viewed as a method name
+ and a list of message parameters.
+*/
+class Message
+{
+ public:
+ typedef SMARTP<baseparam> argPtr; ///< a message argument ptr type
+ typedef std::vector<argPtr> argslist; ///< args list type
+
+ private:
+ unsigned long fSrcIP; ///< the message source IP number
+ std::string fAddress; ///< the message osc destination address
+ argslist fArguments; ///< the message arguments
+
+ public:
+ /*!
+ \brief an empty message constructor
+ */
+ Message() {}
+ /*!
+ \brief a message constructor
+ \param address the message destination address
+ */
+ Message(const std::string& address) : fAddress(address) {}
+ /*!
+ \brief a message constructor
+ \param address the message destination address
+ \param args the message parameters
+ */
+ Message(const std::string& address, const argslist& args)
+ : fAddress(address), fArguments(args) {}
+ /*!
+ \brief a message constructor
+ \param msg a message
+ */
+ Message(const Message& msg);
+ virtual ~Message() {} //{ freed++; std::cout << "running messages: " << (allocated - freed) << std::endl; }
+
+ /*!
+ \brief adds a parameter to the message
+ \param val the parameter
+ */
+ template <typename T> void add(T val) { fArguments.push_back(new MsgParam<T>(val)); }
+ /*!
+ \brief adds a float parameter to the message
+ \param val the parameter value
+ */
+ void add(float val) { add<float>(val); }
+ /*!
+ \brief adds an int parameter to the message
+ \param val the parameter value
+ */
+ void add(int val) { add<int>(val); }
+ /*!
+ \brief adds a string parameter to the message
+ \param val the parameter value
+ */
+ void add(const std::string& val) { add<std::string>(val); }
+
+ /*!
+ \brief adds a parameter to the message
+ \param val the parameter
+ */
+ void add( argPtr val ) { fArguments.push_back( val ); }
+
+ /*!
+ \brief sets the message address
+ \param addr the address
+ */
+ void setSrcIP(unsigned long addr) { fSrcIP = addr; }
+
+ /*!
+ \brief sets the message address
+ \param addr the address
+ */
+ void setAddress(const std::string& addr) { fAddress = addr; }
+ /*!
+ \brief print the message
+ \param out the output stream
+ */
+ void print(std::ostream& out) const;
+ /*!
+ \brief send the message to OSC
+ \param out the OSC output stream
+ */
+ void print(OSCStream& out) const;
+ /*!
+ \brief print message arguments
+ \param out the OSC output stream
+ */
+ void printArgs(OSCStream& out) const;
+
+ /// \brief gives the message address
+ const std::string& address() const { return fAddress; }
+ /// \brief gives the message parameters list
+ const argslist& params() const { return fArguments; }
+ /// \brief gives the message parameters list
+ argslist& params() { return fArguments; }
+ /// \brief gives the message source IP
+ unsigned long src() const { return fSrcIP; }
+ /// \brief gives the message parameters count
+ int size() const { return fArguments.size(); }
+
+ bool operator == (const Message& other) const;
+
+
+ /*!
+ \brief gives a message float parameter
+ \param i the parameter index (0 <= i < size())
+ \param val on output: the parameter value when the parameter type matches
+ \return false when types don't match
+ */
+ bool param(int i, float& val) const { val = params()[i]->value<float>(val); return params()[i]->isType<float>(); }
+ /*!
+ \brief gives a message int parameter
+ \param i the parameter index (0 <= i < size())
+ \param val on output: the parameter value when the parameter type matches
+ \return false when types don't match
+ */
+ bool param(int i, int& val) const { val = params()[i]->value<int>(val); return params()[i]->isType<int>(); }
+ /*!
+ \brief gives a message int parameter
+ \param i the parameter index (0 <= i < size())
+ \param val on output: the parameter value when the parameter type matches
+ \return false when types don't match
+ */
+ bool param(int i, unsigned int& val) const { val = params()[i]->value<int>(val); return params()[i]->isType<int>(); }
+ /*!
+ \brief gives a message int parameter
+ \param i the parameter index (0 <= i < size())
+ \param val on output: the parameter value when the parameter type matches
+ \return false when types don't match
+ \note a boolean value is handled as integer
+ */
+ bool param(int i, bool& val) const { int ival = 0; ival = params()[i]->value<int>(ival); val = ival!=0; return params()[i]->isType<int>(); }
+ /*!
+ \brief gives a message int parameter
+ \param i the parameter index (0 <= i < size())
+ \param val on output: the parameter value when the parameter type matches
+ \return false when types don't match
+ */
+ bool param(int i, long int& val) const { val = long(params()[i]->value<int>(val)); return params()[i]->isType<int>(); }
+ /*!
+ \brief gives a message string parameter
+ \param i the parameter index (0 <= i < size())
+ \param val on output: the parameter value when the parameter type matches
+ \return false when types don't match
+ */
+ bool param(int i, std::string& val) const { val = params()[i]->value<std::string>(val); return params()[i]->isType<std::string>(); }
+};
+
+
+} // end namespoace
+
+#endif