summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Blum2013-06-02 10:50:46 -0700
committerJosh Blum2013-06-02 10:50:46 -0700
commite24e4d7dfe648e33988366cb1f615c2a443f5156 (patch)
tree66137dc9be472b0e26a7fbcbe56068a7d85242c7
parentab1f7e5871d9323242e9b3d21e2f7811f1567c43 (diff)
downloadsandhi-e24e4d7dfe648e33988366cb1f615c2a443f5156.tar.gz
sandhi-e24e4d7dfe648e33988366cb1f615c2a443f5156.tar.bz2
sandhi-e24e4d7dfe648e33988366cb1f615c2a443f5156.zip
props: began filling in pmc to/from ptree
-rw-r--r--lib/block_props.cpp11
-rw-r--r--lib/gras_impl/block_actor.hpp1
-rw-r--r--lib/top_block_query.cpp81
-rw-r--r--tests/query_test.py16
4 files changed, 101 insertions, 8 deletions
diff --git a/lib/block_props.cpp b/lib/block_props.cpp
index 5d536bb..b3456ac 100644
--- a/lib/block_props.cpp
+++ b/lib/block_props.cpp
@@ -77,16 +77,15 @@ struct PropAccessReceiver : Theron::Receiver
/***********************************************************************
* Handle the get and set calls from the user's call-stack
**********************************************************************/
-template <typename ActorType>
-static PMCC prop_access_dispatcher(ActorType &actor, const std::string &key, const PMCC &value, const bool set)
+PMCC BlockActor::prop_access_dispatcher(const std::string &key, const PMCC &value, const bool set)
{
PropAccessReceiver receiver;
PropAccessMessage message;
- message.prio_token = actor->prio_token;
+ message.prio_token = this->prio_token;
message.set = set;
message.key = key;
message.value = value;
- actor->GetFramework().Send(message, receiver.GetAddress(), actor->GetAddress());
+ this->GetFramework().Send(message, receiver.GetAddress(), this->GetAddress());
receiver.Wait();
if (not receiver.message.error.empty())
{
@@ -107,10 +106,10 @@ void Block::_register_setter(const std::string &key, void *pr)
void Block::_set_property(const std::string &key, const PMCC &value)
{
- prop_access_dispatcher((*this)->block, key, value, true);
+ (*this)->block->prop_access_dispatcher(key, value, true);
}
PMCC Block::_get_property(const std::string &key)
{
- return prop_access_dispatcher((*this)->block, key, PMCC(), false);
+ return (*this)->block->prop_access_dispatcher(key, PMCC(), false);
}
diff --git a/lib/gras_impl/block_actor.hpp b/lib/gras_impl/block_actor.hpp
index 269674c..a7ed6c5 100644
--- a/lib/gras_impl/block_actor.hpp
+++ b/lib/gras_impl/block_actor.hpp
@@ -169,6 +169,7 @@ struct BlockActor : Apology::Worker
//property stuff
std::map<std::string, PropertyRegistryPair> property_registry;
+ PMCC prop_access_dispatcher(const std::string &key, const PMCC &value, const bool set);
BlockStats stats;
};
diff --git a/lib/top_block_query.cpp b/lib/top_block_query.cpp
index bf74204..205f965 100644
--- a/lib/top_block_query.cpp
+++ b/lib/top_block_query.cpp
@@ -160,14 +160,91 @@ static ptree query_stats(ElementImpl *self, const ptree &query)
return root;
}
+static PMCC ptree_to_pmc(const ptree &value, const std::type_info &info)
+{
+ //if the type is PMCC - educated guess and recursively call
+ if (info == typeid(PMCC) or info == typeid(PMC))
+ {
+ //single child or array?
+ //can we cast to number?
+ //TODO be lazy and do number for initial tests
+ return ptree_to_pmc(value, typeid(long));
+ }
+
+ #define ptree_to_pmc_try(type) \
+ if (info == typeid(type)) return PMC_M(value.get_value<type>());
+
+ //determine number
+ ptree_to_pmc_try(char);
+ ptree_to_pmc_try(signed char);
+ ptree_to_pmc_try(unsigned char);
+ ptree_to_pmc_try(signed short);
+ ptree_to_pmc_try(unsigned short);
+ ptree_to_pmc_try(signed int);
+ ptree_to_pmc_try(unsigned int);
+ ptree_to_pmc_try(signed long);
+ ptree_to_pmc_try(unsigned long);
+ ptree_to_pmc_try(signed long long);
+ ptree_to_pmc_try(unsigned long long);
+ //complex number
+ //string
+ ptree_to_pmc_try(std::string);
+ //determine number vector
+
+ //otherwise null -- will crap out
+ return PMC();
+}
+
+static ptree pmc_to_ptree(const PMCC &value)
+{
+ ptree v;
+ #define pmc_to_ptree_try(type) \
+ if (value.is<type>()) {v.put_value(value.as<type>()); return v;}
+
+ //determine number
+ pmc_to_ptree_try(char);
+ pmc_to_ptree_try(signed char);
+ pmc_to_ptree_try(unsigned char);
+ pmc_to_ptree_try(signed short);
+ pmc_to_ptree_try(unsigned short);
+ pmc_to_ptree_try(signed int);
+ pmc_to_ptree_try(unsigned int);
+ pmc_to_ptree_try(signed long);
+ pmc_to_ptree_try(unsigned long);
+ pmc_to_ptree_try(signed long long);
+ pmc_to_ptree_try(unsigned long long);
+
+ //determine string
+ pmc_to_ptree_try(std::string);
+
+ return v;
+}
+
static ptree query_props(ElementImpl *self, const ptree &query)
{
ptree root;
const std::string block_id = query.get<std::string>("block");
const std::string prop_key = query.get<std::string>("key");
const std::string action = query.get<std::string>("action");
- const std::string value = query.get<std::string>("value");
- //TODO :-)
+ BOOST_FOREACH(Apology::Worker *worker, self->executor->get_workers())
+ {
+ BlockActor *block = dynamic_cast<BlockActor *>(worker);
+ if (block->block_ptr->get_uid() != block_id) continue;
+ if (action == "set")
+ {
+ const std::type_info &t = block->property_registry[prop_key].setter->type();
+ const PMCC p = ptree_to_pmc(query.get_child("value"), t);
+ block->prop_access_dispatcher(prop_key, p, true);
+ }
+ if (action == "get")
+ {
+ PMCC p = block->prop_access_dispatcher(prop_key, PMC(), false);
+ ptree v = pmc_to_ptree(p);
+ root.push_back(std::make_pair("block", query.get_child("block")));
+ 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/query_test.py b/tests/query_test.py
index 3cbe648..a61d4db 100644
--- a/tests/query_test.py
+++ b/tests/query_test.py
@@ -75,8 +75,24 @@ class QueryTest(unittest.TestCase):
self.assertTrue('my_block_uid' in blocks_result['blocks'])
#set the property
+ self.tb.query(dict(
+ path="/props.json",
+ block='my_block_uid',
+ key='foo',
+ action='set',
+ value=42,
+ ))
+ self.assertEqual(block.foo, 42)
#get the property
+ block.set('foo', 21)
+ result = self.tb.query(dict(
+ path="/props.json",
+ block='my_block_uid',
+ key='foo',
+ action='get'
+ ))
+ self.assertEqual(result['value'], 21)
if __name__ == '__main__':
unittest.main()