diff options
author | Josh Blum | 2013-07-04 19:46:58 -0700 |
---|---|---|
committer | Josh Blum | 2013-07-04 19:46:58 -0700 |
commit | 1298bcd1e421ccfefafa78c6d33760818902f399 (patch) | |
tree | e4c57bbcf98f9e7502850e5ab481ba7b9d4c11fc /include | |
parent | fbec0c405a1fec4e8ee82d065fdc657cdd333f52 (diff) | |
download | sandhi-1298bcd1e421ccfefafa78c6d33760818902f399.tar.gz sandhi-1298bcd1e421ccfefafa78c6d33760818902f399.tar.bz2 sandhi-1298bcd1e421ccfefafa78c6d33760818902f399.zip |
gras: function registry is more flexible
Diffstat (limited to 'include')
-rw-r--r-- | include/gras/block.hpp | 13 | ||||
-rw-r--r-- | include/gras/detail/block.hpp | 87 |
2 files changed, 100 insertions, 0 deletions
diff --git a/include/gras/block.hpp b/include/gras/block.hpp index f2f1b2b..ba9a64a 100644 --- a/include/gras/block.hpp +++ b/include/gras/block.hpp @@ -166,6 +166,14 @@ struct GRAS_API Block : Element * Provides polymorphic, thread-safe access to block properties. ******************************************************************/ + template <typename ClassType, typename ReturnType> void register_call(const std::string &key, ReturnType(ClassType::*fcn)(void)); + template <typename ClassType, typename ReturnType, typename Arg0> void register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &)); + template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1> void register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &)); + + template <typename ReturnType> ReturnType call(const std::string &key); + template <typename ReturnType, typename Arg0> ReturnType call(const std::string &key, const Arg0 &); + template <typename ReturnType, typename Arg0, typename Arg1> ReturnType call(const std::string &key, const Arg0 &, const Arg1 &); + /*! * Register property getter method into the property interface. * Call register_getter() from the contructor of the block. @@ -430,6 +438,11 @@ struct GRAS_API Block : Element /******************************************************************* * private implementation guts for overloads and template support ******************************************************************/ + + void _register_function(const std::string &, void *); + virtual PMCC _handle_function_access(const std::string &, const std::vector<PMCC> &); + + 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 *); diff --git a/include/gras/detail/block.hpp b/include/gras/detail/block.hpp index 9dccb22..fcd52e1 100644 --- a/include/gras/detail/block.hpp +++ b/include/gras/detail/block.hpp @@ -8,6 +8,93 @@ namespace gras { +struct GRAS_API FunctionRegistry +{ + FunctionRegistry(void); + virtual ~FunctionRegistry(void); + virtual PMCC call(const std::vector<PMCC> &args) = 0; +}; + +template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1> +class FunctionRegistryImpl : public FunctionRegistry +{ +public: + FunctionRegistryImpl( + ClassType *obj, + ReturnType(ClassType::*fcn0)(void), + ReturnType(ClassType::*fcn1)(const Arg0 &) = NULL, + ReturnType(ClassType::*fcn2)(const Arg0 &, const Arg1 &) = NULL + ): + _obj(obj), + _fcn0(fcn0), + _fcn1(fcn1), + _fcn2(fcn2) + {} + virtual ~FunctionRegistryImpl(void){} + + PMCC call(const std::vector<PMCC> &args) + { + if (_fcn0) return PMC_M((_obj->*_fcn0)()); + if (_fcn1) return PMC_M((_obj->*_fcn1)(args[0].safe_as<Arg0>())); + if (_fcn2) return PMC_M((_obj->*_fcn2)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>())); + return PMCC();//should not get here + } + +private: + ClassType *_obj; + ReturnType(ClassType::*_fcn0)(void); + ReturnType(ClassType::*_fcn1)(const Arg0 &); + ReturnType(ClassType::*_fcn2)(const Arg0 &, const Arg1 &); +}; + +template <typename ClassType, typename ReturnType> void Block::register_call(const std::string &key, ReturnType(ClassType::*fcn)(void)) +{ + ClassType *obj = dynamic_cast<ClassType *>(this); + void *fr = new FunctionRegistryImpl<ClassType, ReturnType, int, int>(obj, fcn); + _register_function(key, fr); +} + +template <typename ClassType, typename ReturnType, typename Arg0> void Block::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &)) +{ + ClassType *obj = dynamic_cast<ClassType *>(this); + void *fr = new FunctionRegistryImpl<ClassType, ReturnType, Arg0, int>(obj, NULL, fcn); + _register_function(key, fr); +} + +template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1> void Block::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &)) +{ + ClassType *obj = dynamic_cast<ClassType *>(this); + void *fr = new FunctionRegistryImpl<ClassType, ReturnType, Arg0, Arg1>(obj, NULL, NULL, fcn); + _register_function(key, fr); +} + +template <typename ReturnType> ReturnType Block::call(const std::string &key) +{ + std::vector<PMCC> args; + PMCC r = _handle_function_access(key, args); + return r.safe_as<ReturnType>(); +} + +template <typename ReturnType, typename Arg0> ReturnType Block::call(const std::string &key, const Arg0 &a0) +{ + std::vector<PMCC> args; + args.push_back(PMC_M(a0)); + PMCC r = _handle_function_access(key, args); + return r.safe_as<ReturnType>(); +} + +template <typename ReturnType, typename Arg0, typename Arg1> ReturnType Block::call(const std::string &key, const Arg0 &a0, const Arg1 &a1) +{ + std::vector<PMCC> args; + args.push_back(PMC_M(a0)); + args.push_back(PMC_M(a1)); + PMCC r = _handle_function_access(key, args); + return r.safe_as<ReturnType>(); +} + + + + struct GRAS_API PropertyRegistry { PropertyRegistry(void); |