use namespace & not fix return
This commit is contained in:
@@ -14,10 +14,10 @@ if (MSVC)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_library(mrubypp INTERFACE
|
add_library(mrubypp INTERFACE
|
||||||
mrubypp.h
|
engine.h
|
||||||
mrubypp_converters.h
|
converters.h
|
||||||
mrubypp_arena_guard.h
|
arena_guard.h
|
||||||
mrubypp_bind_class.h)
|
bind_class.h)
|
||||||
|
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_LIST_DIR})
|
include_directories(${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|||||||
@@ -7,15 +7,16 @@
|
|||||||
|
|
||||||
#include <mruby.h>
|
#include <mruby.h>
|
||||||
|
|
||||||
|
namespace mrubypp {
|
||||||
// gc arena
|
// gc arena
|
||||||
class mrubypp_arena_guard {
|
class arena_guard {
|
||||||
public:
|
public:
|
||||||
explicit mrubypp_arena_guard(mrb_state *mrb) : mrb(mrb) {
|
explicit arena_guard(mrb_state *mrb) : mrb(mrb) {
|
||||||
ai = mrb_gc_arena_save(mrb);
|
ai = mrb_gc_arena_save(mrb);
|
||||||
}
|
}
|
||||||
mrubypp_arena_guard(mrubypp_arena_guard &&other) = delete;
|
arena_guard(arena_guard &&other) = delete;
|
||||||
mrubypp_arena_guard(const mrubypp_arena_guard &other) = delete;
|
arena_guard(const arena_guard &other) = delete;
|
||||||
~mrubypp_arena_guard() { mrb_gc_arena_restore(mrb, ai); }
|
~arena_guard() { mrb_gc_arena_restore(mrb, ai); }
|
||||||
|
|
||||||
// arena_idx
|
// arena_idx
|
||||||
[[nodiscard]] int get_ai() const { return ai; }
|
[[nodiscard]] int get_ai() const { return ai; }
|
||||||
@@ -24,4 +25,5 @@ private:
|
|||||||
mrb_state *mrb;
|
mrb_state *mrb;
|
||||||
int ai;
|
int ai;
|
||||||
};
|
};
|
||||||
|
} // namespace mrubypp
|
||||||
#endif // MRUBYPP_MRUBYPP_UTILS_H
|
#endif // MRUBYPP_MRUBYPP_UTILS_H
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#ifndef MRUBYPP_BIND_CLASS
|
#ifndef MRUBYPP_BIND_CLASS
|
||||||
#define MRUBYPP_BIND_CLASS
|
#define MRUBYPP_BIND_CLASS
|
||||||
|
|
||||||
#include "mrubypp_arena_guard.h"
|
#include "arena_guard.h"
|
||||||
#include "mrubypp_converters.h"
|
#include "converters.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -15,19 +15,17 @@
|
|||||||
#include <mruby/data.h>
|
#include <mruby/data.h>
|
||||||
#include <mruby/proc.h>
|
#include <mruby/proc.h>
|
||||||
|
|
||||||
|
namespace mrubypp {
|
||||||
template <typename... Args, size_t... Is>
|
template <typename... Args, size_t... Is>
|
||||||
std::tuple<Args...> mrubypp_get_args_helper_impl(mrb_state *mrb,
|
std::tuple<Args...> get_args_helper_impl(mrb_state *mrb, const mrb_value *argv,
|
||||||
const mrb_value *argv,
|
|
||||||
std::index_sequence<Is...>) {
|
std::index_sequence<Is...>) {
|
||||||
return std::make_tuple(
|
return std::make_tuple(
|
||||||
mrubypp_converter<typename std::decay<Args>::type>::from_mrb(
|
converter<typename std::decay<Args>::type>::from_mrb(mrb, argv[Is])...);
|
||||||
mrb, argv[Is])...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
std::tuple<typename std::decay<Args>::type...>
|
std::tuple<typename std::decay<Args>::type...> get_args_helper(mrb_state *mrb) {
|
||||||
mrubypp_get_args_helper(mrb_state *mrb) {
|
arena_guard guard(mrb);
|
||||||
mrubypp_arena_guard guard(mrb);
|
|
||||||
auto argc = mrb_get_argc(mrb);
|
auto argc = mrb_get_argc(mrb);
|
||||||
auto argv = mrb_get_argv(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");
|
mrb_raise(mrb, E_ARGUMENT_ERROR, "argument count mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
return mrubypp_get_args_helper_impl<typename std::decay<Args>::type...>(
|
return get_args_helper_impl<typename std::decay<Args>::type...>(
|
||||||
mrb, argv, std::index_sequence_for<Args...>{});
|
mrb, argv, std::index_sequence_for<Args...>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Ret, typename... MethodArgs>
|
template <typename T, typename Ret, typename... MethodArgs>
|
||||||
struct mrubypp_method_wrapper {
|
struct method_wrapper {
|
||||||
using MethodType = Ret (T::*)(MethodArgs...);
|
using MethodType = Ret (T::*)(MethodArgs...);
|
||||||
|
|
||||||
// TODO, fix memory leak
|
// TODO, fix memory leak
|
||||||
@@ -57,13 +55,12 @@ struct mrubypp_method_wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static mrb_value wrapper(mrb_state *mrb, mrb_value self) {
|
static mrb_value wrapper(mrb_state *mrb, mrb_value self) {
|
||||||
auto args = mrubypp_get_args_helper<MethodArgs...>(mrb);
|
auto args = get_args_helper<MethodArgs...>(mrb);
|
||||||
T *instance = static_cast<T *>(DATA_PTR(self));
|
T *instance = static_cast<T *>(DATA_PTR(self));
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
mrb_raise(mrb, E_RUNTIME_ERROR, "invalid instance");
|
mrb_raise(mrb, E_RUNTIME_ERROR, "invalid instance");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *method_ptr = mrb_cptr(mrb_cfunc_env_get(mrb, 0));
|
void *method_ptr = mrb_cptr(mrb_cfunc_env_get(mrb, 0));
|
||||||
auto method = ptr_to_method(method_ptr);
|
auto method = ptr_to_method(method_ptr);
|
||||||
|
|
||||||
@@ -73,13 +70,13 @@ struct mrubypp_method_wrapper {
|
|||||||
} else {
|
} else {
|
||||||
Ret result =
|
Ret result =
|
||||||
std::apply(method, std::tuple_cat(std::make_tuple(instance), args));
|
std::apply(method, std::tuple_cat(std::make_tuple(instance), args));
|
||||||
return mrubypp_converter<Ret>::to_mrb(mrb, result);
|
return converter<Ret>::to_mrb(mrb, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Ret, typename... MethodArgs>
|
template <typename T, typename Ret, typename... MethodArgs>
|
||||||
struct mrubypp_const_method_wrapper {
|
struct const_method_wrapper {
|
||||||
using MethodType = Ret (T::*)(MethodArgs...) const;
|
using MethodType = Ret (T::*)(MethodArgs...) const;
|
||||||
|
|
||||||
// TODO, fix memory leak
|
// TODO, fix memory leak
|
||||||
@@ -95,65 +92,61 @@ struct mrubypp_const_method_wrapper {
|
|||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static mrb_value wrapper(mrb_state *mrb, mrb_value self) {
|
static mrb_value wrapper(mrb_state *mrb, mrb_value self) {
|
||||||
auto args = mrubypp_get_args_helper<MethodArgs...>(mrb);
|
auto args = get_args_helper<MethodArgs...>(mrb);
|
||||||
T *instance = static_cast<T *>(DATA_PTR(self));
|
T *instance = static_cast<T *>(DATA_PTR(self));
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
mrb_raise(mrb, E_RUNTIME_ERROR, "invalid instance");
|
mrb_raise(mrb, E_RUNTIME_ERROR, "invalid instance");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *method_ptr = mrb_cptr(mrb_cfunc_env_get(mrb, 0));
|
void *method_ptr = mrb_cptr(mrb_cfunc_env_get(mrb, 0));
|
||||||
auto method = ptr_to_method(method_ptr);
|
auto method = ptr_to_method(method_ptr);
|
||||||
if constexpr (std::is_same_v<Ret, void>) {
|
if constexpr (std::is_same_v<Ret, void>) {
|
||||||
std::apply(method, std::tuple_cat(std::make_tuple(instance), args));
|
std::apply(method, std::tuple_cat(std::make_tuple(instance), args));
|
||||||
|
return mrb_nil_value();
|
||||||
} else {
|
} else {
|
||||||
Ret result =
|
Ret result =
|
||||||
std::apply(method, std::tuple_cat(std::make_tuple(instance), args));
|
std::apply(method, std::tuple_cat(std::make_tuple(instance), args));
|
||||||
return mrubypp_converter<Ret>::to_mrb(mrb, result);
|
return converter<Ret>::to_mrb(mrb, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Ret, typename... FuncArgs>
|
template <typename T, typename Ret, typename... FuncArgs>
|
||||||
struct mrubypp_function_wrapper {
|
struct function_wrapper {
|
||||||
using FunctionType = Ret (*)(FuncArgs...);
|
using FunctionType = Ret (*)(FuncArgs...);
|
||||||
|
|
||||||
static mrb_value wrapper(mrb_state *mrb, mrb_value self) {
|
static mrb_value wrapper(mrb_state *mrb, mrb_value self) {
|
||||||
auto func = (FunctionType)mrb_cptr(mrb_cfunc_env_get(mrb, 0));
|
auto func = (FunctionType)mrb_cptr(mrb_cfunc_env_get(mrb, 0));
|
||||||
auto args = mrubypp_get_args_helper<FuncArgs...>(mrb);
|
auto args = get_args_helper<FuncArgs...>(mrb);
|
||||||
if constexpr (std::is_same_v<Ret, void>) {
|
if constexpr (std::is_same_v<Ret, void>) {
|
||||||
std::apply(func, args);
|
std::apply(func, args);
|
||||||
return mrb_nil_value();
|
return mrb_nil_value();
|
||||||
} else {
|
} else {
|
||||||
Ret result = std::apply(func, args);
|
Ret result = std::apply(func, args);
|
||||||
return mrubypp_converter<Ret>::to_mrb(mrb, result);
|
return converter<Ret>::to_mrb(mrb, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T> class class_builder;
|
||||||
class mrubypp_class_builder;
|
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
template <typename T, typename... Args> struct constructor_wrapper {
|
||||||
struct mrubypp_constructor_wrapper {
|
|
||||||
static mrb_value wrapper(mrb_state *mrb, mrb_value self) {
|
static mrb_value wrapper(mrb_state *mrb, mrb_value self) {
|
||||||
auto args = mrubypp_get_args_helper<Args...>(mrb);
|
auto args = get_args_helper<Args...>(mrb);
|
||||||
T *instance = std::apply([](Args... args) { return new T(args...); }, args);
|
T *instance = std::apply([](Args... args) { return new T(args...); }, args);
|
||||||
|
|
||||||
DATA_PTR(self) = instance;
|
DATA_PTR(self) = instance;
|
||||||
DATA_TYPE(self) = &mrubypp_class_builder<T>::data_type;
|
DATA_TYPE(self) = &class_builder<T>::data_type;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T> class class_builder {
|
||||||
class mrubypp_class_builder {
|
|
||||||
public:
|
public:
|
||||||
static const struct mrb_data_type data_type;
|
static const struct mrb_data_type data_type;
|
||||||
|
|
||||||
mrubypp_class_builder(mrb_state *mrb, std::string name)
|
class_builder(mrb_state *mrb, std::string name)
|
||||||
: mrb_(mrb), name_(std::move(name)) {
|
: mrb_(mrb), name_(std::move(name)) {
|
||||||
rclass_ = mrb_define_class(mrb_, name_.c_str(), mrb_->object_class);
|
rclass_ = mrb_define_class(mrb_, name_.c_str(), mrb_->object_class);
|
||||||
MRB_SET_INSTANCE_TT(rclass_, MRB_TT_DATA);
|
MRB_SET_INSTANCE_TT(rclass_, MRB_TT_DATA);
|
||||||
@@ -168,27 +161,25 @@ public:
|
|||||||
MRB_ARGS_ANY());
|
MRB_ARGS_ANY());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template <typename... Args> class_builder &def_constructor() {
|
||||||
mrubypp_class_builder &def_constructor() {
|
|
||||||
mrb_define_method(mrb_, rclass_, "initialize",
|
mrb_define_method(mrb_, rclass_, "initialize",
|
||||||
&mrubypp_constructor_wrapper<T, Args...>::wrapper,
|
&constructor_wrapper<T, Args...>::wrapper,
|
||||||
MRB_ARGS_REQ(sizeof...(Args)));
|
MRB_ARGS_REQ(sizeof...(Args)));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ret, typename... MethodArgs>
|
template <typename Ret, typename... MethodArgs>
|
||||||
mrubypp_class_builder &def_method(const std::string &name,
|
class_builder &def_method(const std::string &name,
|
||||||
Ret (T::*method)(MethodArgs...)) {
|
Ret (T::*method)(MethodArgs...)) {
|
||||||
mrb_sym method_sym = mrb_intern_cstr(mrb_, name.c_str());
|
mrb_sym method_sym = mrb_intern_cstr(mrb_, name.c_str());
|
||||||
|
|
||||||
using wrap = mrubypp_method_wrapper<T, Ret, MethodArgs...>;
|
using wrap = method_wrapper<T, Ret, MethodArgs...>;
|
||||||
auto ptr = wrap::method_to_ptr(method);
|
auto ptr = wrap::method_to_ptr(method);
|
||||||
|
|
||||||
mrb_value env[] = {
|
mrb_value env[] = {
|
||||||
mrb_cptr_value(mrb_, ptr),
|
mrb_cptr_value(mrb_, ptr),
|
||||||
};
|
};
|
||||||
struct RProc *p = mrb_proc_new_cfunc_with_env(
|
struct RProc *p = mrb_proc_new_cfunc_with_env(mrb_, &wrap::wrapper, 1, env);
|
||||||
mrb_, &wrap::wrapper, 1, env);
|
|
||||||
mrb_method_t m;
|
mrb_method_t m;
|
||||||
MRB_METHOD_FROM_PROC(m, p);
|
MRB_METHOD_FROM_PROC(m, p);
|
||||||
mrb_define_method_raw(mrb_, rclass_, method_sym, m);
|
mrb_define_method_raw(mrb_, rclass_, method_sym, m);
|
||||||
@@ -197,21 +188,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ret, typename... MethodArgs>
|
template <typename Ret, typename... MethodArgs>
|
||||||
mrubypp_class_builder &def_method(const std::string &name,
|
class_builder &def_method(const std::string &name,
|
||||||
Ret (T::*method)(MethodArgs...) const) {
|
Ret (T::*method)(MethodArgs...) const) {
|
||||||
mrb_sym method_sym = mrb_intern_cstr(mrb_, name.c_str());
|
mrb_sym method_sym = mrb_intern_cstr(mrb_, name.c_str());
|
||||||
using wrap = mrubypp_const_method_wrapper<T, Ret, MethodArgs...>;
|
using wrap = const_method_wrapper<T, Ret, MethodArgs...>;
|
||||||
|
|
||||||
auto ptr = wrap::method_to_ptr(method);
|
auto ptr = wrap::method_to_ptr(method);
|
||||||
auto obj = mrb_cptr_value(mrb_, ptr);
|
auto obj = mrb_cptr_value(mrb_, ptr);
|
||||||
mrb_gc_protect(mrb_, obj);
|
mrb_gc_protect(mrb_, obj);
|
||||||
mrb_value env[] = {
|
mrb_value env[] = {obj};
|
||||||
obj
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RProc *p = mrb_proc_new_cfunc_with_env(
|
struct RProc *p = mrb_proc_new_cfunc_with_env(mrb_, &wrap::wrapper, 1, env);
|
||||||
mrb_, &wrap::wrapper, 1,
|
|
||||||
env);
|
|
||||||
mrb_method_t m;
|
mrb_method_t m;
|
||||||
MRB_METHOD_FROM_PROC(m, p);
|
MRB_METHOD_FROM_PROC(m, p);
|
||||||
mrb_define_method_raw(mrb_, rclass_, method_sym, m);
|
mrb_define_method_raw(mrb_, rclass_, method_sym, m);
|
||||||
@@ -219,16 +206,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ret, typename... FuncArgs>
|
template <typename Ret, typename... FuncArgs>
|
||||||
mrubypp_class_builder &def_class_method(const std::string &name,
|
class_builder &def_class_method(const std::string &name,
|
||||||
Ret (*func)(FuncArgs...)) {
|
Ret (*func)(FuncArgs...)) {
|
||||||
using wrap = mrubypp_function_wrapper<T, Ret, FuncArgs...>;
|
using wrap = function_wrapper<T, Ret, FuncArgs...>;
|
||||||
mrb_value env[] = {
|
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());
|
mrb_sym func_sym = mrb_intern_cstr(mrb_, name.c_str());
|
||||||
struct RProc *p = mrb_proc_new_cfunc_with_env(
|
struct RProc *p = mrb_proc_new_cfunc_with_env(mrb_, &wrap::wrapper, 1, env);
|
||||||
mrb_, &wrap::wrapper, 1, env);
|
|
||||||
mrb_method_t m;
|
mrb_method_t m;
|
||||||
MRB_METHOD_FROM_PROC(m, p);
|
MRB_METHOD_FROM_PROC(m, p);
|
||||||
|
|
||||||
@@ -240,15 +226,14 @@ public:
|
|||||||
|
|
||||||
// get set
|
// get set
|
||||||
template <typename Ret>
|
template <typename Ret>
|
||||||
mrubypp_class_builder &def_property(const std::string &name,
|
class_builder &def_property(const std::string &name, Ret (T::*getter)() const,
|
||||||
Ret (T::*getter)() const,
|
|
||||||
void (T::*setter)(Ret)) {
|
void (T::*setter)(Ret)) {
|
||||||
def_method(name, getter);
|
def_method(name, getter);
|
||||||
def_method(name + "=", setter);
|
def_method(name + "=", setter);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
mrubypp_class_builder &def_native(const std::string &name, mrb_func_t func,
|
class_builder &def_native(const std::string &name, mrb_func_t func,
|
||||||
mrb_aspec aspec = MRB_ARGS_ANY()) {
|
mrb_aspec aspec = MRB_ARGS_ANY()) {
|
||||||
mrb_define_method(mrb_, rclass_, name.c_str(), func, aspec);
|
mrb_define_method(mrb_, rclass_, name.c_str(), func, aspec);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -272,15 +257,14 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mrb_state *mrb_;
|
mrb_state *mrb_;
|
||||||
struct RClass *rclass_;
|
struct RClass *rclass_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T> const struct mrb_data_type class_builder<T>::data_type = {
|
||||||
const struct mrb_data_type mrubypp_class_builder<T>::data_type = {
|
typeid(T).name(), class_builder<T>::free_instance
|
||||||
typeid(T).name(), mrubypp_class_builder<T>::free_instance
|
|
||||||
};
|
};
|
||||||
|
} // namespace mrubypp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef MRUBYPP_STD_CONVERTERS_H
|
#ifndef MRUBYPP_STD_CONVERTERS_H
|
||||||
#define MRUBYPP_STD_CONVERTERS_H
|
#define MRUBYPP_STD_CONVERTERS_H
|
||||||
|
|
||||||
#include "mrubypp_arena_guard.h"
|
#include "arena_guard.h"
|
||||||
|
|
||||||
#include <mruby.h>
|
#include <mruby.h>
|
||||||
#include <mruby/array.h>
|
#include <mruby/array.h>
|
||||||
@@ -9,7 +9,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
template <typename T> struct mrubypp_converter {
|
namespace mrubypp {
|
||||||
|
|
||||||
|
template <typename T> struct converter {
|
||||||
static mrb_value to_mrb(mrb_state *mrb, const T &var) {
|
static mrb_value to_mrb(mrb_state *mrb, const T &var) {
|
||||||
static_assert(sizeof(T) == 0, "Specialization required");
|
static_assert(sizeof(T) == 0, "Specialization required");
|
||||||
return mrb_nil_value();
|
return mrb_nil_value();
|
||||||
@@ -20,7 +22,7 @@ template <typename T> struct mrubypp_converter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct mrubypp_converter<int> {
|
template <> struct converter<int> {
|
||||||
static mrb_value to_mrb(mrb_state *mrb, int var) {
|
static mrb_value to_mrb(mrb_state *mrb, int var) {
|
||||||
return mrb_fixnum_value(var);
|
return mrb_fixnum_value(var);
|
||||||
}
|
}
|
||||||
@@ -29,7 +31,7 @@ template <> struct mrubypp_converter<int> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct mrubypp_converter<unsigned int> {
|
template <> struct converter<unsigned int> {
|
||||||
static mrb_value to_mrb(mrb_state *mrb, unsigned int var) {
|
static mrb_value to_mrb(mrb_state *mrb, unsigned int var) {
|
||||||
return mrb_fixnum_value(var);
|
return mrb_fixnum_value(var);
|
||||||
}
|
}
|
||||||
@@ -38,7 +40,7 @@ template <> struct mrubypp_converter<unsigned int> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct mrubypp_converter<float> {
|
template <> struct converter<float> {
|
||||||
static mrb_value to_mrb(mrb_state *mrb, float var) {
|
static mrb_value to_mrb(mrb_state *mrb, float var) {
|
||||||
return mrb_float_value(mrb, var);
|
return mrb_float_value(mrb, var);
|
||||||
}
|
}
|
||||||
@@ -47,7 +49,7 @@ template <> struct mrubypp_converter<float> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct mrubypp_converter<double> {
|
template <> struct converter<double> {
|
||||||
static mrb_value to_mrb(mrb_state *mrb, double var) {
|
static mrb_value to_mrb(mrb_state *mrb, double var) {
|
||||||
return mrb_float_value(mrb, var);
|
return mrb_float_value(mrb, var);
|
||||||
}
|
}
|
||||||
@@ -56,7 +58,7 @@ template <> struct mrubypp_converter<double> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct mrubypp_converter<std::string> {
|
template <> struct converter<std::string> {
|
||||||
static mrb_value to_mrb(mrb_state *mrb, const std::string &var) {
|
static mrb_value to_mrb(mrb_state *mrb, const std::string &var) {
|
||||||
return mrb_str_new(mrb, var.data(), (mrb_int)var.size());
|
return mrb_str_new(mrb, var.data(), (mrb_int)var.size());
|
||||||
}
|
}
|
||||||
@@ -69,34 +71,35 @@ template <> struct mrubypp_converter<std::string> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct mrubypp_converter<const char *> {
|
template <> struct converter<const char *> {
|
||||||
static mrb_value to_mrb(mrb_state *mrb, const char *var) {
|
static mrb_value to_mrb(mrb_state *mrb, const char *var) {
|
||||||
return mrb_str_new(mrb, var, (mrb_int)strlen(var));
|
return mrb_str_new(mrb, var, (mrb_int)strlen(var));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct mrubypp_converter<std::vector<T>> {
|
template <typename T> struct converter<std::vector<T>> {
|
||||||
static mrb_value to_mrb(mrb_state *mrb, const std::vector<T> &var) {
|
static mrb_value to_mrb(mrb_state *mrb, const std::vector<T> &var) {
|
||||||
mrb_value ary = mrb_ary_new_capa(mrb, static_cast<mrb_int>(var.size()));
|
mrb_value ary = mrb_ary_new_capa(mrb, static_cast<mrb_int>(var.size()));
|
||||||
for (const T &el : var) {
|
for (const T &el : var) {
|
||||||
mrubypp_arena_guard guard(mrb);
|
arena_guard guard(mrb);
|
||||||
mrb_ary_push(mrb, ary, mrubypp_converter<T>::to_mrb(mrb, el));
|
mrb_ary_push(mrb, ary, converter<T>::to_mrb(mrb, el));
|
||||||
}
|
}
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<T> from_mrb(mrb_state *mrb, mrb_value value) {
|
static std::vector<T> from_mrb(mrb_state *mrb, mrb_value value) {
|
||||||
mrubypp_arena_guard guard(mrb);
|
arena_guard guard(mrb);
|
||||||
std::vector<T> result;
|
std::vector<T> result;
|
||||||
if (mrb_array_p(value)) {
|
if (mrb_array_p(value)) {
|
||||||
int len = RARRAY_LEN(value);
|
int len = RARRAY_LEN(value);
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; ++i) {
|
||||||
result.append(
|
result.append(converter<T>::from_mrb(mrb, mrb_ary_ref(mrb, value, i)));
|
||||||
mrubypp_converter<T>::from_mrb(mrb, mrb_ary_ref(mrb, value, i)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace mrubypp
|
||||||
|
|
||||||
#endif // MRUBYPP_STD_CONVERTERS_H
|
#endif // MRUBYPP_STD_CONVERTERS_H
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#ifndef MRUBYPP_H
|
#ifndef MRUBYPP_H
|
||||||
#define MRUBYPP_H
|
#define MRUBYPP_H
|
||||||
|
|
||||||
#include "mrubypp_arena_guard.h"
|
#include "arena_guard.h"
|
||||||
#include "mrubypp_bind_class.h"
|
#include "bind_class.h"
|
||||||
#include "mrubypp_converters.h"
|
#include "converters.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <mruby.h>
|
#include <mruby.h>
|
||||||
@@ -11,10 +11,11 @@
|
|||||||
|
|
||||||
#include <mruby/compile.h>
|
#include <mruby/compile.h>
|
||||||
|
|
||||||
class mrubypp {
|
namespace mrubypp {
|
||||||
|
class engine {
|
||||||
public:
|
public:
|
||||||
mrubypp() { mrb_ = mrb_open(); }
|
engine() { mrb_ = mrb_open(); }
|
||||||
~mrubypp() { mrb_close(mrb_); }
|
~engine() { mrb_close(mrb_); }
|
||||||
void load(const std::string &str) {
|
void load(const std::string &str) {
|
||||||
if (!mrb_)
|
if (!mrb_)
|
||||||
return;
|
return;
|
||||||
@@ -22,25 +23,25 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> T call(const std::string &funcName) {
|
template <typename T> T call(const std::string &funcName) {
|
||||||
mrubypp_arena_guard guard(mrb_);
|
arena_guard guard(mrb_);
|
||||||
mrb_value result =
|
mrb_value result =
|
||||||
mrb_funcall(mrb_, mrb_top_self(mrb_), funcName.data(), 0);
|
mrb_funcall(mrb_, mrb_top_self(mrb_), funcName.data(), 0);
|
||||||
return mrubypp_converter<T>::from_mrb(mrb_, result);
|
return converter<T>::from_mrb(mrb_, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
T call(const std::string &funcName, Args... args) {
|
T call(const std::string &funcName, Args... args) {
|
||||||
mrubypp_arena_guard guard(mrb_);
|
arena_guard guard(mrb_);
|
||||||
mrb_value argv[] = {mrubypp_converter<Args>::to_mrb(mrb_, args)...};
|
mrb_value argv[] = {converter<Args>::to_mrb(mrb_, args)...};
|
||||||
mrb_sym sym = mrb_intern_cstr(mrb_, funcName.data());
|
mrb_sym sym = mrb_intern_cstr(mrb_, funcName.data());
|
||||||
mrb_value result =
|
mrb_value result =
|
||||||
mrb_funcall_argv(mrb_, mrb_top_self(mrb_), sym, sizeof...(Args), argv);
|
mrb_funcall_argv(mrb_, mrb_top_self(mrb_), sym, sizeof...(Args), argv);
|
||||||
return mrubypp_converter<T>::from_mrb(mrb_, result);
|
return converter<T>::from_mrb(mrb_, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
mrubypp_class_builder<T> class_builder(const std::string &class_name) {
|
class_builder<T> class_builder(const std::string &class_name) {
|
||||||
return mrubypp_class_builder<T>(mrb_, class_name);
|
return class_builder<T>(mrb_, class_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] mrb_state *get_mrb() const { return mrb_; }
|
[[nodiscard]] mrb_state *get_mrb() const { return mrb_; }
|
||||||
@@ -48,5 +49,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
mrb_state *mrb_;
|
mrb_state *mrb_;
|
||||||
};
|
};
|
||||||
|
} // namespace mrubypp
|
||||||
|
|
||||||
#endif // MRUBYPP_H
|
#endif // MRUBYPP_H
|
||||||
@@ -4,12 +4,11 @@
|
|||||||
|
|
||||||
#include <catch2/catch_all.hpp>
|
#include <catch2/catch_all.hpp>
|
||||||
|
|
||||||
#include "mrubypp.h"
|
#include "engine.h"
|
||||||
|
|
||||||
class Point {
|
class Point {
|
||||||
public:
|
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) {
|
void set_values(int x, int y) {
|
||||||
x_ = x;
|
x_ = x;
|
||||||
@@ -18,15 +17,11 @@ public:
|
|||||||
|
|
||||||
int get_x() const { return x_; }
|
int get_x() const { return x_; }
|
||||||
|
|
||||||
void set_x(int x) {
|
void set_x(int x) { x_ = x; }
|
||||||
x_ = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_y() const { return y_; }
|
int get_y() const { return y_; }
|
||||||
|
|
||||||
void set_y(int y) {
|
void set_y(int y) { y_ = y; }
|
||||||
y_ = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(const Point &other) {
|
void add(const Point &other) {
|
||||||
this->x_ += other.x_;
|
this->x_ += other.x_;
|
||||||
@@ -48,8 +43,7 @@ static mrb_value point_native_div(mrb_state *mrb, mrb_value self) {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template <> struct mrubypp_converter<Point> {
|
||||||
struct mrubypp_converter<Point> {
|
|
||||||
static mrb_value to_mrb(mrb_state *mrb, const Point &var) {
|
static mrb_value to_mrb(mrb_state *mrb, const Point &var) {
|
||||||
mrb_value obj = mrb_obj_value(
|
mrb_value obj = mrb_obj_value(
|
||||||
mrb_data_object_alloc(mrb, mrb->object_class, new Point(var),
|
mrb_data_object_alloc(mrb, mrb->object_class, new Point(var),
|
||||||
@@ -67,7 +61,7 @@ struct mrubypp_converter<Point> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE("Point", "[class]") {
|
TEST_CASE("Point", "[class]") {
|
||||||
mrubypp engine;
|
engine engine;
|
||||||
engine.class_builder<Point>("Point")
|
engine.class_builder<Point>("Point")
|
||||||
.def_constructor<int, int>()
|
.def_constructor<int, int>()
|
||||||
.def_method("add", &Point::add)
|
.def_method("add", &Point::add)
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
#include <catch2/catch_all.hpp>
|
#include <catch2/catch_all.hpp>
|
||||||
|
|
||||||
#include "mrubypp.h"
|
#include "engine.h"
|
||||||
|
|
||||||
TEST_CASE("none args call", "[engine]") {
|
TEST_CASE("none args call", "[engine]") {
|
||||||
mrubypp engine;
|
engine engine;
|
||||||
engine.load(R"(
|
engine.load(R"(
|
||||||
def get_1()
|
def get_1()
|
||||||
1
|
1
|
||||||
@@ -22,7 +22,7 @@ TEST_CASE("none args call", "[engine]") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("args call", "[engine]") {
|
TEST_CASE("args call", "[engine]") {
|
||||||
mrubypp engine;
|
engine engine;
|
||||||
engine.load(R"(
|
engine.load(R"(
|
||||||
def sort_and_get_first(a)
|
def sort_and_get_first(a)
|
||||||
a.sort!
|
a.sort!
|
||||||
@@ -36,7 +36,7 @@ TEST_CASE("args call", "[engine]") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("call benchmark", "[!benchmark]") {
|
TEST_CASE("call benchmark", "[!benchmark]") {
|
||||||
mrubypp engine;
|
engine engine;
|
||||||
engine.load(R"(
|
engine.load(R"(
|
||||||
def get_same(a)
|
def get_same(a)
|
||||||
return a
|
return a
|
||||||
|
|||||||
Reference in New Issue
Block a user