#ifndef __scripting_function_hpp__ #define __scripting_function_hpp__ #include "scripting_object.hpp" #include #include #include #include #include // handle_return implementations template struct Handle_Return { Scripting_Object operator()(const boost::function &f) { return Scripting_Object(f()); } }; template struct Handle_Return { Scripting_Object operator()(const boost::function &f) { return Scripting_Object(boost::ref(f())); } }; template<> struct Handle_Return { Scripting_Object operator()(const boost::function &f) { f(); return Scripting_Object(); } }; // call_func implementations todo: handle reference return types // to be made variadic template Scripting_Object call_func(const boost::function &f, const std::vector ¶ms) { if (params.size() != 2) { throw std::range_error("Incorrect number of parameters"); } else { return Handle_Return()(boost::bind(f, Cast_Helper()(params[0]), Cast_Helper()(params[1]))); } } template Scripting_Object call_func(const boost::function &f, const std::vector ¶ms) { if (params.size() != 1) { throw std::range_error("Incorrect number of parameters"); } else { return Handle_Return()(boost::bind(f, Cast_Helper()(params[0]))); } } template Scripting_Object call_func(const boost::function &f, const std::vector ¶ms) { if (params.size() != 0) { throw std::range_error("Incorrect number of parameters"); } else { return Handle_Return()(f); } } class Function_Handler { public: virtual Scripting_Object operator()(const std::vector ¶ms) = 0; }; template class Function_Handler_Impl : public Function_Handler { public: Function_Handler_Impl(const Func &f) : m_f(f) { } virtual Scripting_Object operator()(const std::vector ¶ms) { return call_func(m_f, params); } private: Func m_f; }; std::vector build_param_list(const Scripting_Object &so) { std::vector sos; sos.push_back(so); return sos; } std::vector build_param_list(const Scripting_Object &so1, const Scripting_Object &so2) { std::vector sos; sos.push_back(so1); sos.push_back(so2); return sos; } std::vector build_param_list(const Scripting_Object &so1, const Scripting_Object &so2, const Scripting_Object &so3) { std::vector sos; sos.push_back(so1); sos.push_back(so2); sos.push_back(so3); return sos; } #endif