Allow client code to provide their foreign_class_fn() implementation.
This commit is contained in:
parent
2c2d783730
commit
3d68124a60
2 changed files with 27 additions and 0 deletions
|
@ -55,6 +55,19 @@ namespace wren {
|
|||
auto retval = reinterpret_cast<WrenForeignMethodFn>(dfm->make(cb->owner, func));
|
||||
return retval;
|
||||
}
|
||||
|
||||
WrenForeignClassMethods foreign_class_fn (WrenVM* wvm, const char* module, const char* class_name) {
|
||||
auto cb = static_cast<detail::Callbacks*>(wrenGetUserData(wvm));
|
||||
assert(cb);
|
||||
assert(cb->foreign_class_fn and cb->config_obj and cb->owner);
|
||||
foreign_class_t funcs = cb->foreign_class_fn(*cb->config_obj, cb->owner, module, class_name);
|
||||
DynafuncMaker* const dfm = cb->dynafunc;
|
||||
assert(dfm);
|
||||
WrenForeignClassMethods retval;
|
||||
retval.allocate = reinterpret_cast<WrenForeignMethodFn>(dfm->make(cb->owner, funcs.allocate));
|
||||
retval.finalize = funcs.finalize;
|
||||
return retval;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
struct VM::LocalData {
|
||||
|
@ -106,6 +119,9 @@ namespace wren {
|
|||
if (cb.foreign_method_fn)
|
||||
wconf.bindForeignMethodFn = &foreign_method_fn;
|
||||
|
||||
if (cb.foreign_class_fn)
|
||||
wconf.bindForeignClassFn = &foreign_class_fn;
|
||||
|
||||
m_local->wvm = wrenNewVM(&wconf);
|
||||
if (not m_local->wvm)
|
||||
throw std::runtime_error("Failed to initialize Wren VM");
|
||||
|
|
|
@ -11,6 +11,12 @@ namespace wren {
|
|||
class DynafuncMaker;
|
||||
|
||||
typedef void(*foreign_method_t)(VM*);
|
||||
typedef void(*finalizer_t)(void*);
|
||||
|
||||
struct foreign_class_t {
|
||||
foreign_method_t allocate;
|
||||
finalizer_t finalize;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
struct Callbacks {
|
||||
|
@ -20,6 +26,7 @@ namespace wren {
|
|||
const char* (*resolve_module_fn)(Configuration&, VM*, const char*, const char*) {nullptr};
|
||||
char* (*load_module_fn)(Configuration&, VM*, const char*) {nullptr};
|
||||
foreign_method_t (*foreign_method_fn)(Configuration&, VM*, const char*, const char*, bool, const char*);
|
||||
foreign_class_t (*foreign_class_fn)(Configuration&, VM*, const char*, const char*);
|
||||
|
||||
Configuration* config_obj {nullptr};
|
||||
VM* owner {nullptr};
|
||||
|
@ -57,6 +64,7 @@ namespace wren {
|
|||
define_method_info(resolve_module_fn, resolve_module, const char*, const char*, const char*);
|
||||
define_method_info(load_module_fn, load_module, char*, VM*, const char*);
|
||||
define_method_info(foreign_method_fn, foreign_method, foreign_method_t, VM*, const char*, const char*, bool, const char*);
|
||||
define_method_info(foreign_class_fn, foreign_class, foreign_class_t, VM*, const char*, const char*);
|
||||
|
||||
template <typename T, typename F> struct AnyFunctionWrap;
|
||||
template <typename T, typename R, typename... Args>
|
||||
|
@ -103,6 +111,9 @@ namespace wren {
|
|||
if constexpr (detail::method_foreign_method::exists<T>::value)
|
||||
ret.foreign_method_fn = &detail::AnyFunctionWrap<T, decltype(&T::foreign_method_fn)>::template call<&T::foreign_method_fn>;
|
||||
|
||||
if constexpr (detail::method_foreign_class::exists<T>::value)
|
||||
ret.foreign_class_fn = &detail::AnyFunctionWrap<T, decltype(&T::foreign_class_fn)>::template call<&T::foreign_class_fn>;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue