Add support for foreign constructor overload
Make vm_fun.hpp fun again by moving setters/getters into a separate header. Add new make_overloaded_foreign_class(), but code is still untested and it's a work in progress at this point. Interface will change.
This commit is contained in:
parent
996a089185
commit
9921e59a6b
5 changed files with 299 additions and 177 deletions
|
@ -22,6 +22,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace wren {
|
namespace wren {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -73,7 +74,7 @@ namespace wren {
|
||||||
} //namespace detail
|
} //namespace detail
|
||||||
|
|
||||||
class ClassManager {
|
class ClassManager {
|
||||||
typedef foreign_class_t(*make_foreign_class_t)();
|
typedef std::function<foreign_class_t()> make_foreign_class_t;
|
||||||
typedef std::unordered_map<detail::ClassNameOwning, make_foreign_class_t, detail::ClassNameHash, detail::ClassNameEqual> ClassMap;
|
typedef std::unordered_map<detail::ClassNameOwning, make_foreign_class_t, detail::ClassNameHash, detail::ClassNameEqual> ClassMap;
|
||||||
public:
|
public:
|
||||||
ClassManager();
|
ClassManager();
|
||||||
|
|
124
include/wrenpp/detail/construct_foreign_class.hpp
Normal file
124
include/wrenpp/detail/construct_foreign_class.hpp
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/* Copyright 2020-2022, Michele Santullo
|
||||||
|
* This file is part of wrenpp.
|
||||||
|
*
|
||||||
|
* Wrenpp is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Wrenpp is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with wrenpp. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wrenpp/vm.hpp"
|
||||||
|
#include "seters_getters.hpp"
|
||||||
|
#include <utility>
|
||||||
|
#include <tuple>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace wren {
|
||||||
|
namespace detail {
|
||||||
|
template <typename T, int... Indices, typename... Args>
|
||||||
|
inline void construct_single (
|
||||||
|
std::integer_sequence<int, Indices...>,
|
||||||
|
VM& vm,
|
||||||
|
void* memory
|
||||||
|
) {
|
||||||
|
new(memory) T{get<Args>(vm, Indices + 1)...};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
struct ForeignClassHelper;
|
||||||
|
|
||||||
|
template <typename T, template <typename...> class Pack, typename... PackArgs, typename... Args>
|
||||||
|
struct ForeignClassHelper<T, Pack<PackArgs...>, Args...> {
|
||||||
|
static bool construct (VM& vm, int cardinality, void* memory) {
|
||||||
|
using std::make_integer_sequence;
|
||||||
|
|
||||||
|
//search by number of parameters.
|
||||||
|
//once we find a tuple-like parameter that contains the right
|
||||||
|
//number of types we invoke construct_single() with those types.
|
||||||
|
constexpr int pack_size = static_cast<int>(sizeof...(PackArgs));
|
||||||
|
if (pack_size == cardinality) {
|
||||||
|
construct_single<T>(make_integer_sequence<int, pack_size>{}, vm, memory);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ForeignClassHelper<T, Args...>::construct(vm, cardinality, memory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename LoneArg, typename... Args>
|
||||||
|
struct ForeignClassHelper<T, LoneArg, Args...> {
|
||||||
|
static bool construct (VM& vm, int cardinality, void* memory) {
|
||||||
|
using std::make_integer_sequence;
|
||||||
|
|
||||||
|
if (1 == cardinality) {
|
||||||
|
construct_single<T>(make_integer_sequence<int, 1>{}, vm, memory);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ForeignClassHelper<T, Args...>::construct(vm, cardinality, memory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct ForeignClassHelper<T> {
|
||||||
|
static bool construct (VM& vm, int cardinality, void* memory) {
|
||||||
|
using std::make_integer_sequence;
|
||||||
|
|
||||||
|
assert(cardinality == 0);
|
||||||
|
construct_single<T>(make_integer_sequence<int, 0>{}, vm, memory);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename... Args, int... Indices>
|
||||||
|
inline void find_params_and_construct_foreign_class (
|
||||||
|
std::integer_sequence<int, Indices...> seq,
|
||||||
|
VM& vm,
|
||||||
|
void* memory
|
||||||
|
) {
|
||||||
|
if constexpr (sizeof...(Args) == 0) {
|
||||||
|
construct_single<T>(seq, vm, memory);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ForeignClassHelper<T, Args...>::construct(vm, vm.slot_count() - 1, memory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //namespace detail
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
inline foreign_class_t make_overloaded_foreign_class() {
|
||||||
|
foreign_class_t ret;
|
||||||
|
ret.allocate = [](VM& vm) {
|
||||||
|
void* const mem = vm.set_slot_new_foreign(0, 0, sizeof(T));
|
||||||
|
|
||||||
|
detail::find_params_and_construct_foreign_class<T, Args...>(
|
||||||
|
std::make_integer_sequence<int, sizeof...(Args)>{},
|
||||||
|
vm,
|
||||||
|
mem
|
||||||
|
);
|
||||||
|
};
|
||||||
|
ret.finalize = [](void* mem) {
|
||||||
|
const auto cale = static_cast<T*>(mem);
|
||||||
|
cale->~T();
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
inline foreign_class_t make_foreign_class() {
|
||||||
|
return make_overloaded_foreign_class<T, std::tuple<Args...>>();
|
||||||
|
}
|
||||||
|
} //namespace wren
|
170
include/wrenpp/detail/seters_getters.hpp
Normal file
170
include/wrenpp/detail/seters_getters.hpp
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
/* Copyright 2020-2022, Michele Santullo
|
||||||
|
* This file is part of wrenpp.
|
||||||
|
*
|
||||||
|
* Wrenpp is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Wrenpp is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with wrenpp. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wrenpp/vm.hpp"
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace wren {
|
||||||
|
namespace detail {
|
||||||
|
template <typename T> struct GetTypeToRetType;
|
||||||
|
template <typename T> using GetTypeToRetType_t = typename GetTypeToRetType<T>::type;
|
||||||
|
|
||||||
|
template <typename T> struct TType { typedef T type; };
|
||||||
|
|
||||||
|
template<typename T>struct GetTypeToRetType{
|
||||||
|
static_assert(not std::is_fundamental_v<T>, "User type expected");
|
||||||
|
static_assert(not std::is_pointer_v<T>, "Unexpected pointer type");
|
||||||
|
typedef std::remove_cv_t<T>* type;
|
||||||
|
};
|
||||||
|
template<>struct GetTypeToRetType<const char*> : TType<const char*>{};
|
||||||
|
template<>struct GetTypeToRetType<double> : TType<double>{};
|
||||||
|
template<>struct GetTypeToRetType<bool> : TType<bool>{};
|
||||||
|
template<>struct GetTypeToRetType<std::pair<const char*,int>> : TType<std::pair<const char*,int>> {};
|
||||||
|
template<>struct GetTypeToRetType<int> : TType<int>{};
|
||||||
|
template<>struct GetTypeToRetType<std::size_t> : TType<std::size_t>{};
|
||||||
|
template<>struct GetTypeToRetType<std::string> : TType<std::string>{};
|
||||||
|
template<>struct GetTypeToRetType<std::string_view> : TType<std::string_view>{};
|
||||||
|
template<>struct GetTypeToRetType<std::vector<char>> : TType<std::vector<char>>{};
|
||||||
|
|
||||||
|
#if __cpp_concepts >= 201907
|
||||||
|
template <typename T>
|
||||||
|
concept ConstCharTuple = requires {
|
||||||
|
std::same_as<std::remove_cv_t<T>, Handle> or
|
||||||
|
std::same_as<std::remove_cv_t<T>, ModuleAndName>;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __cpp_concepts >= 201907
|
||||||
|
template <typename... Outs, int... Indices, ConstCharTuple... Params>
|
||||||
|
#else
|
||||||
|
template <typename... Outs, int... Indices, typename... Params>
|
||||||
|
#endif
|
||||||
|
inline std::tuple<detail::GetTypeToRetType_t<Outs>...> variables_impl (
|
||||||
|
VM& vm,
|
||||||
|
std::integer_sequence<int, Indices...>,
|
||||||
|
Params&&... modules_names
|
||||||
|
) {
|
||||||
|
if constexpr (sizeof...(Outs) == 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
static_assert(sizeof...(Params) == sizeof...(Outs), "Expected a module/name pair per requested output");
|
||||||
|
static_assert(sizeof...(Outs) == sizeof...(Indices), "Mismatching index count");
|
||||||
|
|
||||||
|
vm.ensure_slots(sizeof...(Params));
|
||||||
|
(variable(vm, modules_names, Indices), ...);
|
||||||
|
return std::tuple<detail::GetTypeToRetType_t<Outs>...>(get<Outs>(vm, Indices)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //namespace detail
|
||||||
|
|
||||||
|
void set (VM& vm, int slot_num, const char* value);
|
||||||
|
void set (VM& vm, int slot_num, double value);
|
||||||
|
void set (VM& vm, int slot_num, bool value);
|
||||||
|
void set (VM& vm, int slot_num, std::nullptr_t);
|
||||||
|
void set (VM& vm, int slot_num, const char* bytes, std::size_t length);
|
||||||
|
void set (VM& vm, int slot_num, const std::string& value);
|
||||||
|
void set (VM& vm, int slot_num, std::string_view value);
|
||||||
|
void set (VM& vm, int slot_num, const std::vector<char>& value);
|
||||||
|
void set (VM& vm, int slot_num, const char* beg, const char* end);
|
||||||
|
void set (VM& vm, int slot_num, int value);
|
||||||
|
void set (VM& vm, int slot_num, std::size_t value);
|
||||||
|
std::string_view slot_string_view (VM& vm, int slot_num);
|
||||||
|
template <typename T> detail::GetTypeToRetType_t<T> get (VM& vm, int slot_num);
|
||||||
|
template <typename T> T* foreign (VM& vm, int slot_num);
|
||||||
|
|
||||||
|
#if __cpp_concepts >= 201907
|
||||||
|
template <typename... Outs, detail::ConstCharTuple... Params>
|
||||||
|
#else
|
||||||
|
template <typename... Outs, typename... Params>
|
||||||
|
#endif
|
||||||
|
std::tuple<detail::GetTypeToRetType_t<Outs>...> variables(VM& vm, Params&&... modules_names);
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, const char* value) {
|
||||||
|
vm.set_slot_string(slot_num, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, double value) {
|
||||||
|
vm.set_slot_double(slot_num, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, bool value) {
|
||||||
|
vm.set_slot_bool(slot_num, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, std::nullptr_t) {
|
||||||
|
vm.set_slot_null(slot_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, const char* bytes, std::size_t length) {
|
||||||
|
vm.set_slot_bytes(slot_num, bytes, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, const std::string& value) {
|
||||||
|
vm.set_slot_string(slot_num, value.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, std::string_view value) {
|
||||||
|
vm.set_slot_bytes(slot_num, value.data(), value.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, const std::vector<char>& value) {
|
||||||
|
vm.set_slot_bytes(slot_num, value.data(), value.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, int value) {
|
||||||
|
vm.set_slot_double(slot_num, static_cast<double>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set (VM& vm, int slot_num, std::size_t value) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cpp_concepts >= 201907
|
||||||
|
template <typename... Outs, detail::ConstCharTuple... Params>
|
||||||
|
#else
|
||||||
|
template <typename... Outs, typename... Params>
|
||||||
|
#endif
|
||||||
|
inline std::tuple<detail::GetTypeToRetType_t<Outs>...> variables(VM& vm, Params&&... modules_names) {
|
||||||
|
return detail::variables_impl<Outs...>(vm, std::make_integer_sequence<int, sizeof...(Outs)>(), std::forward<Params>(modules_names)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline detail::GetTypeToRetType_t<T> get (VM& vm, int slot_num) {
|
||||||
|
return foreign<T>(vm, slot_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> const char* get<const char*> (VM& vm, int slot_num);
|
||||||
|
template <> double get<double> (VM& vm, int slot_num);
|
||||||
|
template <> bool get<bool> (VM& vm, int slot_num);
|
||||||
|
template <> std::pair<const char*, int> get<std::pair<const char*,int>> (VM& vm, int slot_num);
|
||||||
|
template<> int get<int> (VM& vm, int slot_num);
|
||||||
|
template<> std::size_t get<std::size_t> (VM& vm, int slot_num);
|
||||||
|
template<> std::string get<std::string> (VM& vm, int slot_num);
|
||||||
|
template <> std::string_view get<std::string_view> (VM& vm, int slot_num);
|
||||||
|
template <> std::vector<char> get<std::vector<char>> (VM& vm, int slot_num);
|
||||||
|
} //namespace wren
|
|
@ -23,40 +23,18 @@
|
||||||
# include "guess_class_name.hpp"
|
# include "guess_class_name.hpp"
|
||||||
#endif
|
#endif
|
||||||
#include "wren_types.hpp"
|
#include "wren_types.hpp"
|
||||||
|
#include "detail/construct_foreign_class.hpp"
|
||||||
|
#include "detail/seters_getters.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace wren {
|
namespace wren {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename T> struct GetTypeToRetType;
|
|
||||||
template <typename T> using GetTypeToRetType_t = typename GetTypeToRetType<T>::type;
|
|
||||||
|
|
||||||
#if __cpp_concepts >= 201907
|
|
||||||
template <typename T>
|
|
||||||
concept ConstCharTuple = requires {
|
|
||||||
std::same_as<std::remove_cv_t<T>, Handle> or
|
|
||||||
std::same_as<std::remove_cv_t<T>, ModuleAndName>;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T, int... Indices, typename... Args>
|
|
||||||
inline void construct_foreign_class (
|
|
||||||
std::integer_sequence<int, Indices...>,
|
|
||||||
void* memory
|
|
||||||
);
|
|
||||||
} //namespace detail
|
} //namespace detail
|
||||||
|
|
||||||
#if __cpp_concepts >= 201907
|
|
||||||
template <typename... Outs, detail::ConstCharTuple... Params>
|
|
||||||
#else
|
|
||||||
template <typename... Outs, typename... Params>
|
|
||||||
#endif
|
|
||||||
std::tuple<detail::GetTypeToRetType_t<Outs>...> variables(VM& vm, Params&&... modules_names);
|
|
||||||
|
|
||||||
template <typename R, typename... Args>
|
template <typename R, typename... Args>
|
||||||
R call (VM& vm, const Handle& object, const Handle& method, const Args&... args);
|
R call (VM& vm, const Handle& object, const Handle& method, const Args&... args);
|
||||||
|
|
||||||
|
@ -69,9 +47,6 @@ namespace wren {
|
||||||
template <typename R, std::size_t N, typename... Args>
|
template <typename R, std::size_t N, typename... Args>
|
||||||
R call (VM& vm, const ModuleAndName& object, const char (&method)[N], const Args&... args);
|
R call (VM& vm, const ModuleAndName& object, const char (&method)[N], const Args&... args);
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
|
||||||
foreign_class_t make_foreign_class();
|
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
T* make_foreign_object(VM& vm, const ModuleAndName& mn, Args&&... args);
|
T* make_foreign_object(VM& vm, const ModuleAndName& mn, Args&&... args);
|
||||||
|
|
||||||
|
@ -84,66 +59,12 @@ namespace wren {
|
||||||
foreign_method_t make_method_bindable();
|
foreign_method_t make_method_bindable();
|
||||||
|
|
||||||
void interpret (VM& vm, const std::string& module_name, const std::string& script);
|
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);
|
|
||||||
void set (VM& vm, int slot_num, bool value);
|
|
||||||
void set (VM& vm, int slot_num, std::nullptr_t);
|
|
||||||
void set (VM& vm, int slot_num, const char* bytes, std::size_t length);
|
|
||||||
void set (VM& vm, int slot_num, const std::string& value);
|
|
||||||
void set (VM& vm, int slot_num, std::string_view value);
|
|
||||||
void set (VM& vm, int slot_num, const std::vector<char>& value);
|
|
||||||
void set (VM& vm, int slot_num, const char* beg, const char* end);
|
|
||||||
void set (VM& vm, int slot_num, int value);
|
|
||||||
void set (VM& vm, int slot_num, std::size_t value);
|
|
||||||
std::string_view slot_string_view (VM& vm, int slot_num);
|
|
||||||
template <typename T> detail::GetTypeToRetType_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 ModuleAndName& mod_and_name, int slot);
|
||||||
void variable(VM& vm, const Handle& handle, int slot);
|
void variable(VM& vm, const Handle& handle, int slot);
|
||||||
void variable_ensure_slot(VM& vm, const ModuleAndName& mod_and_name, int slot);
|
void variable_ensure_slot(VM& vm, const ModuleAndName& mod_and_name, int slot);
|
||||||
void variable_ensure_slot(VM& vm, const Handle& handle, int slot);
|
void variable_ensure_slot(VM& vm, const Handle& handle, int slot);
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename T> struct TType { typedef T type; };
|
|
||||||
|
|
||||||
template<typename T>struct GetTypeToRetType{
|
|
||||||
static_assert(not std::is_fundamental_v<T>, "User type expected");
|
|
||||||
static_assert(not std::is_pointer_v<T>, "Unexpected pointer type");
|
|
||||||
typedef std::remove_cv_t<T>* type;
|
|
||||||
};
|
|
||||||
template<>struct GetTypeToRetType<const char*> : TType<const char*>{};
|
|
||||||
template<>struct GetTypeToRetType<double> : TType<double>{};
|
|
||||||
template<>struct GetTypeToRetType<bool> : TType<bool>{};
|
|
||||||
template<>struct GetTypeToRetType<std::pair<const char*,int>> : TType<std::pair<const char*,int>> {};
|
|
||||||
template<>struct GetTypeToRetType<int> : TType<int>{};
|
|
||||||
template<>struct GetTypeToRetType<std::size_t> : TType<std::size_t>{};
|
|
||||||
template<>struct GetTypeToRetType<std::string> : TType<std::string>{};
|
|
||||||
template<>struct GetTypeToRetType<std::string_view> : TType<std::string_view>{};
|
|
||||||
template<>struct GetTypeToRetType<std::vector<char>> : TType<std::vector<char>>{};
|
|
||||||
|
|
||||||
#if __cpp_concepts >= 201907
|
|
||||||
template <typename... Outs, int... Indices, ConstCharTuple... Params>
|
|
||||||
#else
|
|
||||||
template <typename... Outs, int... Indices, typename... Params>
|
|
||||||
#endif
|
|
||||||
inline std::tuple<detail::GetTypeToRetType_t<Outs>...> variables_impl (
|
|
||||||
VM& vm,
|
|
||||||
std::integer_sequence<int, Indices...>,
|
|
||||||
Params&&... modules_names
|
|
||||||
) {
|
|
||||||
if constexpr (sizeof...(Outs) == 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
static_assert(sizeof...(Params) == sizeof...(Outs), "Expected a module/name pair per requested output");
|
|
||||||
static_assert(sizeof...(Outs) == sizeof...(Indices), "Mismatching index count");
|
|
||||||
|
|
||||||
vm.ensure_slots(sizeof...(Params));
|
|
||||||
(variable(vm, modules_names, Indices), ...);
|
|
||||||
return std::tuple<detail::GetTypeToRetType_t<Outs>...>(get<Outs>(vm, Indices)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void set_single_for_call (VM& vm, int slot, const T& value) {
|
inline void set_single_for_call (VM& vm, int slot, const T& value) {
|
||||||
set(vm, slot, value);
|
set(vm, slot, value);
|
||||||
|
@ -204,76 +125,12 @@ namespace wren {
|
||||||
|
|
||||||
template <typename T, typename R, typename... Args, R(T::*Method)(Args...)> struct MakeMethodBindable<Method> : MakeMethodBindableConstNonConst<T, R, Method, Args...> {};
|
template <typename T, typename R, typename... Args, R(T::*Method)(Args...)> struct MakeMethodBindable<Method> : MakeMethodBindableConstNonConst<T, R, Method, Args...> {};
|
||||||
template <typename T, typename R, typename... Args, R(T::*Method)(Args...)const> struct MakeMethodBindable<Method> : MakeMethodBindableConstNonConst<T, R, Method, Args...> {};
|
template <typename T, typename R, typename... Args, R(T::*Method)(Args...)const> struct MakeMethodBindable<Method> : MakeMethodBindableConstNonConst<T, R, Method, Args...> {};
|
||||||
|
|
||||||
template <typename T, typename... Args, int... Indices>
|
|
||||||
inline void construct_foreign_class (
|
|
||||||
std::integer_sequence<int, Indices...>,
|
|
||||||
VM& vm,
|
|
||||||
void* memory
|
|
||||||
) {
|
|
||||||
new(memory) T{get<Args>(vm, Indices + 1)...};
|
|
||||||
}
|
|
||||||
} //namespace detail
|
} //namespace detail
|
||||||
|
|
||||||
#if __cpp_concepts >= 201907
|
|
||||||
template <typename... Outs, detail::ConstCharTuple... Params>
|
|
||||||
#else
|
|
||||||
template <typename... Outs, typename... Params>
|
|
||||||
#endif
|
|
||||||
inline std::tuple<detail::GetTypeToRetType_t<Outs>...> variables(VM& vm, Params&&... modules_names) {
|
|
||||||
return detail::variables_impl<Outs...>(vm, std::make_integer_sequence<int, sizeof...(Outs)>(), std::forward<Params>(modules_names)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void interpret (VM& vm, const std::string& module_name, const std::string& script) {
|
inline void interpret (VM& vm, const std::string& module_name, const std::string& script) {
|
||||||
return vm.interpret(module_name.c_str(), script.c_str());
|
return vm.interpret(module_name.c_str(), script.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, const char* value) {
|
|
||||||
vm.set_slot_string(slot_num, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, double value) {
|
|
||||||
vm.set_slot_double(slot_num, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, bool value) {
|
|
||||||
vm.set_slot_bool(slot_num, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, std::nullptr_t) {
|
|
||||||
vm.set_slot_null(slot_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, const char* bytes, std::size_t length) {
|
|
||||||
vm.set_slot_bytes(slot_num, bytes, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, const std::string& value) {
|
|
||||||
vm.set_slot_string(slot_num, value.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, std::string_view value) {
|
|
||||||
vm.set_slot_bytes(slot_num, value.data(), value.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, const std::vector<char>& value) {
|
|
||||||
vm.set_slot_bytes(slot_num, value.data(), value.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, int value) {
|
|
||||||
vm.set_slot_double(slot_num, static_cast<double>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (VM& vm, int slot_num, std::size_t value) {
|
|
||||||
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>
|
template <typename R, typename... Args>
|
||||||
inline R call (VM& vm, const Handle& object, const Handle& method, const Args&... 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...);
|
detail::set_for_call<Args...>(std::make_integer_sequence<int, sizeof...(Args)>(), vm, args...);
|
||||||
|
@ -314,21 +171,6 @@ namespace wren {
|
||||||
return call<R, N, Args...>(vm, obj_handle, method, args...);
|
return call<R, N, Args...>(vm, obj_handle, method, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
|
||||||
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));
|
|
||||||
detail::construct_foreign_class<T, Args...>(std::make_integer_sequence<int, sizeof...(Args)>{}, vm, mem);
|
|
||||||
};
|
|
||||||
ret.finalize = [](void* mem) {
|
|
||||||
const auto cale = static_cast<T*>(mem);
|
|
||||||
cale->~T();
|
|
||||||
};
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
inline T* make_foreign_object(VM& vm, const ModuleAndName& mn, Args&&... args) {
|
inline T* make_foreign_object(VM& vm, const ModuleAndName& mn, Args&&... args) {
|
||||||
variable(vm, mn, 0);
|
variable(vm, mn, 0);
|
||||||
|
@ -352,19 +194,4 @@ namespace wren {
|
||||||
inline foreign_method_t make_method_bindable() {
|
inline foreign_method_t make_method_bindable() {
|
||||||
return detail::MakeMethodBindable<V>::make();
|
return detail::MakeMethodBindable<V>::make();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline detail::GetTypeToRetType_t<T> get (VM& vm, int slot_num) {
|
|
||||||
return foreign<T>(vm, slot_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> const char* get<const char*> (VM& vm, int slot_num);
|
|
||||||
template <> double get<double> (VM& vm, int slot_num);
|
|
||||||
template <> bool get<bool> (VM& vm, int slot_num);
|
|
||||||
template <> std::pair<const char*, int> get<std::pair<const char*,int>> (VM& vm, int slot_num);
|
|
||||||
template<> int get<int> (VM& vm, int slot_num);
|
|
||||||
template<> std::size_t get<std::size_t> (VM& vm, int slot_num);
|
|
||||||
template<> std::string get<std::string> (VM& vm, int slot_num);
|
|
||||||
template <> std::string_view get<std::string_view> (VM& vm, int slot_num);
|
|
||||||
template <> std::vector<char> get<std::vector<char>> (VM& vm, int slot_num);
|
|
||||||
} //namespace wren
|
} //namespace wren
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace wren {
|
||||||
|
|
||||||
auto it_found = m_classes.find(TempClassName{module_name, class_name});
|
auto it_found = m_classes.find(TempClassName{module_name, class_name});
|
||||||
if (m_classes.cend() != it_found)
|
if (m_classes.cend() != it_found)
|
||||||
return (*it_found->second)();
|
return it_found->second();
|
||||||
else
|
else
|
||||||
return {nullptr, nullptr};
|
return {nullptr, nullptr};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue