diff options
author | Josh Blum | 2013-07-05 19:40:26 -0700 |
---|---|---|
committer | Josh Blum | 2013-07-05 19:40:26 -0700 |
commit | 66db95c9d57cd0c2a7a9fabe06f7d7d5b3fb8a45 (patch) | |
tree | 3a3fcbac80e13971e20ca4c93de51e1c693f4af4 | |
parent | fc80d2c0acec4f668b58a05bd5a3a06b0a2a2280 (diff) | |
download | sandhi-66db95c9d57cd0c2a7a9fabe06f7d7d5b3fb8a45.tar.gz sandhi-66db95c9d57cd0c2a7a9fabe06f7d7d5b3fb8a45.tar.bz2 sandhi-66db95c9d57cd0c2a7a9fabe06f7d7d5b3fb8a45.zip |
gras: pythonic work on callable interface
-rw-r--r-- | include/gras/block.hpp | 4 | ||||
-rw-r--r-- | include/gras/block.i | 10 | ||||
-rw-r--r-- | include/gras/callable.hpp | 2 | ||||
-rw-r--r-- | include/gras/detail/callable.hpp | 70 | ||||
-rw-r--r-- | include/gras/element.i | 9 | ||||
-rw-r--r-- | lib/block_props.cpp | 7 | ||||
-rw-r--r-- | lib/callable.cpp | 2 | ||||
-rw-r--r-- | lib/gras_impl/messages.hpp | 2 | ||||
-rw-r--r-- | python/gras/GRAS_PyBlock.i | 65 | ||||
-rw-r--r-- | tests/block_props_test.py | 22 |
10 files changed, 82 insertions, 111 deletions
diff --git a/include/gras/block.hpp b/include/gras/block.hpp index 644a73c..05809a1 100644 --- a/include/gras/block.hpp +++ b/include/gras/block.hpp @@ -339,8 +339,8 @@ struct GRAS_API Block : Element /******************************************************************* * private implementation guts for overloads and template support ******************************************************************/ - PMCC _handle_call(const std::string &, const PMCC *); - virtual PMCC _handle_call_ts(const std::string &, const PMCC *); + virtual 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/block.i b/include/gras/block.i index 2de2c98..2ba9779 100644 --- a/include/gras/block.i +++ b/include/gras/block.i @@ -21,19 +21,10 @@ //////////////////////////////////////////////////////////////////////// // Create pythonic gateway to get and set //////////////////////////////////////////////////////////////////////// -%pythoncode %{ -from PMC import * -%} %extend gras::Block { %insert("python") %{ - def set(self, key, value): - self._set_property(key, PMC_M(value)) - - def get(self, key): - return self._get_property(key)() - def post_output_msg(self, which_output, value): if not isinstance(value, PMCC): value = PMC_M(value) self._post_output_msg(which_output, value) @@ -41,7 +32,6 @@ from PMC import * def post_input_msg(self, which_input, value): if not isinstance(value, PMCC): value = PMC_M(value) self._post_input_msg(which_input, value) - %} } diff --git a/include/gras/callable.hpp b/include/gras/callable.hpp index 2405b9d..ad74dd7 100644 --- a/include/gras/callable.hpp +++ b/include/gras/callable.hpp @@ -97,7 +97,7 @@ struct GRAS_API Callable * Private registration hooks ******************************************************************/ void _register_call(const std::string &, void *); - virtual PMCC _handle_call(const std::string &, const PMCC *); + virtual PMCC _handle_call(const std::string &, const PMCC &); boost::shared_ptr<void> _call_registry; }; diff --git a/include/gras/detail/callable.hpp b/include/gras/detail/callable.hpp index 3f5252d..ddc8f55 100644 --- a/include/gras/detail/callable.hpp +++ b/include/gras/detail/callable.hpp @@ -3,6 +3,8 @@ #ifndef INCLUDED_GRAS_DETAIL_CALLABLE_HPP #define INCLUDED_GRAS_DETAIL_CALLABLE_HPP +#include <PMC/Containers.hpp> //PMCList + namespace gras { @@ -13,7 +15,7 @@ struct GRAS_API CallableRegistryEntry { CallableRegistryEntry(void); virtual ~CallableRegistryEntry(void); - virtual PMCC call(const PMCC *args) = 0; + virtual PMCC call(const PMCC &args) = 0; }; /*********************************************************************** @@ -25,7 +27,7 @@ struct CallableRegistryEntryImpl0 : CallableRegistryEntry typedef ReturnType(ClassType::*Fcn)(void); CallableRegistryEntryImpl0(ClassType *obj, Fcn fcn): _obj(obj), _fcn(fcn){} - PMCC call(const PMCC *args) + PMCC call(const PMCC &) { return PMC_M((_obj->*_fcn)()); } @@ -46,7 +48,7 @@ struct CallableRegistryEntryImplVoid0 : CallableRegistryEntry typedef void(ClassType::*Fcn)(void); CallableRegistryEntryImplVoid0(ClassType *obj, Fcn fcn): _obj(obj), _fcn(fcn){} - PMCC call(const PMCC *args) + PMCC call(const PMCC &) { (_obj->*_fcn)(); return PMCC(); } @@ -70,9 +72,10 @@ struct CallableRegistryEntryImpl1 : CallableRegistryEntry typedef ReturnType(ClassType::*Fcn)(const Arg0 &); CallableRegistryEntryImpl1(ClassType *obj, Fcn fcn): _obj(obj), _fcn(fcn){} - PMCC call(const PMCC *args) + PMCC call(const PMCC &args) { - return PMC_M((_obj->*_fcn)(args[0].safe_as<Arg0>())); + const PMCList &a = args.as<PMCList>(); + return PMC_M((_obj->*_fcn)(a[0].safe_as<Arg0>())); } ClassType *_obj; Fcn _fcn; }; @@ -91,9 +94,10 @@ struct CallableRegistryEntryImplVoid1 : CallableRegistryEntry typedef void(ClassType::*Fcn)(const Arg0 &); CallableRegistryEntryImplVoid1(ClassType *obj, Fcn fcn): _obj(obj), _fcn(fcn){} - PMCC call(const PMCC *args) + PMCC call(const PMCC &args) { - (_obj->*_fcn)(args[0].safe_as<Arg0>()); return PMCC(); + const PMCList &a = args.as<PMCList>(); + (_obj->*_fcn)(a[0].safe_as<Arg0>()); return PMCC(); } ClassType *_obj; Fcn _fcn; }; @@ -115,9 +119,10 @@ struct CallableRegistryEntryImpl2 : CallableRegistryEntry typedef ReturnType(ClassType::*Fcn)(const Arg0 &, const Arg1 &); CallableRegistryEntryImpl2(ClassType *obj, Fcn fcn): _obj(obj), _fcn(fcn){} - PMCC call(const PMCC *args) + PMCC call(const PMCC &args) { - return PMC_M((_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>())); + const PMCList &a = args.as<PMCList>(); + return PMC_M((_obj->*_fcn)(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>())); } ClassType *_obj; Fcn _fcn; }; @@ -136,9 +141,10 @@ struct CallableRegistryEntryImplVoid2 : CallableRegistryEntry typedef void(ClassType::*Fcn)(const Arg0 &, const Arg1 &); CallableRegistryEntryImplVoid2(ClassType *obj, Fcn fcn): _obj(obj), _fcn(fcn){} - PMCC call(const PMCC *args) + PMCC call(const PMCC &args) { - (_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>()); return PMCC(); + const PMCList &a = args.as<PMCList>(); + (_obj->*_fcn)(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>()); return PMCC(); } ClassType *_obj; Fcn _fcn; }; @@ -160,9 +166,10 @@ struct CallableRegistryEntryImpl3 : CallableRegistryEntry typedef ReturnType(ClassType::*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &); CallableRegistryEntryImpl3(ClassType *obj, Fcn fcn): _obj(obj), _fcn(fcn){} - PMCC call(const PMCC *args) + PMCC call(const PMCC &args) { - return PMC_M((_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>(), args[2].safe_as<Arg2>())); + const PMCList &a = args.as<PMCList>(); + return PMC_M((_obj->*_fcn)(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>(), a[2].safe_as<Arg2>())); } ClassType *_obj; Fcn _fcn; }; @@ -181,9 +188,10 @@ struct CallableRegistryEntryImplVoid3 : CallableRegistryEntry typedef void(ClassType::*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &); CallableRegistryEntryImplVoid3(ClassType *obj, Fcn fcn): _obj(obj), _fcn(fcn){} - PMCC call(const PMCC *args) + PMCC call(const PMCC &args) { - (_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>(), args[2].safe_as<Arg2>()); return PMCC(); + const PMCList &a = args.as<PMCList>(); + (_obj->*_fcn)(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>(), a[2].safe_as<Arg2>()); return PMCC(); } ClassType *_obj; Fcn _fcn; }; @@ -202,16 +210,16 @@ void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const template <typename ReturnType> ReturnType Callable::x(const std::string &key) { - PMCC args[0]; - PMCC r = _handle_call(key, args); + PMCList args(0); + PMCC r = _handle_call(key, PMC_M(args)); return r.safe_as<ReturnType>(); } inline void Callable::x(const std::string &key) { - PMCC args[0]; - _handle_call(key, args); + PMCList args(0); + _handle_call(key, PMC_M(args)); } /*********************************************************************** @@ -220,18 +228,18 @@ void Callable::x(const std::string &key) template <typename ReturnType, typename Arg0> ReturnType Callable::x(const std::string &key, const Arg0 &a0) { - PMCC args[1]; + PMCList args(1); args[0] = PMC_M(a0); - PMCC r = _handle_call(key, args); + PMCC r = _handle_call(key, PMC_M(args)); return r.safe_as<ReturnType>(); } template <typename Arg0> void Callable::x(const std::string &key, const Arg0 &a0) { - PMCC args[1]; + PMCList args(1); args[0] = PMC_M(a0); - _handle_call(key, args); + _handle_call(key, PMC_M(args)); } /*********************************************************************** @@ -240,20 +248,20 @@ void Callable::x(const std::string &key, const Arg0 &a0) template <typename ReturnType, typename Arg0, typename Arg1> ReturnType Callable::x(const std::string &key, const Arg0 &a0, const Arg1 &a1) { - PMCC args[2]; + PMCList args(2); args[0] = PMC_M(a0); args[1] = PMC_M(a1); - PMCC r = _handle_call(key, args); + PMCC r = _handle_call(key, PMC_M(args)); return r.safe_as<ReturnType>(); } template <typename Arg0, typename Arg1> void Callable::x(const std::string &key, const Arg0 &a0, const Arg1 &a1) { - PMCC args[2]; + PMCList args(2); args[0] = PMC_M(a0); args[1] = PMC_M(a1); - _handle_call(key, args); + _handle_call(key, PMC_M(args)); } /*********************************************************************** @@ -262,22 +270,22 @@ void Callable::x(const std::string &key, const Arg0 &a0, const Arg1 &a1) template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2> ReturnType Callable::x(const std::string &key, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2) { - PMCC args[3]; + PMCList args(3); args[0] = PMC_M(a0); args[1] = PMC_M(a1); args[2] = PMC_M(a2); - PMCC r = _handle_call(key, args); + PMCC r = _handle_call(key, PMC_M(args)); return r.safe_as<ReturnType>(); } template <typename Arg0, typename Arg1, typename Arg2> void Callable::x(const std::string &key, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2) { - PMCC args[3]; + PMCList args(3); args[0] = PMC_M(a0); args[1] = PMC_M(a1); args[2] = PMC_M(a2); - _handle_call(key, args); + _handle_call(key, PMC_M(args)); } } //namespace gras diff --git a/include/gras/element.i b/include/gras/element.i index eb4d039..8fbba00 100644 --- a/include/gras/element.i +++ b/include/gras/element.i @@ -25,14 +25,23 @@ namespace gras %include <std_string.i> %include <gras/gras.hpp> %include <gras/element.hpp> +%import <PMC/PMC.i> //////////////////////////////////////////////////////////////////////// // Operator overloads for Element //////////////////////////////////////////////////////////////////////// +%pythoncode %{ +from PMC import * +%} %extend gras::Element { %insert("python") %{ + def x(self, key, *args): + pmcargs = PMC_M(list(args)) + pmcret = self._handle_call(key, pmcargs) + return pmcret() + def __eq__(self, rhs): if not isinstance(rhs, Element): return False return self.equals(rhs) diff --git a/lib/block_props.cpp b/lib/block_props.cpp index 172282d..9a374f1 100644 --- a/lib/block_props.cpp +++ b/lib/block_props.cpp @@ -16,7 +16,6 @@ void BlockActor::handle_callable( //setup reply CallableMessage reply; reply.key = message.key; - reply.args = NULL; //call into the handler overload to do the property access try @@ -40,7 +39,7 @@ void BlockActor::handle_callable( this->Send(SelfKickMessage(), this->GetAddress()); } -PMCC Block::_handle_call_ts(const std::string &key, const PMCC *args) +PMCC Block::_handle_call_ts(const std::string &key, const PMCC &args) { //got here, so we call the base class unless this got overloaded return Callable::_handle_call(key, args); @@ -67,14 +66,14 @@ struct CallableReceiver : Theron::Receiver /*********************************************************************** * Handle the get and set calls from the user's call-stack **********************************************************************/ -PMCC Block::_handle_call(const std::string &key, const PMCC *args) +PMCC Block::_handle_call(const std::string &key, const PMCC &args) { CallableReceiver receiver; CallableMessage message; boost::shared_ptr<BlockActor> actor = (*this)->block_actor; message.prio_token = actor->prio_token; message.key = key; - message.args = (PMCC *)args; + message.args = args; actor->GetFramework().Send(message, receiver.GetAddress(), actor->GetAddress()); receiver.Wait(); if (not receiver.message.error.empty()) diff --git a/lib/callable.cpp b/lib/callable.cpp index cd783fc..385715a 100644 --- a/lib/callable.cpp +++ b/lib/callable.cpp @@ -25,7 +25,7 @@ void Callable::_register_call(const std::string &key, void *entry) (*cr)[key].reset(reinterpret_cast<CallableRegistryEntry *>(entry)); } -PMCC Callable::_handle_call(const std::string &key, const PMCC *args) +PMCC Callable::_handle_call(const std::string &key, const PMCC &args) { CallableRegistry *cr = reinterpret_cast<CallableRegistry *>(_call_registry.get()); boost::shared_ptr<CallableRegistryEntry> entry = (*cr)[key]; diff --git a/lib/gras_impl/messages.hpp b/lib/gras_impl/messages.hpp index 88d0d79..4294ab8 100644 --- a/lib/gras_impl/messages.hpp +++ b/lib/gras_impl/messages.hpp @@ -135,7 +135,7 @@ struct CallableMessage { Token prio_token; std::string key; - PMCC *args; + PMCC args; PMCC ret; std::string error; }; diff --git a/python/gras/GRAS_PyBlock.i b/python/gras/GRAS_PyBlock.i index e9809a8..ff91a6f 100644 --- a/python/gras/GRAS_PyBlock.i +++ b/python/gras/GRAS_PyBlock.i @@ -12,7 +12,7 @@ %feature("nodirector") gras::BlockPython::notify_inactive; %feature("nodirector") gras::BlockPython::notify_topology; %feature("nodirector") gras::BlockPython::work; -%feature("nodirector") gras::BlockPython::_handle_prop_access; +%feature("nodirector") gras::BlockPython::_handle_call_ts; //////////////////////////////////////////////////////////////////////// // http://www.swig.org/Doc2.0/Library.html#Library_stl_exceptions @@ -157,45 +157,19 @@ struct BlockPython : Block virtual void _Py_propagate_tags(const size_t which_input, const TagIter &iter) = 0; - void _set_property(const std::string &key, const PMCC &value) + PMCC _handle_call(const std::string &key, const PMCC &args) { PyTSPhondler phil; - return Block::_set_property(key, value); + return Block::_handle_call(key, args); } - PMCC _get_property(const std::string &key) - { - PyTSPhondler phil; - return Block::_get_property(key); - } - - PMCC _handle_prop_access(const std::string &key, const PMCC &value, const bool set) + PMCC _handle_call_ts(const std::string &key, const PMCC &args) { PyGILPhondler phil; - return this->_Py_handle_prop_access(key, value, set); - } - - 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); + return this->_Py_handle_call_ts(key, args); } + virtual PMCC _Py_handle_call_ts(const std::string &key, const PMCC &args) = 0; }; } @@ -221,8 +195,7 @@ class PyBlock(BlockPython): BlockPython.__init__(self, name) self.set_input_signature(in_sig) self.set_output_signature(out_sig) - self.__getter_registry = dict() - self.__setter_registry = dict() + self.__call_registry = dict() def set_input_signature(self, sig): self.__in_sig = sig_to_dtype_sig(sig) @@ -301,20 +274,12 @@ class PyBlock(BlockPython): t.offset -= self.get_consumed(i) self.post_output_tag(o, t) - def _Py_handle_prop_access(self, key, value, set): - if set: - setter = self.__setter_registry[key] - setter(value()) - return PMCC() - else: - getter = self.__getter_registry[key] - 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 + def _Py_handle_call_ts(self, key, args): + call = self.__call_registry[key] + pyargs = args() + pyret = call(*pyargs) + return PMC_M(pyret) + + def register_call(self, key, call): + self.__call_registry[key] = call %} diff --git a/tests/block_props_test.py b/tests/block_props_test.py index 0b068f9..65acaac 100644 --- a/tests/block_props_test.py +++ b/tests/block_props_test.py @@ -8,8 +8,8 @@ class MyBlock(gras.Block): def __init__(self): gras.Block.__init__(self, "MyBlock") self.foo = 0 - self.register_getter("foo", self.get_foo) - self.register_setter("foo", self.set_foo) + self.register_call("get_foo", self.get_foo) + self.register_call("set_foo", self.set_foo) def work(self, *args): pass @@ -27,10 +27,10 @@ class BlockPropsTest(unittest.TestCase): my_block = MyBlock() self.assertEqual(my_block.foo, 0) - my_block.set("foo", 42) + my_block.x("set_foo", 42) self.assertEqual(my_block.foo, 42) - my_foo = my_block.get("foo") + my_foo = my_block.x("get_foo") self.assertEqual(my_foo, 42) def test_property_errors(self): @@ -38,13 +38,13 @@ class BlockPropsTest(unittest.TestCase): #property does not exist threw = False - try: my_block.get("bar") + try: my_block.x("get_bar") except: threw = True self.assertTrue(threw) #wrong type for property threw = False - try: my_block.set("foo", None) + try: my_block.x("set_foo", None) except: threw = True self.assertTrue(threw) @@ -56,17 +56,17 @@ class BlockPropsTest(unittest.TestCase): tb.adopt_element("my_hier", hb) hb.adopt_element("my_block", my_block) - my_block.set("foo", 42) - self.assertEqual(my_block.get("foo"), 42) + my_block.x("set_foo", 42) + self.assertEqual(my_block.x("get_foo"), 42) my_block0 = tb.locate_block('/my_hier/my_block') - self.assertEqual(my_block0.get("foo"), 42) + self.assertEqual(my_block0.x("get_foo"), 42) my_block1 = hb.locate_block('my_block') - self.assertEqual(my_block1.get("foo"), 42) + self.assertEqual(my_block1.x("get_foo"), 42) my_block2 = hb.locate_block('./../my_hier/my_block') - self.assertEqual(my_block2.get("foo"), 42) + self.assertEqual(my_block2.x("get_foo"), 42) threw = False try: hb.locate_block('../../my_hier/my_block') |