-/*
-
- 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