From e38f5850d37aaea0ab935429e5585f396726f078 Mon Sep 17 00:00:00 2001 From: zekexiao Date: Wed, 22 Oct 2025 23:30:54 +0800 Subject: [PATCH] better call template & move to include/murbypp dir & fix test namepsace --- CMakeLists.txt | 11 ++-- engine.h | 54 ----------------- .../mrubypp/arena_guard.h | 0 bind_class.h => include/mrubypp/bind_class.h | 40 ++++++------- converters.h => include/mrubypp/converters.h | 0 include/mrubypp/engine.h | 60 +++++++++++++++++++ test/test_class.cpp | 17 +++--- test/test_engine.cpp | 20 +++++-- 8 files changed, 108 insertions(+), 94 deletions(-) delete mode 100644 engine.h rename arena_guard.h => include/mrubypp/arena_guard.h (100%) rename bind_class.h => include/mrubypp/bind_class.h (86%) rename converters.h => include/mrubypp/converters.h (100%) create mode 100644 include/mrubypp/engine.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d9b0aa..2326dd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,13 +14,12 @@ if (MSVC) endif () add_library(mrubypp INTERFACE - engine.h - converters.h - arena_guard.h - bind_class.h) + include/mrubypp/engine.h + include/mrubypp/converters.h + include/mrubypp/arena_guard.h + include/mrubypp/bind_class.h) - -include_directories(${CMAKE_CURRENT_LIST_DIR}) +target_include_directories(mrubypp INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) if (${MRUBYPP_BUILD_TEST}) if (NOT DEFINED mruby_ROOT) diff --git a/engine.h b/engine.h deleted file mode 100644 index fcedeb2..0000000 --- a/engine.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef MRUBYPP_H -#define MRUBYPP_H - -#include "arena_guard.h" -#include "bind_class.h" -#include "converters.h" - -#include -#include -#include - -#include - -namespace mrubypp { -class engine { -public: - engine() { mrb_ = mrb_open(); } - ~engine() { mrb_close(mrb_); } - void load(const std::string &str) { - if (!mrb_) - return; - mrb_load_string(mrb_, str.c_str()); - } - - template T call(const std::string &funcName) { - arena_guard guard(mrb_); - mrb_value result = - mrb_funcall(mrb_, mrb_top_self(mrb_), funcName.data(), 0); - return converter::from_mrb(mrb_, result); - } - - template - T call(const std::string &funcName, Args... args) { - arena_guard guard(mrb_); - mrb_value argv[] = {converter::to_mrb(mrb_, args)...}; - mrb_sym sym = mrb_intern_cstr(mrb_, funcName.data()); - mrb_value result = - mrb_funcall_argv(mrb_, mrb_top_self(mrb_), sym, sizeof...(Args), argv); - return converter::from_mrb(mrb_, result); - } - - template - class_builder class_builder(const std::string &class_name) { - return class_builder(mrb_, class_name); - } - - [[nodiscard]] mrb_state *get_mrb() const { return mrb_; } - -private: - mrb_state *mrb_; -}; -} // namespace mrubypp - -#endif // MRUBYPP_H diff --git a/arena_guard.h b/include/mrubypp/arena_guard.h similarity index 100% rename from arena_guard.h rename to include/mrubypp/arena_guard.h diff --git a/bind_class.h b/include/mrubypp/bind_class.h similarity index 86% rename from bind_class.h rename to include/mrubypp/bind_class.h index c3ae48d..0a27a97 100644 --- a/bind_class.h +++ b/include/mrubypp/bind_class.h @@ -4,12 +4,8 @@ #include "arena_guard.h" #include "converters.h" -#include -#include #include -#include -#include -#include +#include #include #include @@ -129,7 +125,7 @@ struct function_wrapper { } }; -template class class_builder; +template class bind_class; template struct constructor_wrapper { static mrb_value wrapper(mrb_state *mrb, mrb_value self) { @@ -137,16 +133,16 @@ template struct constructor_wrapper { T *instance = std::apply([](Args... args) { return new T(args...); }, args); DATA_PTR(self) = instance; - DATA_TYPE(self) = &class_builder::data_type; + DATA_TYPE(self) = &bind_class::data_type; return self; } }; -template class class_builder { +template class bind_class { public: static const struct mrb_data_type data_type; - class_builder(mrb_state *mrb, std::string name) + bind_class(mrb_state *mrb, std::string name) : mrb_(mrb), name_(std::move(name)) { rclass_ = mrb_define_class(mrb_, name_.c_str(), mrb_->object_class); MRB_SET_INSTANCE_TT(rclass_, MRB_TT_DATA); @@ -161,7 +157,7 @@ public: MRB_ARGS_ANY()); } - template class_builder &def_constructor() { + template bind_class &def_constructor() { mrb_define_method(mrb_, rclass_, "initialize", &constructor_wrapper::wrapper, MRB_ARGS_REQ(sizeof...(Args))); @@ -169,8 +165,8 @@ public: } template - class_builder &def_method(const std::string &name, - Ret (T::*method)(MethodArgs...)) { + bind_class &def_method(const std::string &name, + Ret (T::*method)(MethodArgs...)) { mrb_sym method_sym = mrb_intern_cstr(mrb_, name.c_str()); using wrap = method_wrapper; @@ -188,8 +184,8 @@ public: } template - class_builder &def_method(const std::string &name, - Ret (T::*method)(MethodArgs...) const) { + bind_class &def_method(const std::string &name, + Ret (T::*method)(MethodArgs...) const) { mrb_sym method_sym = mrb_intern_cstr(mrb_, name.c_str()); using wrap = const_method_wrapper; @@ -206,8 +202,8 @@ public: } template - class_builder &def_class_method(const std::string &name, - Ret (*func)(FuncArgs...)) { + bind_class &def_class_method(const std::string &name, + Ret (*func)(FuncArgs...)) { using wrap = function_wrapper; mrb_value env[] = { mrb_cptr_value(mrb_, (void *)func), @@ -226,15 +222,15 @@ public: // get set template - class_builder &def_property(const std::string &name, Ret (T::*getter)() const, - void (T::*setter)(Ret)) { + bind_class &def_property(const std::string &name, Ret (T::*getter)() const, + void (T::*setter)(Ret)) { def_method(name, getter); def_method(name + "=", setter); return *this; } - class_builder &def_native(const std::string &name, mrb_func_t func, - mrb_aspec aspec = MRB_ARGS_ANY()) { + bind_class &def_native(const std::string &name, mrb_func_t func, + mrb_aspec aspec = MRB_ARGS_ANY()) { mrb_define_method(mrb_, rclass_, name.c_str(), func, aspec); return *this; } @@ -262,8 +258,8 @@ private: std::string name_; }; -template const struct mrb_data_type class_builder::data_type = { - typeid(T).name(), class_builder::free_instance +template const struct mrb_data_type bind_class::data_type = { + typeid(T).name(), bind_class::free_instance }; } // namespace mrubypp diff --git a/converters.h b/include/mrubypp/converters.h similarity index 100% rename from converters.h rename to include/mrubypp/converters.h diff --git a/include/mrubypp/engine.h b/include/mrubypp/engine.h new file mode 100644 index 0000000..a42f9cd --- /dev/null +++ b/include/mrubypp/engine.h @@ -0,0 +1,60 @@ +#ifndef MRUBYPP_H +#define MRUBYPP_H + +#include "arena_guard.h" +#include "converters.h" + +#include +#include +#include + +#include + +namespace mrubypp { +class engine { +public: + engine() { mrb_ = mrb_open(); } + ~engine() { mrb_close(mrb_); } + void load(const std::string &str) { + if (!mrb_) + return; + mrb_load_string(mrb_, str.c_str()); + } + + template + typename std::enable_if::value, T>::type + call(const std::string &funcName, Args... args) { + arena_guard guard(mrb_); + if constexpr (sizeof...(Args) > 0) { + mrb_value argv[] = {converter::to_mrb(mrb_, args)...}; + mrb_sym sym = mrb_intern_cstr(mrb_, funcName.data()); + mrb_value result = mrb_funcall_argv(mrb_, mrb_top_self(mrb_), sym, + sizeof...(Args), argv); + return converter::from_mrb(mrb_, result); + } + mrb_value result = + mrb_funcall(mrb_, mrb_top_self(mrb_), funcName.data(), 0); + return converter::from_mrb(mrb_, result); + } + + template + typename std::enable_if::value, T>::type + call(const std::string &funcName, Args... args) { + if constexpr (sizeof...(Args) > 0) { + arena_guard guard(mrb_); + mrb_value argv[] = {converter::to_mrb(mrb_, args)...}; + mrb_sym sym = mrb_intern_cstr(mrb_, funcName.data()); + mrb_funcall_argv(mrb_, mrb_top_self(mrb_), sym, sizeof...(Args), argv); + } else { + mrb_funcall(mrb_, mrb_top_self(mrb_), funcName.data(), 0); + } + } + + [[nodiscard]] mrb_state *get_mrb() const { return mrb_; } + +private: + mrb_state *mrb_; +}; +} // namespace mrubypp + +#endif // MRUBYPP_H diff --git a/test/test_class.cpp b/test/test_class.cpp index 584b210..529890b 100644 --- a/test/test_class.cpp +++ b/test/test_class.cpp @@ -4,7 +4,8 @@ #include -#include "engine.h" +#include +#include class Point { public: @@ -36,18 +37,18 @@ private: }; static mrb_value point_native_div(mrb_state *mrb, mrb_value self) { - auto point = mrubypp_class_builder::get_this(mrb, self); - auto divisor = mrubypp_converter::from_mrb(mrb, mrb_get_arg1(mrb)); + auto point = mrubypp::bind_class::get_this(mrb, self); + auto divisor = mrubypp::converter::from_mrb(mrb, mrb_get_arg1(mrb)); point->set_x(point->get_x() / divisor); point->set_y(point->get_y() / divisor); return self; } -template <> struct mrubypp_converter { +template <> struct mrubypp::converter { static mrb_value to_mrb(mrb_state *mrb, const Point &var) { mrb_value obj = mrb_obj_value( mrb_data_object_alloc(mrb, mrb->object_class, new Point(var), - &mrubypp_class_builder::data_type)); + &mrubypp::bind_class::data_type)); return obj; } @@ -60,9 +61,9 @@ template <> struct mrubypp_converter { } }; -TEST_CASE("Point", "[class]") { - engine engine; - engine.class_builder("Point") +TEST_CASE("bind_class", "[class]") { + mrubypp::engine engine; + mrubypp::bind_class(engine.get_mrb(), "Point") .def_constructor() .def_method("add", &Point::add) .def_class_method("none", &Point::none) diff --git a/test/test_engine.cpp b/test/test_engine.cpp index 069fcae..01c8cce 100644 --- a/test/test_engine.cpp +++ b/test/test_engine.cpp @@ -7,10 +7,10 @@ #include -#include "engine.h" +#include TEST_CASE("none args call", "[engine]") { - engine engine; + mrubypp::engine engine; engine.load(R"( def get_1() 1 @@ -22,7 +22,7 @@ TEST_CASE("none args call", "[engine]") { } TEST_CASE("args call", "[engine]") { - engine engine; + mrubypp::engine engine; engine.load(R"( def sort_and_get_first(a) a.sort! @@ -35,8 +35,20 @@ TEST_CASE("args call", "[engine]") { REQUIRE(b == 1); } +TEST_CASE("void call", "[engine]") { + mrubypp::engine engine; + engine.load(R"( + def no_return_puts(a) + puts a + end + )"); + + std::vector a{3, 1, 2}; + engine.call("no_return_puts", a); +} + TEST_CASE("call benchmark", "[!benchmark]") { - engine engine; + mrubypp::engine engine; engine.load(R"( def get_same(a) return a