diff --git a/furvm/include/furvm/context.hpp b/furvm/include/furvm/context.hpp index 06bc379..e48c673 100644 --- a/furvm/include/furvm/context.hpp +++ b/furvm/include/furvm/context.hpp @@ -5,6 +5,7 @@ #include "furvm/fwd.hpp" #include "furvm/module.hpp" +#include #include #include @@ -21,12 +22,12 @@ public: /** * @brief Move constructor. */ - context(context&&) = default; + context(context&&) noexcept = default; /** * @brief Move constructor. */ - context& operator=(context&&) = default; + context& operator=(context&&) noexcept = default; context(const context&) = delete; context& operator=(const context&) = delete; @@ -97,8 +98,9 @@ private: std::vector m_things; std::vector m_executors; - std::vector m_deadThings; - furlang::arena m_thingArena; + std::queue m_deadThings; + std::vector m_deadThingData; + furlang::arena m_thingArena; }; } // namespace furvm diff --git a/furvm/include/furvm/thing.hpp b/furvm/include/furvm/thing.hpp index 934d18f..15dcdd5 100644 --- a/furvm/include/furvm/thing.hpp +++ b/furvm/include/furvm/thing.hpp @@ -50,7 +50,7 @@ public: const char* what() const noexcept override { return "bad thing access"; } }; -class thing { +class thing final { friend class executor; private: /** @@ -61,6 +61,8 @@ private: struct rzecz { explicit rzecz() = default; }; +public: + static constexpr thing_handle GENERATION_SIZE = 12; /**< Bit size of generation part in thing_handle. */ public: /** * @brief Private constructor. diff --git a/furvm/src/thing.cpp b/furvm/src/thing.cpp index 32dc7b0..f13cbe6 100644 --- a/furvm/src/thing.cpp +++ b/furvm/src/thing.cpp @@ -21,12 +21,13 @@ thing::thing(rzecz, thing_handle id, thing_t type, const context_p& context) : m_id(id), m_type(type), m_context(context) { std::size_t size = thing_type_size(type); std::byte* data = nullptr; - if (!m_context->m_deadThings.empty()) { + if (!m_context->m_deadThingData.empty()) { thing_t itType{}; - for (auto it = m_context->m_deadThings.rbegin(); it != m_context->m_deadThings.rend(); ++it) { + for (auto it = m_context->m_deadThingData.rbegin(); it != m_context->m_deadThingData.rend(); ++it) { std::memcpy(&itType, static_cast(*it) - sizeof(itType), sizeof(itType)); if (size == thing_type_size(itType)) { data = static_cast(*it); + m_context->m_deadThingData.erase(std::next(it).base()); break; } } @@ -40,12 +41,20 @@ thing::thing(rzecz, thing_handle id, thing_t type, const context_p& context) } thing::~thing() { - m_context->m_deadThings.push_back(m_data); + m_context->m_deadThingData.push_back(m_data); } thing_p thing::create(const context_p& context, thing_t type) { - auto th = std::make_shared(rzecz{}, context->m_things.size(), type, context); - context->m_things.push_back(th); + thing_handle id = context->m_things.size(); + if (!context->m_deadThings.empty()) { + id = context->m_deadThings.front(); + context->m_deadThings.pop(); + id += 1 << GENERATION_SIZE; + } + thing_handle idx = id & ((1ULL << ((sizeof(id) * 8) - GENERATION_SIZE)) - 1); + + auto th = std::make_shared(rzecz{}, id, type, context); + context->m_things.emplace(context->m_things.begin() + idx, th); return std::move(th); }