Add calendar example and supporting functions

This commit is contained in:
King_DuckZ 2020-05-03 01:54:00 +02:00
commit 90d93d2583
4 changed files with 192 additions and 0 deletions

View file

@ -56,6 +56,12 @@ namespace wren {
template <typename R, std::size_t N, typename... Args>
R call (VM& vm, const ModuleAndName& object, const char (&method)[N], const Args&... args);
template <typename T>
foreign_class_t make_foreign_class();
template <auto V>
foreign_method_t make_method_bindable();
void interpret (VM& vm, const std::string& module_name, const std::string& script);
void set (VM& vm, int slot_num, const char* value);
void set (VM& vm, int slot_num, double value);
@ -69,6 +75,7 @@ namespace wren {
void set (VM& vm, int slot_num, int value);
std::string_view slot_string_view (VM& vm, int slot_num);
template <typename T> T get (VM& vm, int slot_num);
template <typename T> T* foreign (VM& vm, int slot_num);
void variable(VM& vm, const ModuleAndName& mod_and_name, int slot);
void variable(VM& vm, const Handle& handle, int slot);
@ -116,6 +123,16 @@ namespace wren {
vm.ensure_slots(sizeof...(Args));
(set_single_for_call(vm, Indices + 1, args), ...);
}
template <auto V> struct MakeMethodBindable;
template <typename T, void(T::*Method)(VM&)> struct MakeMethodBindable<Method> {
static foreign_method_t make() {
return [](VM& vm) {
T* obj = foreign<T>(vm, 0);
(obj->*Method)(vm);
};
}
};
} //namespace detail
#if __cpp_concepts >= 201907
@ -167,6 +184,12 @@ namespace wren {
vm.set_slot_double(slot_num, static_cast<double>(value));
}
template <typename T>
inline T* foreign (VM& vm, int slot_num) {
T* obj = static_cast<T*>(vm.slot_foreign(slot_num));
return obj;
}
template <typename R, typename... Args>
inline R call (VM& vm, const Handle& object, const Handle& method, const Args&... args) {
detail::set_for_call<Args...>(std::make_integer_sequence<int, sizeof...(Args)>(), vm, args...);
@ -205,4 +228,24 @@ namespace wren {
Handle obj_handle = vm.slot_handle(0);
return call<R, N, Args...>(vm, obj_handle, method, args...);
}
template <typename T>
inline foreign_class_t make_foreign_class() {
foreign_class_t ret;
ret.allocate = [](VM& vm) {
void* const mem = vm.set_slot_new_foreign(0, 0, sizeof(T));
new(mem) T;
};
ret.finalize = [](void* mem) {
const auto cale = static_cast<T*>(mem);
cale->~T();
};
return ret;
}
template <auto V>
inline foreign_method_t make_method_bindable() {
return detail::MakeMethodBindable<V>::make();
}
} //namespace wren