diff options
-rw-r--r-- | include/gras/block.hpp | 98 | ||||
-rw-r--r-- | include/gras/detail/block.hpp | 91 | ||||
-rw-r--r-- | include/gras/detail/callable.hpp | 2 | ||||
-rw-r--r-- | include/gras/element.hpp | 3 | ||||
-rw-r--r-- | lib/block_props.cpp | 68 | ||||
-rw-r--r-- | lib/gras_impl/block_actor.hpp | 4 | ||||
-rw-r--r-- | lib/gras_impl/block_data.hpp | 10 | ||||
-rw-r--r-- | lib/gras_impl/messages.hpp | 8 | ||||
-rw-r--r-- | lib/register_messages.cpp | 2 | ||||
-rw-r--r-- | lib/top_block_query.cpp | 4 | ||||
-rw-r--r-- | tests/block_props_test.cpp | 27 |
11 files changed, 40 insertions, 277 deletions
diff --git a/include/gras/block.hpp b/include/gras/block.hpp index f2f1b2b..644a73c 100644 --- a/include/gras/block.hpp +++ b/include/gras/block.hpp @@ -162,97 +162,6 @@ struct GRAS_API Block : Element void post_input_msg(const size_t which_input, const ValueType &value); /******************************************************************* - * The property interface: - * Provides polymorphic, thread-safe access to block properties. - ******************************************************************/ - - /*! - * Register property getter method into the property interface. - * Call register_getter() from the contructor of the block. - * - * Example register usage: - * this->register_getter("foo", &MyBlock::get_foo); - * - * Example method declaration: - * int get_foo(void); - * - * \param key the string to identify this property - * \param get the class method to get the property - */ - template <typename ClassType, typename ValueType> - void register_getter( - const std::string &key, - ValueType(ClassType::*get)(void) - ); - - /*! - * Register property setter method into the property interface. - * Call register_setter() from the contructor of the block. - * - * Example register usage: - * this->register_setter("foo", &MyBlock::set_foo); - * - * Example method declaration: - * void set_foo(const int &new_foo); - * - * \param key the string to identify this property - * \param set the class method to set the property - */ - template <typename ClassType, typename ValueType> - void register_setter( - const std::string &key, - void(ClassType::*set)(const ValueType &) - ); - - /*! - * Set the value of a registered property. - * - * This call is synchronous and will not return until - * the block has actually called the registered set operation. - * - * Note: the user must be careful to only use a value - * that is of the exact type associated with this property. - * Otherwise, set_property with throw a type error. - * - * Examples with explicit argument types: - * my_block->set<size_t>("foo", 42); - * my_block->set("foo", size_t(42)); - * - * \param key the string to identify this property - * \param value the new value to set to this property - */ - template <typename ValueType> - void set(const std::string &key, const ValueType &value); - - /*! - * Get the value of a registered property with reference semantics. - * - * Note: the user must be careful to only use a value - * that is of the exact type associated with this property. - * Otherwise, get_property with throw a type error. - * - * Example getting property with reference semantics: - * size_t foo; my_block->get("foo", foo); - * - * \param key the string to identify this property - * \param value a reference to set to the result - */ - template <typename ValueType> - void get(const std::string &key, ValueType &value); - - /*! - * Get the value of a registered property with return semantics. - * - * Example getting property with return value semantics: - * const size_t foo = my_block->get<size_t>("foo"); - * - * \param key the string to identify this property - * \return the value of this property - */ - template <typename ValueType> - ValueType get(const std::string &key); - - /******************************************************************* * Work related routines and fail states ******************************************************************/ @@ -430,11 +339,8 @@ struct GRAS_API Block : Element /******************************************************************* * private implementation guts for overloads and template support ******************************************************************/ - virtual PMCC _handle_prop_access(const std::string &, const PMCC &, const bool); - void _register_getter(const std::string &, void *); - void _register_setter(const std::string &, void *); - virtual void _set_property(const std::string &, const PMCC &); - virtual PMCC _get_property(const std::string &); + PMCC _handle_call(const std::string &, const PMCC *); + virtual PMCC _handle_call_ts(const std::string &, const PMCC *); void _post_output_msg(const size_t which_output, const PMCC &msg); void _post_input_msg(const size_t which_input, const PMCC &msg); }; diff --git a/include/gras/detail/block.hpp b/include/gras/detail/block.hpp index 9dccb22..3f94e54 100644 --- a/include/gras/detail/block.hpp +++ b/include/gras/detail/block.hpp @@ -3,100 +3,9 @@ #ifndef INCLUDED_GRAS_DETAIL_BLOCK_HPP #define INCLUDED_GRAS_DETAIL_BLOCK_HPP -#include <typeinfo> - namespace gras { -struct GRAS_API PropertyRegistry -{ - PropertyRegistry(void); - virtual ~PropertyRegistry(void); - virtual void set(const PMCC &) = 0; - virtual PMCC get(void) = 0; - virtual const std::type_info &type(void) const = 0; -}; - -template <typename ClassType, typename ValueType> -class PropertyRegistryImpl : public PropertyRegistry -{ -public: - PropertyRegistryImpl( - ClassType *my_class, - ValueType(ClassType::*getter)(void), - void(ClassType::*setter)(const ValueType &) - ): - _my_class(my_class), - _getter(getter), - _setter(setter) - {} - virtual ~PropertyRegistryImpl(void){} - - void set(const PMCC &value) - { - (_my_class->*_setter)(value.safe_as<ValueType>()); - } - - PMCC get(void) - { - return PMC_M((_my_class->*_getter)()); - } - - const std::type_info &type(void) const - { - return typeid(ValueType); - } - -private: - ClassType *_my_class; - ValueType(ClassType::*_getter)(void); - void(ClassType::*_setter)(const ValueType &); -}; - -/*! - * The following functions implement the templated methods in Block - */ - -template <typename ClassType, typename ValueType> -inline void Block::register_getter( - const std::string &key, - ValueType(ClassType::*get)(void) -) -{ - ClassType *obj = dynamic_cast<ClassType *>(this); - void *pr = new PropertyRegistryImpl<ClassType, ValueType>(obj, get, NULL); - this->_register_getter(key, pr); -} - -template <typename ClassType, typename ValueType> -inline void Block::register_setter( - const std::string &key, - void(ClassType::*set)(const ValueType &) -) -{ - ClassType *obj = dynamic_cast<ClassType *>(this); - void *pr = new PropertyRegistryImpl<ClassType, ValueType>(obj, NULL, set); - this->_register_setter(key, pr); -} - -template <typename ValueType> -inline void Block::set(const std::string &key, const ValueType &value) -{ - this->_set_property(key, PMC_M(value)); -} - -template <typename ValueType> -inline void Block::get(const std::string &key, ValueType &value) -{ - value = this->_get_property(key).safe_as<ValueType>(); -} - -template <typename ValueType> -inline ValueType Block::get(const std::string &key) -{ - return this->_get_property(key).safe_as<ValueType>(); -} - template <typename ValueType> inline void Block::post_output_msg(const size_t i, const ValueType &value) { diff --git a/include/gras/detail/callable.hpp b/include/gras/detail/callable.hpp index b3f0d00..3f5252d 100644 --- a/include/gras/detail/callable.hpp +++ b/include/gras/detail/callable.hpp @@ -3,8 +3,6 @@ #ifndef INCLUDED_GRAS_DETAIL_CALLABLE_HPP #define INCLUDED_GRAS_DETAIL_CALLABLE_HPP -#include <typeinfo> - namespace gras { diff --git a/include/gras/element.hpp b/include/gras/element.hpp index 47fbae6..9b46d76 100644 --- a/include/gras/element.hpp +++ b/include/gras/element.hpp @@ -9,6 +9,7 @@ #endif //_MSC_VER #include <gras/gras.hpp> +#include <gras/callable.hpp> #include <gras/weak_container.hpp> #include <boost/shared_ptr.hpp> @@ -18,7 +19,7 @@ namespace gras /*! * Element is a base class for all topological elements. */ -struct GRAS_API Element : boost::shared_ptr<ElementImpl> +struct GRAS_API Element : Callable, boost::shared_ptr<ElementImpl> { //! Create an empty element Element(void); diff --git a/lib/block_props.cpp b/lib/block_props.cpp index ae687be..172282d 100644 --- a/lib/block_props.cpp +++ b/lib/block_props.cpp @@ -5,26 +5,23 @@ using namespace gras; -PropertyRegistry::PropertyRegistry(void){} -PropertyRegistry::~PropertyRegistry(void){} - /*********************************************************************** * The actual thread-safe implementation of property handling **********************************************************************/ -void BlockActor::handle_prop_access( - const PropAccessMessage &message, +void BlockActor::handle_callable( + const CallableMessage &message, const Theron::Address from ) { //setup reply - PropAccessMessage reply; - reply.set = not message.set; + CallableMessage reply; reply.key = message.key; + reply.args = NULL; //call into the handler overload to do the property access try { - reply.value = data->block->_handle_prop_access(message.key, message.value, message.set); + reply.ret = data->block->_handle_call_ts(message.key, message.args); } catch (const std::exception &e) { @@ -43,73 +40,46 @@ void BlockActor::handle_prop_access( this->Send(SelfKickMessage(), this->GetAddress()); } -PMCC Block::_handle_prop_access(const std::string &key, const PMCC &value, const bool set) +PMCC Block::_handle_call_ts(const std::string &key, const PMCC *args) { - const PropertyRegistryPair &pair = (*this)->block_data->property_registry[key]; - PropertyRegistrySptr pr = (set)? pair.setter : pair.getter; - if (not pr) throw std::invalid_argument("no property registered for key: " + key); - if (set) - { - pr->set(value); - return PMCC(); - } - return pr->get(); + //got here, so we call the base class unless this got overloaded + return Callable::_handle_call(key, args); } /*********************************************************************** * A special receiver to handle the property access result **********************************************************************/ -struct PropAccessReceiver : Theron::Receiver +struct CallableReceiver : Theron::Receiver { - PropAccessReceiver(void) + CallableReceiver(void) { - this->RegisterHandler(this, &PropAccessReceiver::handle_prop_access); + this->RegisterHandler(this, &CallableReceiver::handle_callable); } - void handle_prop_access(const PropAccessMessage &msg, const Theron::Address) + void handle_callable(const CallableMessage &msg, const Theron::Address) { this->message = msg; } - PropAccessMessage message; + CallableMessage message; }; /*********************************************************************** * Handle the get and set calls from the user's call-stack **********************************************************************/ -static PMCC prop_access_dispatcher(boost::shared_ptr<BlockActor> actor, const std::string &key, const PMCC &value, const bool set) +PMCC Block::_handle_call(const std::string &key, const PMCC *args) { - PropAccessReceiver receiver; - PropAccessMessage message; + CallableReceiver receiver; + CallableMessage message; + boost::shared_ptr<BlockActor> actor = (*this)->block_actor; message.prio_token = actor->prio_token; - message.set = set; message.key = key; - message.value = value; + message.args = (PMCC *)args; actor->GetFramework().Send(message, receiver.GetAddress(), actor->GetAddress()); receiver.Wait(); if (not receiver.message.error.empty()) { throw std::runtime_error(receiver.message.error); } - return receiver.message.value; -} - -void Block::_register_getter(const std::string &key, void *pr) -{ - (*this)->block_data->property_registry[key].getter.reset(reinterpret_cast<PropertyRegistry *>(pr)); -} - -void Block::_register_setter(const std::string &key, void *pr) -{ - (*this)->block_data->property_registry[key].setter.reset(reinterpret_cast<PropertyRegistry *>(pr)); -} - -void Block::_set_property(const std::string &key, const PMCC &value) -{ - prop_access_dispatcher((*this)->block_actor, key, value, true); -} - -PMCC Block::_get_property(const std::string &key) -{ - return prop_access_dispatcher((*this)->block_actor, key, PMCC(), false); + return receiver.message.ret; } diff --git a/lib/gras_impl/block_actor.hpp b/lib/gras_impl/block_actor.hpp index 9a5c7b8..cfbc2c0 100644 --- a/lib/gras_impl/block_actor.hpp +++ b/lib/gras_impl/block_actor.hpp @@ -52,7 +52,7 @@ struct BlockActor : Theron::Actor this->RegisterHandler(this, &BlockActor::handle_output_alloc); this->RegisterHandler(this, &BlockActor::handle_output_update); - this->RegisterHandler(this, &BlockActor::handle_prop_access); + this->RegisterHandler(this, &BlockActor::handle_callable); this->RegisterHandler(this, &BlockActor::handle_self_kick); this->RegisterHandler(this, &BlockActor::handle_get_stats); } @@ -82,7 +82,7 @@ struct BlockActor : Theron::Actor void handle_output_alloc(const OutputAllocMessage &, const Theron::Address); void handle_output_update(const OutputUpdateMessage &, const Theron::Address); - void handle_prop_access(const PropAccessMessage &, const Theron::Address); + void handle_callable(const CallableMessage &, const Theron::Address); void handle_self_kick(const SelfKickMessage &, const Theron::Address); void handle_get_stats(const GetStatsMessage &, const Theron::Address); diff --git a/lib/gras_impl/block_data.hpp b/lib/gras_impl/block_data.hpp index cbc657e..d6af53d 100644 --- a/lib/gras_impl/block_data.hpp +++ b/lib/gras_impl/block_data.hpp @@ -18,13 +18,6 @@ namespace gras { -typedef boost::shared_ptr<PropertyRegistry> PropertyRegistrySptr; -struct PropertyRegistryPair -{ - PropertyRegistrySptr setter; - PropertyRegistrySptr getter; -}; - enum BlockState { BLOCK_STATE_INIT, @@ -80,9 +73,6 @@ struct BlockData std::vector<std::vector<OutputHintMessage> > output_allocation_hints; - //property stuff - std::map<std::string, PropertyRegistryPair> property_registry; - BlockStats stats; }; diff --git a/lib/gras_impl/messages.hpp b/lib/gras_impl/messages.hpp index a959bef..88d0d79 100644 --- a/lib/gras_impl/messages.hpp +++ b/lib/gras_impl/messages.hpp @@ -131,12 +131,12 @@ struct OutputUpdateMessage //-- do not ack //---------------------------------------------------------------------- -struct PropAccessMessage +struct CallableMessage { Token prio_token; - bool set; std::string key; - PMCC value; + PMCC *args; + PMCC ret; std::string error; }; @@ -182,7 +182,7 @@ THERON_DECLARE_REGISTERED_MESSAGE(gras::OutputHintMessage); THERON_DECLARE_REGISTERED_MESSAGE(gras::OutputAllocMessage); THERON_DECLARE_REGISTERED_MESSAGE(gras::OutputUpdateMessage); -THERON_DECLARE_REGISTERED_MESSAGE(gras::PropAccessMessage); +THERON_DECLARE_REGISTERED_MESSAGE(gras::CallableMessage); THERON_DECLARE_REGISTERED_MESSAGE(gras::SelfKickMessage); THERON_DECLARE_REGISTERED_MESSAGE(gras::GetStatsMessage); diff --git a/lib/register_messages.cpp b/lib/register_messages.cpp index 058f308..eda73ce 100644 --- a/lib/register_messages.cpp +++ b/lib/register_messages.cpp @@ -26,6 +26,6 @@ THERON_DEFINE_REGISTERED_MESSAGE(gras::OutputHintMessage); THERON_DEFINE_REGISTERED_MESSAGE(gras::OutputAllocMessage); THERON_DEFINE_REGISTERED_MESSAGE(gras::OutputUpdateMessage); -THERON_DEFINE_REGISTERED_MESSAGE(gras::PropAccessMessage); +THERON_DEFINE_REGISTERED_MESSAGE(gras::CallableMessage); THERON_DEFINE_REGISTERED_MESSAGE(gras::SelfKickMessage); THERON_DEFINE_REGISTERED_MESSAGE(gras::GetStatsMessage); diff --git a/lib/top_block_query.cpp b/lib/top_block_query.cpp index 7707e32..7a5e13e 100644 --- a/lib/top_block_query.cpp +++ b/lib/top_block_query.cpp @@ -36,6 +36,7 @@ static ptree query_blocks(ElementImpl *self, const ptree &) { BlockActor *actor = dynamic_cast<BlockActor *>(w->get_actor()); ptree prop_e; + /* typedef std::pair<std::string, PropertyRegistryPair> PropRegistryKVP; BOOST_FOREACH(const PropRegistryKVP &p, actor->data->property_registry) { @@ -56,6 +57,7 @@ static ptree query_blocks(ElementImpl *self, const ptree &) block_attrs.push_back(std::make_pair(p.first, prop_attrs)); prop_e.push_back(std::make_pair("props", block_attrs)); } + */ e.push_back(std::make_pair(actor->data->block->get_uid(), prop_e)); } root.push_back(std::make_pair("blocks", e)); @@ -182,6 +184,7 @@ static ptree query_props(ElementImpl *self, const ptree &query) { BlockActor *actor = dynamic_cast<BlockActor *>(w->get_actor()); if (actor->data->block->get_uid() != block_id) continue; + /* if (set) { const std::type_info &t = actor->data->property_registry[prop_key].setter->type(); @@ -196,6 +199,7 @@ static ptree query_props(ElementImpl *self, const ptree &query) root.push_back(std::make_pair("key", query.get_child("key"))); root.push_back(std::make_pair("value", v)); } + */ } return root; } diff --git a/tests/block_props_test.cpp b/tests/block_props_test.cpp index f53a1c3..b14677d 100644 --- a/tests/block_props_test.cpp +++ b/tests/block_props_test.cpp @@ -11,8 +11,8 @@ struct MyBlock : gras::Block gras::Block("MyBlock") { foo = 0; - this->register_getter("foo", &MyBlock::get_foo); - this->register_setter("foo", &MyBlock::set_foo); + this->register_call("get_foo", &MyBlock::get_foo); + this->register_call("set_foo", &MyBlock::set_foo); } //dummy work @@ -36,35 +36,20 @@ BOOST_AUTO_TEST_CASE(test_property_set_get_with_return) MyBlock my_block; BOOST_CHECK_EQUAL(my_block.foo, size_t(0)); - my_block.set("foo", size_t(42)); + my_block.x("set_foo", size_t(42)); BOOST_CHECK_EQUAL(my_block.foo, size_t(42)); - const size_t my_foo = my_block.get<size_t>("foo"); + const size_t my_foo = my_block.x<size_t>("get_foo"); BOOST_CHECK_EQUAL(my_foo, size_t(42)); } -BOOST_AUTO_TEST_CASE(test_property_set_get_with_reference) -{ - MyBlock my_block; - BOOST_CHECK_EQUAL(my_block.foo, size_t(0)); - - my_block.set("foo", size_t(42)); - BOOST_CHECK_EQUAL(my_block.foo, size_t(42)); - - size_t my_foo; my_block.get("foo", my_foo); - BOOST_CHECK_EQUAL(my_foo, size_t(42)); - - double my_foo_d; my_block.get("foo", my_foo_d); - BOOST_CHECK_EQUAL(my_foo_d, double(42)); -} - BOOST_AUTO_TEST_CASE(test_property_errors) { MyBlock my_block; //property does not exist - BOOST_CHECK_THROW(my_block.get<size_t>("bar"), std::exception); + BOOST_CHECK_THROW(my_block.x<size_t>("get_bar"), std::exception); //wrong type for property - BOOST_CHECK_THROW(my_block.set("foo", "a string"), std::exception); + BOOST_CHECK_THROW(my_block.x("set_foo", "a string"), std::exception); } |