Skip to content

Commit

Permalink
[kernel] fix: make sure all active objects are properly destroyed.
Browse files Browse the repository at this point in the history
chore: convert ObjectPayload to Variant
  • Loading branch information
jd28 committed Sep 30, 2024
1 parent 4f3db37 commit 8de93ab
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
21 changes: 16 additions & 5 deletions lib/nw/kernel/Objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,20 @@ namespace nw::kernel {

void ObjectSystem::clear()
{
// Clear tag map first
object_tag_map_.clear();

// Make sure all objects are correctly destroyed. Have to do this now that
// the underlying storage is a memory pool that will not itself run destructor.
for (auto& obj : objects_) {
if (obj.is<ObjectBase*>()) {
destroy(obj.as<ObjectBase*>()->handle());
}
}

// Clear the free list
free_list_ = std::stack<ObjectID, std::vector<ObjectID>>();
objects_.clear();
object_tag_map_.clear();
module_.reset();
areas_.clear();
creatures_.clear();
Expand Down Expand Up @@ -78,7 +89,7 @@ void ObjectSystem::destroy(ObjectHandle obj)
{
if (valid(obj)) {
size_t idx = static_cast<size_t>(obj.id);
auto o = std::get<ObjectBase*>(objects_[idx]);
auto o = objects_[idx].as<ObjectBase*>();
auto new_handle = o->handle();

// Delete from tag map
Expand Down Expand Up @@ -146,7 +157,7 @@ ObjectBase* ObjectSystem::get_object_base(ObjectHandle obj) const
{
if (!valid(obj)) { return nullptr; }
auto idx = static_cast<size_t>(obj.id);
return std::get<ObjectBase*>(objects_[idx]);
return objects_[idx].as<ObjectBase*>();
}

ObjectBase* ObjectSystem::get_by_tag(std::string_view tag, int nth) const
Expand Down Expand Up @@ -236,11 +247,11 @@ void ObjectSystem::set_instantiate_callback(void (*callback)(ObjectBase*))
bool ObjectSystem::valid(ObjectHandle handle) const
{
auto idx = static_cast<size_t>(handle.id);
if (idx >= objects_.size() || std::holds_alternative<ObjectHandle>(objects_[idx])) {
if (idx >= objects_.size() || objects_[idx].is<ObjectHandle>()) {
return false;
}

if (auto& obj = std::get<ObjectBase*>(objects_[idx])) {
if (auto obj = objects_[idx].as<ObjectBase*>()) {
return obj->handle() == handle;
}

Expand Down
6 changes: 3 additions & 3 deletions lib/nw/kernel/Objects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

namespace nw::kernel {

using ObjectPayload = std::variant<ObjectHandle, ObjectBase*>;
using ObjectPayload = Variant<ObjectHandle, ObjectBase*>;

struct ObjectSystemStats {
size_t total_objects = 0;
Expand Down Expand Up @@ -156,7 +156,7 @@ T* ObjectSystem::get(ObjectHandle obj)
{
if (!valid(obj) || T::object_type != obj.type) return nullptr;
auto idx = static_cast<size_t>(obj.id);
return static_cast<T*>(std::get<ObjectBase*>(objects_[idx]));
return static_cast<T*>(objects_[idx].as<ObjectBase*>());
}

template <typename T>
Expand All @@ -169,7 +169,7 @@ T* ObjectSystem::make()
auto oid = free_list_.top();
auto idx = static_cast<size_t>(oid);
free_list_.pop();
ObjectHandle oh = std::get<ObjectHandle>(objects_[idx]);
ObjectHandle oh = objects_[idx].as<ObjectHandle>();
oh.type = T::object_type;
obj->set_handle(oh);
objects_[idx] = obj;
Expand Down

0 comments on commit 8de93ab

Please sign in to comment.