diff options
Diffstat (limited to 'include/gras')
-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); |