From 7927c3da2eb04f6969af7afc6cfc5a83ade89565 Mon Sep 17 00:00:00 2001 From: florent <florent@laas.fr> Date: Thu, 21 Oct 2010 17:55:44 +0200 Subject: [PATCH] Implement command * include/CMakeLists.txt, * include/dynamic-graph/command.h: new, * include/dynamic-graph/entity.h, * include/dynamic-graph/parameter.h: new, * include/dynamic-graph/value.h: new, * src/command/command.cpp: new, * src/command/value.cpp: new, * src/dgraph/entity.cpp. --- include/CMakeLists.txt | 4 ++ include/dynamic-graph/command.h | 63 +++++++++++++++++++++++ include/dynamic-graph/entity.h | 13 +++++ include/dynamic-graph/parameter.h | 18 +++++++ include/dynamic-graph/value.h | 83 +++++++++++++++++++++++++++++++ src/command/command.cpp | 75 ++++++++++++++++++++++++++++ src/command/value.cpp | 75 ++++++++++++++++++++++++++++ src/dgraph/entity.cpp | 24 +++++++++ 8 files changed, 355 insertions(+) create mode 100644 include/dynamic-graph/command.h create mode 100644 include/dynamic-graph/parameter.h create mode 100644 include/dynamic-graph/value.h create mode 100644 src/command/command.cpp create mode 100644 src/command/value.cpp diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 008cc9f..0ac0e40 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -65,6 +65,10 @@ all-signals.h tracer.h tracer-real-time.h + +command.h +value.h +parameter.h ) # Recreate correct path for the headers diff --git a/include/dynamic-graph/command.h b/include/dynamic-graph/command.h new file mode 100644 index 0000000..3f0d02f --- /dev/null +++ b/include/dynamic-graph/command.h @@ -0,0 +1,63 @@ +// +// Copyright 2010 CNRS +// +// Author: Florent Lamiraux +// +// This file is part of dynamic-graph. +// dynamic-graph 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 3 of +// the License, or (at your option) any later version. +// dynamic-graph 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 dynamic-graph. If not, see <http://www.gnu.org/licenses/>. + +#ifndef DYNAMIC_GRAPH_COMMAND_H +#define DYNAMIC_GRAPH_COMMAND_H + +#include <vector> +#include "dynamic-graph/value.h" +#include "dynamic-graph/dynamic-graph-api.h" + +namespace dynamicgraph { + class Entity; + namespace command { + /// Abstract class for entity commands + /// + /// This class provide a mean to control entities from external python script. + /// A command has several parameters (dynamicgraph::parameter) that can take + /// various types of values (dynamicgraph::Value). + + class DYNAMICGRAPH_EXPORT Command + { + public: + virtual ~Command(); + /// Store the owner entity and a vector of value types + /// \param entity reference to Entity owning this command. + /// \param valueTypes vector specifying the number and types of parameters + Command(Entity& entity, const std::vector<Value::Type>& valueTypes); + /// Return the value type of all parameters + const std::vector<Value::Type>& valueTypes() const; + /// Set parameter values + void setParameterValues(const std::vector<Value>& values); + /// Get parameter values + const std::vector<Value> getParameterValues(); + /// Execute the command after checking parameters + Value execute(); + /// Get a reference to the Entity owning this command + Entity& owner(); + protected: + /// Specific action performed by the command + virtual Value doExecute() = 0; + private: + Entity& owner_; + std::vector<Value::Type> valueTypeVector_; + std::vector<Value> valueVector_; + }; + } // namespace command +} // namespace dynamicgraph + +#endif //DYNAMIC_GRAPH_COMMAND_H diff --git a/include/dynamic-graph/entity.h b/include/dynamic-graph/entity.h index 2a215e0..c1c5f4d 100644 --- a/include/dynamic-graph/entity.h +++ b/include/dynamic-graph/entity.h @@ -41,6 +41,10 @@ /* NAMESPACE */ namespace dynamicgraph { + // Forward declaration + namespace command { + class Command; + }; /* --------------------------------------------------------------------- */ /* --- CLASS ----------------------------------------------------------- */ @@ -97,6 +101,15 @@ class DYNAMIC_GRAPH_DLLAPI Entity virtual void test2( SignalBase<int>* ) { return ; } virtual const std::string& getCommandList( void ) const; + /// Return the list of command objects + virtual std::map<const std::string, command::Command*> + getNewStyleCommandMap(); + protected: + /// Add a command to Entity + virtual void addCommand(const std::string& name, + command::Command* command); + private: + std::map<const std::string, command::Command*> commandMap; }; DYNAMIC_GRAPH_DLLAPI std::ostream& operator<< (std::ostream& os, const dynamicgraph::Entity& ent ); diff --git a/include/dynamic-graph/parameter.h b/include/dynamic-graph/parameter.h new file mode 100644 index 0000000..719aa08 --- /dev/null +++ b/include/dynamic-graph/parameter.h @@ -0,0 +1,18 @@ +#ifndef DYNAMIC_GRAPH_PARAMETER_H +#define DYNAMIC_GRAPH_PARAMETER_H + +#include <boost/static_assert.hpp> +#include "dynamicgraph/exception-abstract.h" + +namespace dynamicgraph { + namespace command { + class Parameter { + public: + Parameter(Value::Type valueType) : valueType_(valueType) {} + /// Return value type of parameter + Value::Type valueType() { return valueType_;} + private: + Value::Type valueType_; + }; // class Parameter + } // namespace command +} //namespace dynamicgraph diff --git a/include/dynamic-graph/value.h b/include/dynamic-graph/value.h new file mode 100644 index 0000000..6e151de --- /dev/null +++ b/include/dynamic-graph/value.h @@ -0,0 +1,83 @@ +// +// Copyright 2010 CNRS +// +// Author: Florent Lamiraux +// +// This file is part of dynamic-graph. +// dynamic-graph 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 3 of +// the License, or (at your option) any later version. +// dynamic-graph 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 dynamic-graph. If not, see <http://www.gnu.org/licenses/>. + +#ifndef DYNAMIC_GRAPH_VALUE_H +#define DYNAMIC_GRAPH_VALUE_H + +#include <iostream> +#include <string> +#include <cassert> +#include <typeinfo> +#include "dynamic-graph/dynamic-graph-api.h" + +namespace dynamicgraph { + namespace command { + class DYNAMICGRAPH_EXPORT Value { + public: + enum Type { + NONE, + INT, + DOUBLE, + STRING, + NB_TYPES + }; + /// template constructor + template <class T> Value(const T& value); + /// Copy constructor + Value(const Value& value); + // Construct an empty value (None) + Value(); + /// Return the type of the value + Type type() const; + + /// Return the value if it is a double and throw otherwise + const double& doubleValue () const; + /// Return the value if it is a int and throw otherwise + const int& intValue () const; + /// Return the value if it is a string and throw otherwise + const std::string& stringValue () const; + /// Return the name of the type + static std::string typeName(Type type); + private: + Type type_; + const void* value_; + }; + + // Template constructors + template <> Value::Value(const int& value) + { + value_ = &value; + type_ = INT; + } + template <> Value::Value(const double& value) + { + value_ = &value; + type_ = DOUBLE; + } + template <> Value::Value(const std::string& value) + { + value_ = &value; + type_ = STRING; + } + template <class T> Value::Value(const T& value) + { + assert(false); + } + } // namespace command +} //namespace dynamicgraph + +#endif //DYNAMIC_GRAPH_VALUE_H diff --git a/src/command/command.cpp b/src/command/command.cpp new file mode 100644 index 0000000..e0c1745 --- /dev/null +++ b/src/command/command.cpp @@ -0,0 +1,75 @@ +// +// Copyright 2010 CNRS +// +// Author: Florent Lamiraux +// +// This file is part of dynamic-graph. +// dynamic-graph 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 3 of +// the License, or (at your option) any later version. +// dynamic-graph 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 dynamic-graph. If not, see <http://www.gnu.org/licenses/>. + +#include <sstream> +#include "dynamic-graph/command.h" +#include "dynamic-graph/exception-abstract.h" + +namespace dynamicgraph { + namespace command { + + Command::~Command() {} + Command::Command(Entity& entity, + const std::vector<Value::Type>& valueTypes) : + owner_(entity), valueTypeVector_(valueTypes) + { + } + + const std::vector<Value::Type>& Command::valueTypes() const + { + return valueTypeVector_; + } + + void Command::setParameterValues(const std::vector<Value>& values) + { + unsigned int size = values.size(); + const std::vector<Value::Type>& paramTypes = valueTypes(); + // Check that number of parameters is correct + if (values.size() != paramTypes.size()) { + throw ExceptionAbstract(ExceptionAbstract::ABSTRACT, + "wrong number of parameters"); + } + // Check that each parameter is of correct type + for (unsigned int iParam=0; iParam < values.size(); iParam++) { + if (values[iParam].type() != paramTypes[iParam]) { + std::stringstream ss; + ss << "argument " << iParam << "is of wrong type: " + << Value::typeName(paramTypes[iParam]) << " expected, got " + << Value::typeName(values[iParam].type()); + throw ExceptionAbstract(ExceptionAbstract::TOOLS, ss.str()); + } + } + // Copy vector of values in private part + valueVector_ = values; + } + + const std::vector<Value> Command::getParameterValues() + { + return valueVector_; + } + + Value Command::execute() + { + return doExecute(); + } + + Entity& Command::owner() + { + return owner_; + } + } // namespace command +} //namespace dynamicgraph diff --git a/src/command/value.cpp b/src/command/value.cpp new file mode 100644 index 0000000..06fd51d --- /dev/null +++ b/src/command/value.cpp @@ -0,0 +1,75 @@ +// +// Copyright 2010 CNRS +// +// Author: Florent Lamiraux +// +// This file is part of dynamic-graph. +// dynamic-graph 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 3 of +// the License, or (at your option) any later version. +// dynamic-graph 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 dynamic-graph. If not, see <http://www.gnu.org/licenses/>. + +#include "dynamic-graph/value.h" +#include "dynamic-graph/exception-abstract.h" + +namespace dynamicgraph { + namespace command { + + Value::Value(const Value& value) : type_(value.type_), + value_(value.value_) + { + } + + Value::Value() : type_(NONE), value_(NULL) + { + } + + Value::Type Value::type() const + { + return type_; + } + + const double& Value::doubleValue () const + { + if (type_ == DOUBLE) + return *(static_cast<const double*>(value_)); + throw ExceptionAbstract(ExceptionAbstract::TOOLS, + "value is not a double"); + } + + const int& Value::intValue () const + { + if (type_ == INT) + return *(static_cast<const int*>(value_)); + throw ExceptionAbstract(ExceptionAbstract::TOOLS, + "value is not an int"); + } + + const std::string& Value::stringValue () const + { + if (type_ == STRING) + return *(static_cast<const std::string*>(value_)); + throw ExceptionAbstract(ExceptionAbstract::TOOLS, + "value is not an string"); + } + + std::string Value::typeName(Type type) + { + switch (type) { + case INT: + return std::string("int"); + case DOUBLE: + return std::string("double"); + case STRING: + return std::string("string"); + } + return std::string("unknown"); + } + } // namespace command +} //namespace dynamicgraph diff --git a/src/dgraph/entity.cpp b/src/dgraph/entity.cpp index 02764fa..b71fdc6 100644 --- a/src/dgraph/entity.cpp +++ b/src/dgraph/entity.cpp @@ -23,6 +23,7 @@ #include <dynamic-graph/pool.h> #include <dynamic-graph/pool.h> #include <dynamic-graph/debug.h> +#include <dynamic-graph/command.h> /*! System includes */ #include <stdlib.h> @@ -31,6 +32,7 @@ using namespace std; using namespace dynamicgraph; +using dynamicgraph::command::Command; const std::string Entity::CLASS_NAME = "Entity"; @@ -70,6 +72,10 @@ Entity:: { dgDEBUG(25) << "# In (" << name << " { " << endl; entityDeregistration(); + for (std::map<const std::string, Command*>::iterator it = + commandMap.begin(); it != commandMap.end(); it++) { + delete it->second; + } dgDEBUGOUT(25); } @@ -267,3 +273,21 @@ commandLine( const std::string& cmdLine,std::istringstream& cmdArgs,std::ostream } } + +void Entity:: +addCommand(const std::string& inName, Command* command) +{ + if (commandMap.count(inName) != 0) { + DG_THROW ExceptionFactory(ExceptionFactory::OBJECT_CONFLICT, + "Command " + inName + + " already registered in Entity."); + } + std::pair<const std::string, Command*> item(inName, command); + commandMap.insert(item); +} + +std::map<const std::string, Command*> Entity:: +getNewStyleCommandMap() +{ + return commandMap; +} -- GitLab