diff options
-rw-r--r-- | CMakeLists.txt | 4 | ||||
-rw-r--r-- | include/gras/detail/block.hpp | 8 | ||||
-rw-r--r-- | lib/block_props.cpp | 10 | ||||
-rw-r--r-- | lib/gras_impl/block_actor.hpp | 8 | ||||
-rw-r--r-- | lib/top_block_query.cpp | 33 | ||||
-rw-r--r-- | python/gras/GRAS_Block.i | 22 | ||||
-rw-r--r-- | tests/query_test.py | 32 |
7 files changed, 107 insertions, 10 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 21f1909..b3c93dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,7 +114,7 @@ set(CMAKE_PROJECT_NAME gnuradio) #for submodule vars set(GR_MOAR_LIBRARIES ${GRAS_LIBRARIES}) -add_subdirectory(gnuradio) +#add_subdirectory(gnuradio) ######################################################################## # add GRAS to gnuradio cpack registry @@ -195,7 +195,7 @@ if(ENABLE_GR_DIGITAL) list(APPEND GR_TEST_TARGET_DEPS gnuradio-digital gnuradio-filter gnuradio-fft gnuradio-analog) endif(ENABLE_GR_DIGITAL) -add_subdirectory(grextras) +#add_subdirectory(grextras) ######################################################################## # add GrExtras to gnuradio cpack registry diff --git a/include/gras/detail/block.hpp b/include/gras/detail/block.hpp index ac9a669..d975b0f 100644 --- a/include/gras/detail/block.hpp +++ b/include/gras/detail/block.hpp @@ -3,6 +3,8 @@ #ifndef INCLUDED_GRAS_DETAIL_BLOCK_HPP #define INCLUDED_GRAS_DETAIL_BLOCK_HPP +#include <typeinfo> + namespace gras { @@ -12,6 +14,7 @@ struct GRAS_API PropertyRegistry 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> @@ -39,6 +42,11 @@ public: return PMC_M((_my_class->*_getter)()); } + const std::type_info &type(void) const + { + return typeid(ValueType); + } + private: ClassType *_my_class; ValueType(ClassType::*_getter)(void); diff --git a/lib/block_props.cpp b/lib/block_props.cpp index f32dc69..5d536bb 100644 --- a/lib/block_props.cpp +++ b/lib/block_props.cpp @@ -45,10 +45,8 @@ void BlockActor::handle_prop_access( PMCC Block::_handle_prop_access(const std::string &key, const PMCC &value, const bool set) { - PropertyRegistrySptr pr = (set)? - (*this)->block->setter_registry[key] : - (*this)->block->getter_registry[key] - ; + const PropertyRegistryPair &pair = (*this)->block->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) { @@ -99,12 +97,12 @@ static PMCC prop_access_dispatcher(ActorType &actor, const std::string &key, con void Block::_register_getter(const std::string &key, void *pr) { - (*this)->block->getter_registry[key].reset(reinterpret_cast<PropertyRegistry *>(pr)); + (*this)->block->property_registry[key].getter.reset(reinterpret_cast<PropertyRegistry *>(pr)); } void Block::_register_setter(const std::string &key, void *pr) { - (*this)->block->setter_registry[key].reset(reinterpret_cast<PropertyRegistry *>(pr)); + (*this)->block->property_registry[key].setter.reset(reinterpret_cast<PropertyRegistry *>(pr)); } void Block::_set_property(const std::string &key, const PMCC &value) diff --git a/lib/gras_impl/block_actor.hpp b/lib/gras_impl/block_actor.hpp index bc4ecdd..269674c 100644 --- a/lib/gras_impl/block_actor.hpp +++ b/lib/gras_impl/block_actor.hpp @@ -24,6 +24,11 @@ namespace gras { typedef boost::shared_ptr<PropertyRegistry> PropertyRegistrySptr; +struct PropertyRegistryPair +{ + PropertyRegistrySptr setter; + PropertyRegistrySptr getter; +}; struct BlockActor : Apology::Worker { @@ -163,8 +168,7 @@ struct BlockActor : Apology::Worker std::vector<std::vector<OutputHintMessage> > output_allocation_hints; //property stuff - std::map<std::string, PropertyRegistrySptr> getter_registry; - std::map<std::string, PropertyRegistrySptr> setter_registry; + std::map<std::string, PropertyRegistryPair> property_registry; BlockStats stats; }; diff --git a/lib/top_block_query.cpp b/lib/top_block_query.cpp index 29d3bb0..3905faf 100644 --- a/lib/top_block_query.cpp +++ b/lib/top_block_query.cpp @@ -155,6 +155,38 @@ static std::string query_stats(ElementImpl *self, const boost::property_tree::pt return my_write_json(root); } +static std::string query_props(ElementImpl *self, const boost::property_tree::ptree &) +{ + boost::property_tree::ptree root; + boost::property_tree::ptree e; + BOOST_FOREACH(Apology::Worker *worker, self->executor->get_workers()) + { + BlockActor *block = dynamic_cast<BlockActor *>(worker); + boost::property_tree::ptree prop_e; + typedef std::pair<std::string, PropertyRegistryPair> PropRegistryKVP; + BOOST_FOREACH(const PropRegistryKVP &p, block->property_registry) + { + boost::property_tree::ptree attrs; + if (p.second.setter) + { + boost::property_tree::ptree type; + type.put_value(p.second.setter->type().name()); + attrs.push_back(std::make_pair("set_type", type)); + } + if (p.second.getter) + { + boost::property_tree::ptree type; + type.put_value(p.second.getter->type().name()); + attrs.push_back(std::make_pair("get_type", type)); + } + prop_e.push_back(std::make_pair(p.first, attrs)); + } + e.push_back(std::make_pair(block->block_ptr->to_string(), prop_e)); + } + root.push_back(std::make_pair("props", e)); + return my_write_json(root); +} + std::string TopBlock::query(const std::string &args) { //why the fuck does no OS ever patch boost when there is a bug @@ -168,5 +200,6 @@ std::string TopBlock::query(const std::string &args) std::string path = query_args_pt.get<std::string>("args.path"); if (path == "/blocks.json") return query_blocks(this->get(), query_args_pt); if (path == "/stats.json") return query_stats(this->get(), query_args_pt); + if (path == "/props.json") return query_props(this->get(), query_args_pt); return ""; } diff --git a/python/gras/GRAS_Block.i b/python/gras/GRAS_Block.i index 4cf245e..bedeb85 100644 --- a/python/gras/GRAS_Block.i +++ b/python/gras/GRAS_Block.i @@ -176,6 +176,26 @@ struct BlockPython : Block } virtual PMCC _Py_handle_prop_access(const std::string &key, const PMCC &value, const bool set) = 0; + + void dummy_setter(const PMCC &) + { + //NOP + } + PMCC dummy_getter(void) + { + return PMC(); + } + + void _Py_register_dummy_setter(const std::string &key) + { + this->register_setter(key, &BlockPython::dummy_setter); + } + + void _Py_register_dummy_getter(const std::string &key) + { + this->register_getter(key, &BlockPython::dummy_getter); + } + }; } @@ -291,8 +311,10 @@ class Block(BlockPython): return PMC_M(getter()) def register_getter(self, key, getter): + self._Py_register_dummy_getter(key) self.__getter_registry[key] = getter def register_setter(self, key, setter): + self._Py_register_dummy_setter(key) self.__setter_registry[key] = setter %} diff --git a/tests/query_test.py b/tests/query_test.py index e93b5d6..1038712 100644 --- a/tests/query_test.py +++ b/tests/query_test.py @@ -6,6 +6,27 @@ import numpy from demo_blocks import * import json +class MyBlock(gras.Block): + def __init__(self): + gras.Block.__init__(self, "MyBlock", out_sig=[numpy.uint32], in_sig=[numpy.uint32]) + self.foo = 0 + self.register_getter("foo", self.get_foo) + self.register_setter("foo", self.set_foo) + + def work(self, ins, outs): + n = min(len(ins[0]), len(outs[0])) + outs[0][:n] = ins[0][:n] + self.foo + self.consume(n) + self.produce(n) + + def get_foo(self): + return self.foo + + def set_foo(self, new_foo): + print "new_foo", new_foo + new_foo + 0 #throws if its not a number + self.foo = new_foo + class QueryTest(unittest.TestCase): def setUp(self): @@ -31,5 +52,16 @@ class QueryTest(unittest.TestCase): print stats_json json.loads(stats_json) + def test_props(self): + vec_source = VectorSource(numpy.uint32, [0, 9, 8, 7, 6]) + vec_sink = VectorSink(numpy.uint32) + block = MyBlock() + self.tb.connect(vec_source, block, vec_sink) + self.tb.run() + + props_json = self.tb.query("<args><path>/props.json</path></args>") + print props_json + json.loads(props_json) + if __name__ == '__main__': unittest.main() |