Add support for registering foreign methods that return foreign objects
Still a bit work in progress but functioning
This commit is contained in:
parent
9c147b1a6e
commit
1fa6d62f17
15 changed files with 264 additions and 45 deletions
|
@ -123,7 +123,7 @@ int main() {
|
||||||
vm.callback_manager().add_callback(true, "calendar", "Calendar", "today()", &Calendar::today)
|
vm.callback_manager().add_callback(true, "calendar", "Calendar", "today()", &Calendar::today)
|
||||||
.add_callback(false, "calendar", "Calendar", "add_appointment(_)", wren::make_method_bindable<&Calendar::add_appointment>())
|
.add_callback(false, "calendar", "Calendar", "add_appointment(_)", wren::make_method_bindable<&Calendar::add_appointment>())
|
||||||
.add_callback(false, "calendar", "Calendar", "appointment_count()", wren::make_method_bindable<&Calendar::appointment_count>());
|
.add_callback(false, "calendar", "Calendar", "appointment_count()", wren::make_method_bindable<&Calendar::appointment_count>());
|
||||||
vm.class_manager().add_class_maker("calendar", "Calendar", &wren::make_foreign_class<Calendar>);
|
vm.class_manager().add_class_maker("calendar", "Calendar", wren::make_foreign_class<Calendar>);
|
||||||
|
|
||||||
vm.interpret("main", g_test_script);
|
vm.interpret("main", g_test_script);
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ int main() {
|
||||||
.add_callback(false, "math_vector", "MathVector", "z", make_method_bindable<&Vector<double>::z>());
|
.add_callback(false, "math_vector", "MathVector", "z", make_method_bindable<&Vector<double>::z>());
|
||||||
|
|
||||||
vm.class_manager()
|
vm.class_manager()
|
||||||
.add_class_maker("math_vector", "MathVector", &make_foreign_class<Vector<double>,
|
.add_class_maker("math_vector", "MathVector", make_foreign_class<Vector<double>,
|
||||||
double, //single value constructor
|
double, //single value constructor
|
||||||
std::tuple<double, double, double>, //x,y,z constructor
|
std::tuple<double, double, double>, //x,y,z constructor
|
||||||
std::tuple<> //default constructor
|
std::tuple<> //default constructor
|
||||||
|
|
|
@ -19,10 +19,13 @@
|
||||||
|
|
||||||
#include "detail/wren_types.hpp"
|
#include "detail/wren_types.hpp"
|
||||||
#include "detail/strings_in_vector.hpp"
|
#include "detail/strings_in_vector.hpp"
|
||||||
|
#include "detail/construct_foreign_class.hpp"
|
||||||
|
#include "detail/wren_class_name_from_type.hpp"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace wren {
|
namespace wren {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -47,6 +50,7 @@ namespace wren {
|
||||||
|
|
||||||
std::string_view module_name() const { return this->as_string_view<0>(); }
|
std::string_view module_name() const { return this->as_string_view<0>(); }
|
||||||
std::string_view class_name() const { return this->as_string_view<1>(); }
|
std::string_view class_name() const { return this->as_string_view<1>(); }
|
||||||
|
operator ModuleAndName() const;
|
||||||
|
|
||||||
using StringsInVector<2>::operator<;
|
using StringsInVector<2>::operator<;
|
||||||
bool operator== (const ClassNameOwning& other) const;
|
bool operator== (const ClassNameOwning& other) const;
|
||||||
|
@ -58,6 +62,9 @@ namespace wren {
|
||||||
TempClassName (const ClassNameOwning& model);
|
TempClassName (const ClassNameOwning& model);
|
||||||
bool operator== (const TempClassName& other) const;
|
bool operator== (const TempClassName& other) const;
|
||||||
|
|
||||||
|
std::string_view module_name() const { return m_module_name; }
|
||||||
|
std::string_view class_name() const { return m_class_name; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string_view m_module_name, m_class_name;
|
std::string_view m_module_name, m_class_name;
|
||||||
};
|
};
|
||||||
|
@ -71,19 +78,73 @@ namespace wren {
|
||||||
using is_transparent = std::true_type;
|
using is_transparent = std::true_type;
|
||||||
std::size_t operator()(TempClassName value) const;
|
std::size_t operator()(TempClassName value) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
struct CppClassTypeHelper {
|
||||||
|
static void register_ifp(ClassManager&, const ClassNameOwning* name);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
struct CppClassTypeHelper<MakeForeignClass<T, Args...>> {
|
||||||
|
static void register_ifp(ClassManager& classman, const ClassNameOwning* name);
|
||||||
|
};
|
||||||
} //namespace detail
|
} //namespace detail
|
||||||
|
|
||||||
class ClassManager {
|
class ClassManager {
|
||||||
|
template <typename F> friend struct detail::CppClassTypeHelper;
|
||||||
typedef std::function<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;
|
||||||
|
typedef std::unordered_map<ClassManagerNameHashType, const detail::ClassNameOwning*> TypeMap;
|
||||||
public:
|
public:
|
||||||
ClassManager();
|
ClassManager();
|
||||||
~ClassManager() noexcept;
|
~ClassManager() noexcept;
|
||||||
|
|
||||||
ClassManager& add_class_maker (std::string_view module_name, std::string_view class_name, make_foreign_class_t);
|
template <typename F>
|
||||||
|
ClassManager& add_class_maker (std::string module_name, std::string_view class_name, F&& maker);
|
||||||
foreign_class_t make_class(std::string_view module_name, std::string_view class_name);
|
foreign_class_t make_class(std::string_view module_name, std::string_view class_name);
|
||||||
|
ModuleAndName wren_class_name_from_hash(ClassManagerNameHashType hash) const;
|
||||||
|
template <typename T>
|
||||||
|
ModuleAndName wren_class_name_from_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ClassMap::const_iterator add_class_maker_implem (
|
||||||
|
std::string_view module_name,
|
||||||
|
std::string_view class_name,
|
||||||
|
make_foreign_class_t
|
||||||
|
);
|
||||||
|
|
||||||
|
void add_type (ClassManagerNameHashType hash, const detail::ClassNameOwning* name);
|
||||||
|
|
||||||
ClassMap m_classes;
|
ClassMap m_classes;
|
||||||
|
TypeMap m_types; //refers to memory in m_classes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <typename F>
|
||||||
|
inline void CppClassTypeHelper<F>::register_ifp(ClassManager&, const ClassNameOwning*) {
|
||||||
|
//Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
inline void CppClassTypeHelper<MakeForeignClass<T, Args...>>::register_ifp(
|
||||||
|
ClassManager& classman,
|
||||||
|
const ClassNameOwning* name
|
||||||
|
) {
|
||||||
|
const auto new_hash = type_hash<T>();
|
||||||
|
classman.add_type(new_hash, name);
|
||||||
|
}
|
||||||
|
} //namespace detail
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
inline ClassManager& ClassManager::add_class_maker (std::string module_name, std::string_view class_name, F&& maker) {
|
||||||
|
auto it_new = this->add_class_maker_implem(module_name, class_name, std::forward<F>(maker));
|
||||||
|
const auto& owning_name = it_new->first;
|
||||||
|
detail::CppClassTypeHelper<std::decay_t<F>>::register_ifp(*this, &owning_name);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline ModuleAndName ClassManager::wren_class_name_from_type() const {
|
||||||
|
return detail::wren_class_name_from_type<T>(*this);
|
||||||
|
}
|
||||||
} //namespace wren
|
} //namespace wren
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "wrenpp/vm.hpp"
|
#include "../vm.hpp"
|
||||||
#include "setters_getters.hpp"
|
#include "setters_getters.hpp"
|
||||||
#if defined(WRENPP_WITH_NAME_GUESSING)
|
#if defined(WRENPP_WITH_NAME_GUESSING)
|
||||||
# include "guess_class_name.hpp"
|
# include "guess_class_name.hpp"
|
||||||
|
@ -123,33 +123,46 @@ namespace wren {
|
||||||
static_assert(dummy == 1); //always true
|
static_assert(dummy == 1); //always true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This is named from the perspective of the user - they say
|
||||||
|
//MakeForeignClass<X> and it will "produce" object of type X. In
|
||||||
|
//reality it produces a functor that does that, and it's that functor
|
||||||
|
//that gets registered into wren, so from the library perspective it
|
||||||
|
//should be called MakeForeignClassMaker
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
class MakeForeignClass {
|
||||||
|
public:
|
||||||
|
MakeForeignClass() = default;
|
||||||
|
|
||||||
|
foreign_class_t operator()() const {
|
||||||
|
detail::static_assert_all_packs_are_unique<Args...>();
|
||||||
|
|
||||||
|
foreign_class_t ret;
|
||||||
|
ret.allocate = [](VM& vm, ModuleAndName mn) {
|
||||||
|
void* const mem = vm.set_slot_new_foreign(0, 0, sizeof(T));
|
||||||
|
|
||||||
|
const auto result = detail::ForeignClassHelper<T, Args...>::construct(vm, vm.slot_count() - 1, mem);
|
||||||
|
if (not result.success) {
|
||||||
|
set(vm, 1, std::string{"No registered c++ constructor "} +
|
||||||
|
#if defined(WRENPP_WITH_NAME_GUESSING)
|
||||||
|
"for class " + guess_class_name<T>() + " " +
|
||||||
|
#endif
|
||||||
|
"takes " + std::to_string(result.parameter_count) +
|
||||||
|
" parameter" + (result.parameter_count == 1 ? "" : "s")
|
||||||
|
);
|
||||||
|
vm.abort_fiber(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ret.finalize = [](void* mem) {
|
||||||
|
const auto cale = static_cast<T*>(mem);
|
||||||
|
cale->~T();
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
} //namespace detail
|
} //namespace detail
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
inline foreign_class_t make_foreign_class() {
|
constexpr detail::MakeForeignClass<T, Args...> make_foreign_class;
|
||||||
detail::static_assert_all_packs_are_unique<Args...>();
|
|
||||||
|
|
||||||
foreign_class_t ret;
|
|
||||||
ret.allocate = [](VM& vm, ModuleAndName mn) {
|
|
||||||
void* const mem = vm.set_slot_new_foreign(0, 0, sizeof(T));
|
|
||||||
|
|
||||||
const auto result = detail::ForeignClassHelper<T, Args...>::construct(vm, vm.slot_count() - 1, mem);
|
|
||||||
if (not result.success) {
|
|
||||||
set(vm, 1, std::string{"No registered c++ constructor "} +
|
|
||||||
#if defined(WRENPP_WITH_NAME_GUESSING)
|
|
||||||
"for class " + guess_class_name<T>() + " " +
|
|
||||||
#endif
|
|
||||||
"takes " + std::to_string(result.parameter_count) +
|
|
||||||
" parameter" + (result.parameter_count == 1 ? "" : "s")
|
|
||||||
);
|
|
||||||
vm.abort_fiber(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ret.finalize = [](void* mem) {
|
|
||||||
const auto cale = static_cast<T*>(mem);
|
|
||||||
cale->~T();
|
|
||||||
};
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} //namespace wren
|
} //namespace wren
|
||||||
|
|
|
@ -8,6 +8,7 @@ include_files = [
|
||||||
'string_bt.hpp',
|
'string_bt.hpp',
|
||||||
'StringCRC32.hpp',
|
'StringCRC32.hpp',
|
||||||
'strings_in_vector.hpp',
|
'strings_in_vector.hpp',
|
||||||
|
'wren_class_name_from_type.hpp',
|
||||||
'wren_types.hpp',
|
'wren_types.hpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace wren {
|
||||||
//spits out.
|
//spits out.
|
||||||
class ModuleAndName {
|
class ModuleAndName {
|
||||||
public:
|
public:
|
||||||
|
constexpr ModuleAndName();
|
||||||
constexpr ModuleAndName (const char* base, std::uint32_t hash, std::size_t mod_name_len, std::size_t class_name_len);
|
constexpr ModuleAndName (const char* base, std::uint32_t hash, std::size_t mod_name_len, std::size_t class_name_len);
|
||||||
|
|
||||||
constexpr const char* module_name_char() const noexcept { return m_base; }
|
constexpr const char* module_name_char() const noexcept { return m_base; }
|
||||||
|
@ -73,6 +74,10 @@ namespace wren {
|
||||||
static_assert(sizeof(raw) == sizeof(module_and_name));
|
static_assert(sizeof(raw) == sizeof(module_and_name));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr ModuleAndName::ModuleAndName() :
|
||||||
|
ModuleAndName(nullptr, 0, 0, 0)
|
||||||
|
{}
|
||||||
|
|
||||||
constexpr ModuleAndName::ModuleAndName (const char* base, std::uint32_t hash, std::size_t mod_name_len, std::size_t class_name_len) :
|
constexpr ModuleAndName::ModuleAndName (const char* base, std::uint32_t hash, std::size_t mod_name_len, std::size_t class_name_len) :
|
||||||
m_base(base),
|
m_base(base),
|
||||||
m_hash(hash),
|
m_hash(hash),
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "wrenpp/vm.hpp"
|
#include "../vm.hpp"
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
|
@ -81,6 +81,10 @@ namespace wren {
|
||||||
bool operator== (const StringsInVectorImplem& other) const;
|
bool operator== (const StringsInVectorImplem& other) const;
|
||||||
bool operator< (const StringsInVectorImplem& other) const;
|
bool operator< (const StringsInVectorImplem& other) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char* raw_buffer() const;
|
||||||
|
std::size_t raw_buffer_size() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<char> m_memory;
|
std::vector<char> m_memory;
|
||||||
};
|
};
|
||||||
|
@ -132,6 +136,16 @@ namespace wren {
|
||||||
return this_memory < other_memory;
|
return this_memory < other_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <std::size_t Count, std::size_t... Indices>
|
||||||
|
inline const char* StringsInVectorImplem<Count, std::index_sequence<Indices...>>::raw_buffer() const {
|
||||||
|
return m_memory.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t Count, std::size_t... Indices>
|
||||||
|
inline std::size_t StringsInVectorImplem<Count, std::index_sequence<Indices...>>::raw_buffer_size() const {
|
||||||
|
return m_memory.size();
|
||||||
|
}
|
||||||
|
|
||||||
template <std::size_t Count>
|
template <std::size_t Count>
|
||||||
using StringsInVector = StringsInVectorImplem<Count, decltype(std::make_index_sequence<Count>())>;
|
using StringsInVector = StringsInVectorImplem<Count, decltype(std::make_index_sequence<Count>())>;
|
||||||
|
|
||||||
|
|
51
include/wrenpp/detail/wren_class_name_from_type.hpp
Normal file
51
include/wrenpp/detail/wren_class_name_from_type.hpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/* 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 "module_and_name.hpp"
|
||||||
|
#include <utility>
|
||||||
|
#include <string_view>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace wren {
|
||||||
|
typedef std::size_t ClassManagerNameHashType;
|
||||||
|
class VM;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
//TODO: work in progress, make it take a type T and hash that for real
|
||||||
|
template<typename T>
|
||||||
|
inline ClassManagerNameHashType type_hash() {
|
||||||
|
static const ClassManagerNameHashType my_hash = 0;
|
||||||
|
return static_cast<ClassManagerNameHashType>(reinterpret_cast<std::uintptr_t>(&my_hash));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Just an utility function to call a method on the class manager in vm
|
||||||
|
//and return its return value without including the header for the
|
||||||
|
//class manager. Useful in inline functions in header files where
|
||||||
|
//including class_manager.hpp would propagate it everywhere.
|
||||||
|
ModuleAndName fetch_class_name_from_manager (
|
||||||
|
const VM& vm,
|
||||||
|
ClassManagerNameHashType hash
|
||||||
|
);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline ModuleAndName wren_class_name_from_type (const VM& vm) {
|
||||||
|
return fetch_class_name_from_manager(vm, type_hash<T>());
|
||||||
|
}
|
||||||
|
} //namespace detail
|
||||||
|
} //namespace wren
|
|
@ -109,7 +109,9 @@ namespace wren {
|
||||||
void reset (Configuration* conf);
|
void reset (Configuration* conf);
|
||||||
|
|
||||||
CallbackManager& callback_manager();
|
CallbackManager& callback_manager();
|
||||||
|
const CallbackManager& callback_manager() const;
|
||||||
ClassManager& class_manager();
|
ClassManager& class_manager();
|
||||||
|
const ClassManager& class_manager() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct LocalData;
|
struct LocalData;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "detail/wren_types.hpp"
|
#include "detail/wren_types.hpp"
|
||||||
#include "detail/construct_foreign_class.hpp"
|
#include "detail/construct_foreign_class.hpp"
|
||||||
#include "detail/setters_getters.hpp"
|
#include "detail/setters_getters.hpp"
|
||||||
|
#include "detail/wren_class_name_from_type.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
@ -103,8 +104,15 @@ namespace wren {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto ret = call_implem(std::make_integer_sequence<int, sizeof...(Args)>(), vm);
|
auto ret = call_implem(std::make_integer_sequence<int, sizeof...(Args)>(), vm);
|
||||||
|
//TODO: check for errors
|
||||||
vm.ensure_slots(1);
|
vm.ensure_slots(1);
|
||||||
set(vm, 0, ret);
|
if constexpr (std::is_fundamental<R>::value) {
|
||||||
|
set(vm, 0, ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ModuleAndName wren_name = wren_class_name_from_type<R>(vm);
|
||||||
|
R* const new_object = make_wren_object<R>(vm, wren_name, std::move(ret));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ wrenpp = library(meson.project_name(),
|
||||||
'src/vm_fun.cpp',
|
'src/vm_fun.cpp',
|
||||||
'src/callback_manager.cpp',
|
'src/callback_manager.cpp',
|
||||||
'src/class_manager.cpp',
|
'src/class_manager.cpp',
|
||||||
|
'src/wren_class_name_from_type.cpp',
|
||||||
dependencies: [wren_dep],
|
dependencies: [wren_dep],
|
||||||
include_directories: public_incl,
|
include_directories: public_incl,
|
||||||
install: (not meson.is_subproject() or get_option('default_library')=='shared'),
|
install: (not meson.is_subproject() or get_option('default_library')=='shared'),
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "wrenpp/class_manager.hpp"
|
#include "wrenpp/class_manager.hpp"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace wren {
|
namespace wren {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -36,6 +37,15 @@ namespace wren {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClassNameOwning::operator ModuleAndName() const {
|
||||||
|
return ModuleAndName{
|
||||||
|
this->raw_buffer(),
|
||||||
|
0, //TODO: replace with hash
|
||||||
|
this->module_name().size(),
|
||||||
|
this->class_name().size()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
bool ClassNameOwning::operator== (const ClassNameOwning& other) const {
|
bool ClassNameOwning::operator== (const ClassNameOwning& other) const {
|
||||||
return
|
return
|
||||||
*static_cast<const ClassNameBase*>(this) == static_cast<const ClassNameBase&>(other) or
|
*static_cast<const ClassNameBase*>(this) == static_cast<const ClassNameBase&>(other) or
|
||||||
|
@ -74,19 +84,6 @@ namespace wren {
|
||||||
ClassManager::ClassManager() = default;
|
ClassManager::ClassManager() = default;
|
||||||
ClassManager::~ClassManager() noexcept = default;
|
ClassManager::~ClassManager() noexcept = default;
|
||||||
|
|
||||||
ClassManager& ClassManager::add_class_maker (std::string_view module_name, std::string_view class_name, make_foreign_class_t maker) {
|
|
||||||
using detail::TempClassName;
|
|
||||||
using detail::ClassNameOwning;
|
|
||||||
|
|
||||||
auto it_found = m_classes.find(TempClassName{module_name, class_name});
|
|
||||||
if (m_classes.cend() == it_found)
|
|
||||||
m_classes.insert(it_found, std::make_pair(ClassNameOwning{module_name, class_name}, maker));
|
|
||||||
else
|
|
||||||
it_found->second = maker;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign_class_t ClassManager::make_class (std::string_view module_name, std::string_view class_name) {
|
foreign_class_t ClassManager::make_class (std::string_view module_name, std::string_view class_name) {
|
||||||
using detail::TempClassName;
|
using detail::TempClassName;
|
||||||
|
|
||||||
|
@ -96,4 +93,47 @@ namespace wren {
|
||||||
else
|
else
|
||||||
return {nullptr, nullptr};
|
return {nullptr, nullptr};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto ClassManager::add_class_maker_implem (
|
||||||
|
std::string_view module_name,
|
||||||
|
std::string_view class_name,
|
||||||
|
make_foreign_class_t maker
|
||||||
|
) -> ClassMap::const_iterator {
|
||||||
|
using detail::TempClassName;
|
||||||
|
using detail::ClassNameOwning;
|
||||||
|
|
||||||
|
auto it_found = m_classes.find(TempClassName{module_name, class_name});
|
||||||
|
ClassMap::const_iterator retval;
|
||||||
|
if (m_classes.cend() == it_found) {
|
||||||
|
retval = m_classes.insert(
|
||||||
|
it_found,
|
||||||
|
std::make_pair(ClassNameOwning{module_name, class_name}, maker)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
it_found->second = maker;
|
||||||
|
retval = it_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassManager::add_type (ClassManagerNameHashType hash, const detail::ClassNameOwning* name) {
|
||||||
|
using detail::TempClassName;
|
||||||
|
|
||||||
|
assert(m_types.count(hash) == 0 or m_types.at(hash) == name);
|
||||||
|
//insert if not present, leave old value if hash is already there
|
||||||
|
m_types.insert(std::make_pair(hash, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleAndName ClassManager::wren_class_name_from_hash(ClassManagerNameHashType hash) const {
|
||||||
|
const auto it_found = m_types.find(hash);
|
||||||
|
if (m_types.cend() != it_found) {
|
||||||
|
const detail::ClassNameOwning* const name = it_found->second;
|
||||||
|
return *name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
} //namespace wren
|
} //namespace wren
|
||||||
|
|
|
@ -289,6 +289,7 @@ namespace wren {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VM::has_module(const char* module) const noexcept {
|
bool VM::has_module(const char* module) const noexcept {
|
||||||
|
assert(module);
|
||||||
return wrenHasModule(m_local->wvm, module);
|
return wrenHasModule(m_local->wvm, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,10 +349,18 @@ namespace wren {
|
||||||
return m_local->callback_manager;
|
return m_local->callback_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CallbackManager& VM::callback_manager() const {
|
||||||
|
return m_local->callback_manager;
|
||||||
|
}
|
||||||
|
|
||||||
ClassManager& VM::class_manager() {
|
ClassManager& VM::class_manager() {
|
||||||
return m_local->class_manager;
|
return m_local->class_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ClassManager& VM::class_manager() const {
|
||||||
|
return m_local->class_manager;
|
||||||
|
}
|
||||||
|
|
||||||
void VM::ensure_slots (int num_slots) {
|
void VM::ensure_slots (int num_slots) {
|
||||||
wrenEnsureSlots(m_local->wvm, num_slots);
|
wrenEnsureSlots(m_local->wvm, num_slots);
|
||||||
}
|
}
|
||||||
|
|
14
src/wren_class_name_from_type.cpp
Normal file
14
src/wren_class_name_from_type.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "wrenpp/detail/wren_class_name_from_type.hpp"
|
||||||
|
#include "wrenpp/vm.hpp"
|
||||||
|
#include "wrenpp/class_manager.hpp"
|
||||||
|
|
||||||
|
namespace wren {
|
||||||
|
namespace detail {
|
||||||
|
ModuleAndName fetch_class_name_from_manager (
|
||||||
|
const VM& vm,
|
||||||
|
ClassManagerNameHashType hash
|
||||||
|
) {
|
||||||
|
return vm.class_manager().wren_class_name_from_hash(hash);
|
||||||
|
}
|
||||||
|
} //namespace detail
|
||||||
|
} //namespace wren
|
Loading…
Reference in a new issue