Add support for registering foreign methods that return foreign objects

Still a bit work in progress but functioning
This commit is contained in:
King_DuckZ 2022-05-18 18:48:18 +02:00
commit 1fa6d62f17
15 changed files with 264 additions and 45 deletions

View file

@ -16,6 +16,7 @@
*/
#include "wrenpp/class_manager.hpp"
#include <cassert>
namespace wren {
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 {
return
*static_cast<const ClassNameBase*>(this) == static_cast<const ClassNameBase&>(other) or
@ -74,19 +84,6 @@ namespace wren {
ClassManager::ClassManager() = 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) {
using detail::TempClassName;
@ -96,4 +93,47 @@ namespace wren {
else
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

View file

@ -289,6 +289,7 @@ namespace wren {
}
bool VM::has_module(const char* module) const noexcept {
assert(module);
return wrenHasModule(m_local->wvm, module);
}
@ -348,10 +349,18 @@ namespace wren {
return m_local->callback_manager;
}
const CallbackManager& VM::callback_manager() const {
return m_local->callback_manager;
}
ClassManager& VM::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) {
wrenEnsureSlots(m_local->wvm, num_slots);
}

View 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