diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d5c77d..0d9b0aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,10 +14,10 @@ if (MSVC) endif () add_library(mrubypp INTERFACE - mrubypp.h - mrubypp_converters.h - mrubypp_arena_guard.h - mrubypp_bind_class.h) + engine.h + converters.h + arena_guard.h + bind_class.h) include_directories(${CMAKE_CURRENT_LIST_DIR}) diff --git a/mrubypp_arena_guard.h b/arena_guard.h similarity index 54% rename from mrubypp_arena_guard.h rename to arena_guard.h index 15f3588..b18722f 100644 --- a/mrubypp_arena_guard.h +++ b/arena_guard.h @@ -7,15 +7,16 @@ #include +namespace mrubypp { // gc arena -class mrubypp_arena_guard { +class arena_guard { public: - explicit mrubypp_arena_guard(mrb_state *mrb) : mrb(mrb) { + explicit arena_guard(mrb_state *mrb) : mrb(mrb) { ai = mrb_gc_arena_save(mrb); } - mrubypp_arena_guard(mrubypp_arena_guard &&other) = delete; - mrubypp_arena_guard(const mrubypp_arena_guard &other) = delete; - ~mrubypp_arena_guard() { mrb_gc_arena_restore(mrb, ai); } + arena_guard(arena_guard &&other) = delete; + arena_guard(const arena_guard &other) = delete; + ~arena_guard() { mrb_gc_arena_restore(mrb, ai); } // arena_idx [[nodiscard]] int get_ai() const { return ai; } @@ -24,4 +25,5 @@ private: mrb_state *mrb; int ai; }; +} // namespace mrubypp #endif // MRUBYPP_MRUBYPP_UTILS_H diff --git a/mrubypp_bind_class.h b/bind_class.h similarity index 55% rename from mrubypp_bind_class.h rename to bind_class.h index 4de8680..c3ae48d 100644 --- a/mrubypp_bind_class.h +++ b/bind_class.h @@ -1,8 +1,8 @@ #ifndef MRUBYPP_BIND_CLASS #define MRUBYPP_BIND_CLASS -#include "mrubypp_arena_guard.h" -#include "mrubypp_converters.h" +#include "arena_guard.h" +#include "converters.h" #include #include @@ -15,19 +15,17 @@ #include #include -template -std::tuple mrubypp_get_args_helper_impl(mrb_state *mrb, - const mrb_value *argv, - std::index_sequence) { +namespace mrubypp { +template +std::tuple get_args_helper_impl(mrb_state *mrb, const mrb_value *argv, + std::index_sequence) { return std::make_tuple( - mrubypp_converter::type>::from_mrb( - mrb, argv[Is])...); + converter::type>::from_mrb(mrb, argv[Is])...); } -template -std::tuple::type...> -mrubypp_get_args_helper(mrb_state *mrb) { - mrubypp_arena_guard guard(mrb); +template +std::tuple::type...> get_args_helper(mrb_state *mrb) { + arena_guard guard(mrb); auto argc = mrb_get_argc(mrb); auto argv = mrb_get_argv(mrb); @@ -35,12 +33,12 @@ mrubypp_get_args_helper(mrb_state *mrb) { mrb_raise(mrb, E_ARGUMENT_ERROR, "argument count mismatch"); } - return mrubypp_get_args_helper_impl::type...>( - mrb, argv, std::index_sequence_for{}); + return get_args_helper_impl::type...>( + mrb, argv, std::index_sequence_for{}); } -template -struct mrubypp_method_wrapper { +template +struct method_wrapper { using MethodType = Ret (T::*)(MethodArgs...); // TODO, fix memory leak @@ -57,13 +55,12 @@ struct mrubypp_method_wrapper { } static mrb_value wrapper(mrb_state *mrb, mrb_value self) { - auto args = mrubypp_get_args_helper(mrb); + auto args = get_args_helper(mrb); T *instance = static_cast(DATA_PTR(self)); if (!instance) { mrb_raise(mrb, E_RUNTIME_ERROR, "invalid instance"); } - void *method_ptr = mrb_cptr(mrb_cfunc_env_get(mrb, 0)); auto method = ptr_to_method(method_ptr); @@ -73,13 +70,13 @@ struct mrubypp_method_wrapper { } else { Ret result = std::apply(method, std::tuple_cat(std::make_tuple(instance), args)); - return mrubypp_converter::to_mrb(mrb, result); + return converter::to_mrb(mrb, result); } } }; -template -struct mrubypp_const_method_wrapper { +template +struct const_method_wrapper { using MethodType = Ret (T::*)(MethodArgs...) const; // TODO, fix memory leak @@ -95,100 +92,94 @@ struct mrubypp_const_method_wrapper { return method; } - static mrb_value wrapper(mrb_state *mrb, mrb_value self) { - auto args = mrubypp_get_args_helper(mrb); + auto args = get_args_helper(mrb); T *instance = static_cast(DATA_PTR(self)); if (!instance) { mrb_raise(mrb, E_RUNTIME_ERROR, "invalid instance"); } - void *method_ptr = mrb_cptr(mrb_cfunc_env_get(mrb, 0)); auto method = ptr_to_method(method_ptr); if constexpr (std::is_same_v) { std::apply(method, std::tuple_cat(std::make_tuple(instance), args)); + return mrb_nil_value(); } else { Ret result = std::apply(method, std::tuple_cat(std::make_tuple(instance), args)); - return mrubypp_converter::to_mrb(mrb, result); + return converter::to_mrb(mrb, result); } } }; -template -struct mrubypp_function_wrapper { +template +struct function_wrapper { using FunctionType = Ret (*)(FuncArgs...); static mrb_value wrapper(mrb_state *mrb, mrb_value self) { - auto func = (FunctionType) mrb_cptr(mrb_cfunc_env_get(mrb, 0)); - auto args = mrubypp_get_args_helper(mrb); + auto func = (FunctionType)mrb_cptr(mrb_cfunc_env_get(mrb, 0)); + auto args = get_args_helper(mrb); if constexpr (std::is_same_v) { std::apply(func, args); return mrb_nil_value(); } else { Ret result = std::apply(func, args); - return mrubypp_converter::to_mrb(mrb, result); + return converter::to_mrb(mrb, result); } } }; -template -class mrubypp_class_builder; +template class class_builder; -template -struct mrubypp_constructor_wrapper { +template struct constructor_wrapper { static mrb_value wrapper(mrb_state *mrb, mrb_value self) { - auto args = mrubypp_get_args_helper(mrb); + auto args = get_args_helper(mrb); T *instance = std::apply([](Args... args) { return new T(args...); }, args); DATA_PTR(self) = instance; - DATA_TYPE(self) = &mrubypp_class_builder::data_type; + DATA_TYPE(self) = &class_builder::data_type; return self; } }; -template -class mrubypp_class_builder { +template class class_builder { public: static const struct mrb_data_type data_type; - mrubypp_class_builder(mrb_state *mrb, std::string name) - : mrb_(mrb), name_(std::move(name)) { + class_builder(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); mrb_define_method( - mrb_, rclass_, "initialize", - [](mrb_state *mrb, mrb_value self) -> mrb_value { - mrb_raise(mrb, E_NOTIMP_ERROR, - "initialize must be defined explicitly"); - return self; - }, - MRB_ARGS_ANY()); + mrb_, rclass_, "initialize", + [](mrb_state *mrb, mrb_value self) -> mrb_value { + mrb_raise(mrb, E_NOTIMP_ERROR, + "initialize must be defined explicitly"); + return self; + }, + MRB_ARGS_ANY()); } - template - mrubypp_class_builder &def_constructor() { + template class_builder &def_constructor() { mrb_define_method(mrb_, rclass_, "initialize", - &mrubypp_constructor_wrapper::wrapper, + &constructor_wrapper::wrapper, MRB_ARGS_REQ(sizeof...(Args))); return *this; } - template - mrubypp_class_builder &def_method(const std::string &name, - Ret (T::*method)(MethodArgs...)) { + template + class_builder &def_method(const std::string &name, + Ret (T::*method)(MethodArgs...)) { mrb_sym method_sym = mrb_intern_cstr(mrb_, name.c_str()); - using wrap = mrubypp_method_wrapper; + using wrap = method_wrapper; auto ptr = wrap::method_to_ptr(method); mrb_value env[] = { - mrb_cptr_value(mrb_, ptr), + mrb_cptr_value(mrb_, ptr), }; - struct RProc *p = mrb_proc_new_cfunc_with_env( - mrb_, &wrap::wrapper, 1, env); + struct RProc *p = mrb_proc_new_cfunc_with_env(mrb_, &wrap::wrapper, 1, env); mrb_method_t m; MRB_METHOD_FROM_PROC(m, p); mrb_define_method_raw(mrb_, rclass_, method_sym, m); @@ -196,39 +187,34 @@ public: return *this; } - template - mrubypp_class_builder &def_method(const std::string &name, - Ret (T::*method)(MethodArgs...) const) { + template + class_builder &def_method(const std::string &name, + Ret (T::*method)(MethodArgs...) const) { mrb_sym method_sym = mrb_intern_cstr(mrb_, name.c_str()); - using wrap = mrubypp_const_method_wrapper; + using wrap = const_method_wrapper; auto ptr = wrap::method_to_ptr(method); auto obj = mrb_cptr_value(mrb_, ptr); mrb_gc_protect(mrb_, obj); - mrb_value env[] = { - obj - }; + mrb_value env[] = {obj}; - struct RProc *p = mrb_proc_new_cfunc_with_env( - mrb_, &wrap::wrapper, 1, - env); + struct RProc *p = mrb_proc_new_cfunc_with_env(mrb_, &wrap::wrapper, 1, env); mrb_method_t m; MRB_METHOD_FROM_PROC(m, p); mrb_define_method_raw(mrb_, rclass_, method_sym, m); return *this; } - template - mrubypp_class_builder &def_class_method(const std::string &name, - Ret (*func)(FuncArgs...)) { - using wrap = mrubypp_function_wrapper; + template + class_builder &def_class_method(const std::string &name, + Ret (*func)(FuncArgs...)) { + using wrap = function_wrapper; mrb_value env[] = { - mrb_cptr_value(mrb_, (void *) func), + mrb_cptr_value(mrb_, (void *)func), }; mrb_sym func_sym = mrb_intern_cstr(mrb_, name.c_str()); - struct RProc *p = mrb_proc_new_cfunc_with_env( - mrb_, &wrap::wrapper, 1, env); + struct RProc *p = mrb_proc_new_cfunc_with_env(mrb_, &wrap::wrapper, 1, env); mrb_method_t m; MRB_METHOD_FROM_PROC(m, p); @@ -239,17 +225,16 @@ public: } // get set - template - mrubypp_class_builder &def_property(const std::string &name, - Ret (T::*getter)() const, - void (T::*setter)(Ret)) { + template + class_builder &def_property(const std::string &name, Ret (T::*getter)() const, + void (T::*setter)(Ret)) { def_method(name, getter); def_method(name + "=", setter); return *this; } - mrubypp_class_builder &def_native(const std::string &name, mrb_func_t func, - mrb_aspec aspec = MRB_ARGS_ANY()) { + class_builder &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; } @@ -272,15 +257,14 @@ private: } } - mrb_state *mrb_; struct RClass *rclass_; std::string name_; }; -template -const struct mrb_data_type mrubypp_class_builder::data_type = { - typeid(T).name(), mrubypp_class_builder::free_instance +template const struct mrb_data_type class_builder::data_type = { + typeid(T).name(), class_builder::free_instance }; +} // namespace mrubypp #endif diff --git a/mrubypp_converters.h b/converters.h similarity index 75% rename from mrubypp_converters.h rename to converters.h index e884ee8..94deb9b 100644 --- a/mrubypp_converters.h +++ b/converters.h @@ -1,7 +1,7 @@ #ifndef MRUBYPP_STD_CONVERTERS_H #define MRUBYPP_STD_CONVERTERS_H -#include "mrubypp_arena_guard.h" +#include "arena_guard.h" #include #include @@ -9,7 +9,9 @@ #include #include -template struct mrubypp_converter { +namespace mrubypp { + +template struct converter { static mrb_value to_mrb(mrb_state *mrb, const T &var) { static_assert(sizeof(T) == 0, "Specialization required"); return mrb_nil_value(); @@ -20,7 +22,7 @@ template struct mrubypp_converter { } }; -template <> struct mrubypp_converter { +template <> struct converter { static mrb_value to_mrb(mrb_state *mrb, int var) { return mrb_fixnum_value(var); } @@ -29,7 +31,7 @@ template <> struct mrubypp_converter { } }; -template <> struct mrubypp_converter { +template <> struct converter { static mrb_value to_mrb(mrb_state *mrb, unsigned int var) { return mrb_fixnum_value(var); } @@ -38,7 +40,7 @@ template <> struct mrubypp_converter { } }; -template <> struct mrubypp_converter { +template <> struct converter { static mrb_value to_mrb(mrb_state *mrb, float var) { return mrb_float_value(mrb, var); } @@ -47,7 +49,7 @@ template <> struct mrubypp_converter { } }; -template <> struct mrubypp_converter { +template <> struct converter { static mrb_value to_mrb(mrb_state *mrb, double var) { return mrb_float_value(mrb, var); } @@ -56,7 +58,7 @@ template <> struct mrubypp_converter { } }; -template <> struct mrubypp_converter { +template <> struct converter { static mrb_value to_mrb(mrb_state *mrb, const std::string &var) { return mrb_str_new(mrb, var.data(), (mrb_int)var.size()); } @@ -69,34 +71,35 @@ template <> struct mrubypp_converter { } }; -template <> struct mrubypp_converter { +template <> struct converter { static mrb_value to_mrb(mrb_state *mrb, const char *var) { return mrb_str_new(mrb, var, (mrb_int)strlen(var)); } }; -template struct mrubypp_converter> { +template struct converter> { static mrb_value to_mrb(mrb_state *mrb, const std::vector &var) { mrb_value ary = mrb_ary_new_capa(mrb, static_cast(var.size())); for (const T &el : var) { - mrubypp_arena_guard guard(mrb); - mrb_ary_push(mrb, ary, mrubypp_converter::to_mrb(mrb, el)); + arena_guard guard(mrb); + mrb_ary_push(mrb, ary, converter::to_mrb(mrb, el)); } return ary; } static std::vector from_mrb(mrb_state *mrb, mrb_value value) { - mrubypp_arena_guard guard(mrb); + arena_guard guard(mrb); std::vector result; if (mrb_array_p(value)) { int len = RARRAY_LEN(value); for (int i = 0; i < len; ++i) { - result.append( - mrubypp_converter::from_mrb(mrb, mrb_ary_ref(mrb, value, i))); + result.append(converter::from_mrb(mrb, mrb_ary_ref(mrb, value, i))); } } return result; } }; +} // namespace mrubypp + #endif // MRUBYPP_STD_CONVERTERS_H diff --git a/mrubypp.h b/engine.h similarity index 58% rename from mrubypp.h rename to engine.h index 8060057..fcedeb2 100644 --- a/mrubypp.h +++ b/engine.h @@ -1,9 +1,9 @@ #ifndef MRUBYPP_H #define MRUBYPP_H -#include "mrubypp_arena_guard.h" -#include "mrubypp_bind_class.h" -#include "mrubypp_converters.h" +#include "arena_guard.h" +#include "bind_class.h" +#include "converters.h" #include #include @@ -11,10 +11,11 @@ #include -class mrubypp { +namespace mrubypp { +class engine { public: - mrubypp() { mrb_ = mrb_open(); } - ~mrubypp() { mrb_close(mrb_); } + engine() { mrb_ = mrb_open(); } + ~engine() { mrb_close(mrb_); } void load(const std::string &str) { if (!mrb_) return; @@ -22,25 +23,25 @@ public: } template T call(const std::string &funcName) { - mrubypp_arena_guard guard(mrb_); + arena_guard guard(mrb_); mrb_value result = mrb_funcall(mrb_, mrb_top_self(mrb_), funcName.data(), 0); - return mrubypp_converter::from_mrb(mrb_, result); + return converter::from_mrb(mrb_, result); } template T call(const std::string &funcName, Args... args) { - mrubypp_arena_guard guard(mrb_); - mrb_value argv[] = {mrubypp_converter::to_mrb(mrb_, 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 mrubypp_converter::from_mrb(mrb_, result); + return converter::from_mrb(mrb_, result); } template - mrubypp_class_builder class_builder(const std::string &class_name) { - return mrubypp_class_builder(mrb_, class_name); + class_builder class_builder(const std::string &class_name) { + return class_builder(mrb_, class_name); } [[nodiscard]] mrb_state *get_mrb() const { return mrb_; } @@ -48,5 +49,6 @@ public: private: mrb_state *mrb_; }; +} // namespace mrubypp #endif // MRUBYPP_H diff --git a/test/test_class.cpp b/test/test_class.cpp index 4e89f9d..584b210 100644 --- a/test/test_class.cpp +++ b/test/test_class.cpp @@ -4,12 +4,11 @@ #include -#include "mrubypp.h" +#include "engine.h" class Point { public: - Point(int x, int y) : x_(x), y_(y) { - } + Point(int x, int y) : x_(x), y_(y) {} void set_values(int x, int y) { x_ = x; @@ -18,15 +17,11 @@ public: int get_x() const { return x_; } - void set_x(int x) { - x_ = x; - } + void set_x(int x) { x_ = x; } int get_y() const { return y_; } - void set_y(int y) { - y_ = y; - } + void set_y(int y) { y_ = y; } void add(const Point &other) { this->x_ += other.x_; @@ -48,12 +43,11 @@ static mrb_value point_native_div(mrb_state *mrb, mrb_value self) { 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)); + mrb_data_object_alloc(mrb, mrb->object_class, new Point(var), + &mrubypp_class_builder::data_type)); return obj; } @@ -67,7 +61,7 @@ struct mrubypp_converter { }; TEST_CASE("Point", "[class]") { - mrubypp engine; + engine engine; engine.class_builder("Point") .def_constructor() .def_method("add", &Point::add) diff --git a/test/test_engine.cpp b/test/test_engine.cpp index ca71390..069fcae 100644 --- a/test/test_engine.cpp +++ b/test/test_engine.cpp @@ -7,10 +7,10 @@ #include -#include "mrubypp.h" +#include "engine.h" TEST_CASE("none args call", "[engine]") { - mrubypp engine; + engine engine; engine.load(R"( def get_1() 1 @@ -22,7 +22,7 @@ TEST_CASE("none args call", "[engine]") { } TEST_CASE("args call", "[engine]") { - mrubypp engine; + engine engine; engine.load(R"( def sort_and_get_first(a) a.sort! @@ -36,7 +36,7 @@ TEST_CASE("args call", "[engine]") { } TEST_CASE("call benchmark", "[!benchmark]") { - mrubypp engine; + engine engine; engine.load(R"( def get_same(a) return a