summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Blum2013-07-05 18:50:01 -0700
committerJosh Blum2013-07-05 18:50:01 -0700
commitfc80d2c0acec4f668b58a05bd5a3a06b0a2a2280 (patch)
tree29433c49392b458aa40b318b11a3afb34b918625
parentdf32957fb259989b6c269c10808e550e0913b652 (diff)
downloadsandhi-fc80d2c0acec4f668b58a05bd5a3a06b0a2a2280.tar.gz
sandhi-fc80d2c0acec4f668b58a05bd5a3a06b0a2a2280.tar.bz2
sandhi-fc80d2c0acec4f668b58a05bd5a3a06b0a2a2280.zip
gras: begin replacing set/get with callable
-rw-r--r--include/gras/block.hpp98
-rw-r--r--include/gras/detail/block.hpp91
-rw-r--r--include/gras/detail/callable.hpp2
-rw-r--r--include/gras/element.hpp3
-rw-r--r--lib/block_props.cpp68
-rw-r--r--lib/gras_impl/block_actor.hpp4
-rw-r--r--lib/gras_impl/block_data.hpp10
-rw-r--r--lib/gras_impl/messages.hpp8
-rw-r--r--lib/register_messages.cpp2
-rw-r--r--lib/top_block_query.cpp4
-rw-r--r--tests/block_props_test.cpp27
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);
}