diff --git a/boxedcpp/boxedcpp.hpp b/boxedcpp/boxedcpp.hpp index 7e63f9bd..4c0fa41f 100644 --- a/boxedcpp/boxedcpp.hpp +++ b/boxedcpp/boxedcpp.hpp @@ -1,5 +1,5 @@ -#ifndef __scripting_system_hpp__ -#define __scripting_system_hpp__ +#ifndef __boxedcpp_system_hpp__ +#define __boxedcpp_system_hpp__ #include #include @@ -9,12 +9,16 @@ #include #include "boxed_value.hpp" +#include "type_info.hpp" #include "proxy_functions.hpp" #include "proxy_constructors.hpp" -class Scripting_System +class BoxedCPP_System { public: + typedef std::multimap > Function_Map; + typedef std::map Type_Name_Map; + template void register_function(const Function &func, const std::string &name) { @@ -41,24 +45,89 @@ class Scripting_System template void register_type(const std::string &name) { - m_types.insert(std::make_pair(name, &typeid(Type))); + m_types.insert(std::make_pair(name, Get_Type_Info()())); } - boost::shared_ptr get_function(const std::string &t_name) + std::vector get_types() const { - std::map >::const_iterator itr = m_functions.find(t_name); - if (itr != m_functions.end()) - { - return itr->second; - } else { - throw std::range_error("Function not known: " + t_name); - } + return std::vector(m_types.begin(), m_types.end()); + } + + std::vector get_function(const std::string &t_name) const + { + std::pair range + = m_functions.equal_range(t_name); + + return std::vector(range.first, range.second); + } + + std::vector get_functions() const + { + return std::vector(m_functions.begin(), m_functions.end()); } private: std::map m_objects; - std::map m_types; - std::map > m_functions; + + Function_Map m_functions; + Type_Name_Map m_types; }; +void dump_type(const Type_Info &type) +{ + std::cout << type.m_bare_type_info->name(); +} + +void dump_function(const BoxedCPP_System::Function_Map::value_type &f) +{ + std::vector params = f.second->get_param_types(); + + dump_type(params.front()); + std::cout << " " << f.first << "("; + + for (std::vector::const_iterator itr = params.begin() + 1; + itr != params.end(); + ++itr) + { + dump_type(*itr); + std::cout << ", "; + } + + std::cout << ")" << std::endl; +} + +void dump_system(const BoxedCPP_System &s) +{ + std::cout << "Registered Types: " << std::endl; + std::vector types = s.get_types(); + for (std::vector::const_iterator itr = types.begin(); + itr != types.end(); + ++itr) + { + std::cout << itr->first << ": "; + dump_type(itr->second); + std::cout << std::endl; + } + + + std::cout << std::endl; std::vector funcs = s.get_functions(); + + std::cout << "Functions: " << std::endl; + for (std::vector::const_iterator itr = funcs.begin(); + itr != funcs.end(); + ++itr) + { + dump_function(*itr); + } + std::cout << std::endl; +} + +void bootstrap(BoxedCPP_System &s) +{ + s.register_type("void"); + s.register_type("double"); + s.register_type("int"); + s.register_type("string"); +} + #endif diff --git a/boxedcpp/proxy_functions.hpp b/boxedcpp/proxy_functions.hpp index bcc1ebd4..20eb6954 100644 --- a/boxedcpp/proxy_functions.hpp +++ b/boxedcpp/proxy_functions.hpp @@ -67,7 +67,6 @@ Boxed_Value call_func(const boost::function &f, const std::vector objects; - }; @@ -128,7 +126,22 @@ class Proxy_Function_Impl : public Proxy_Function Func m_f; }; +Boxed_Value dispatch(const std::vector > > &funcs, + const std::vector &plist) +{ + for (std::vector > >::const_iterator itr = funcs.begin(); + itr != funcs.end(); + ++itr) + { + try { + return (*itr->second)(plist); + } catch (const std::bad_cast &) { + //try again + } + } + throw std::runtime_error("No mathcing function to dispatch to"); +} # endif #else diff --git a/boxedcpp/test.cpp b/boxedcpp/test.cpp index 0745b519..d96bd6b1 100644 --- a/boxedcpp/test.cpp +++ b/boxedcpp/test.cpp @@ -55,7 +55,9 @@ void print() //Test main int main() { - Scripting_System ss; + BoxedCPP_System ss; + bootstrap(ss); + ss.register_type("Test"); ss.register_function(boost::function(&Test::method), "method"); ss.register_function(boost::function(&testprint), "print"); @@ -69,33 +71,37 @@ int main() ss.add_object("d", boost::shared_ptr(new double(10.2))); ss.add_object("str", std::string("Hello World")); + + dump_system(ss); + + std::vector sos; sos.push_back(ss.get_object("testobj")); sos.push_back(ss.get_object("d")); - boost::shared_ptr method1(ss.get_function("method")); + boost::shared_ptr method1(ss.get_function("method").front().second); (*method1)(sos); (*method1)(sos); Boxed_Value o = (*method1)(sos); - (*ss.get_function("print"))(Param_List_Builder() << ss.get_object("str")); + dispatch(ss.get_function("print"), Param_List_Builder() << ss.get_object("str")); //Add new dynamically created object from registered "Test" constructor - ss.add_object("testobj2", (*ss.get_function("Test"))(Param_List_Builder() << std::string("Yo"))); + ss.add_object("testobj2", dispatch(ss.get_function("Test"), Param_List_Builder() << std::string("Yo"))); std::cout << Cast_Helper()(o) << std::endl; - (*ss.get_function("voidfunc"))(std::vector()); + dispatch(ss.get_function("voidfunc"), Param_List_Builder()); std::vector sos3; sos3.push_back(ss.get_object("testobj2")); - (*ss.get_function("show_message"))(sos3); + dispatch(ss.get_function("show_message"), sos3); - Boxed_Value stringref = (*ss.get_function("get_message"))(sos3); + Boxed_Value stringref = dispatch(ss.get_function("get_message"), sos3); std::string &sr = Cast_Helper()(stringref); sr = "Bob Updated The message"; - (*ss.get_function("show_message"))(sos3); + dispatch(ss.get_function("show_message"), sos3); } diff --git a/boxedcpp/type_info.hpp b/boxedcpp/type_info.hpp index 16892240..a196da54 100644 --- a/boxedcpp/type_info.hpp +++ b/boxedcpp/type_info.hpp @@ -29,7 +29,30 @@ struct Get_Type_Info boost::is_void::value, &typeid(T), &typeid(typename boost::remove_const::type>::type>::type)); + } +}; +template +struct Get_Type_Info > +{ + Type_Info operator()() + { + return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, + boost::is_void::value, + &typeid(boost::shared_ptr ), + &typeid(typename boost::remove_const::type>::type>::type)); + } +}; + +template +struct Get_Type_Info > +{ + Type_Info operator()() + { + return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, + boost::is_void::value, + &typeid(boost::reference_wrapper ), + &typeid(typename boost::remove_const::type>::type>::type)); } };