summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Blum2013-07-05 19:40:26 -0700
committerJosh Blum2013-07-05 19:40:26 -0700
commit66db95c9d57cd0c2a7a9fabe06f7d7d5b3fb8a45 (patch)
tree3a3fcbac80e13971e20ca4c93de51e1c693f4af4
parentfc80d2c0acec4f668b58a05bd5a3a06b0a2a2280 (diff)
downloadsandhi-66db95c9d57cd0c2a7a9fabe06f7d7d5b3fb8a45.tar.gz
sandhi-66db95c9d57cd0c2a7a9fabe06f7d7d5b3fb8a45.tar.bz2
sandhi-66db95c9d57cd0c2a7a9fabe06f7d7d5b3fb8a45.zip
gras: pythonic work on callable interface
-rw-r--r--include/gras/block.hpp4
-rw-r--r--include/gras/block.i10
-rw-r--r--include/gras/callable.hpp2
-rw-r--r--include/gras/detail/callable.hpp70
-rw-r--r--include/gras/element.i9
-rw-r--r--lib/block_props.cpp7
-rw-r--r--lib/callable.cpp2
-rw-r--r--lib/gras_impl/messages.hpp2
-rw-r--r--python/gras/GRAS_PyBlock.i65
-rw-r--r--tests/block_props_test.py22
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')