summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/world.cpp13
-rw-r--r--src/world.hpp10
2 files changed, 19 insertions, 4 deletions
diff --git a/src/world.cpp b/src/world.cpp
index 028ddd45..54096608 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -78,6 +78,9 @@ world::~world() noexcept
world::world(size_t capacity) : _chunks{capacity}
{
_chunks.max_load_factor(max_load_factor);
+ _chunks.reserve(initial_capacity);
+ _entities.max_load_factor(max_load_factor);
+ _entities.reserve(initial_capacity);
}
chunk& world::operator[](chunk_coords_ coord) noexcept
@@ -112,9 +115,14 @@ bool world::contains(chunk_coords_ c) const noexcept
void world::clear()
{
+ fm_assert(!_teardown);
_last_collection = 0;
_chunks.clear();
_chunks.rehash(initial_capacity);
+ _entities.clear();
+ _entities.rehash(initial_capacity);
+ _collect_every = initial_collect_every;
+ _entity_counter = entity_counter_init;
auto& [c, pos] = _last_chunk;
c = nullptr;
pos = chunk_tuple::invalid_coords;
@@ -183,4 +191,9 @@ void world::set_entity_counter(object_id value)
_entity_counter = value;
}
+void world::throw_on_wrong_entity_type(object_id id, entity_type actual, entity_type expected)
+{
+ fm_throw("object '{}' has wrong entity type '{}', should be '{}'"_cf, id, (size_t)actual, (size_t)expected);
+}
+
} // namespace floormat
diff --git a/src/world.hpp b/src/world.hpp
index 2dce958c..1379d820 100644
--- a/src/world.hpp
+++ b/src/world.hpp
@@ -3,7 +3,6 @@
#include "chunk.hpp"
#include "global-coords.hpp"
#include "entity-type.hpp"
-#include "compat/exception.hpp"
#include "compat/int-hash.hpp"
#include <memory>
#include <unordered_map>
@@ -25,8 +24,9 @@ struct object_id_hasher {
struct world final
{
static constexpr object_id entity_counter_init = 1024;
- static constexpr size_t initial_capacity = 64;
+ static constexpr size_t initial_capacity = 512;
static constexpr float max_load_factor = .5;
+ static constexpr size_t initial_collect_every = 64;
private:
struct chunk_tuple final {
@@ -38,7 +38,7 @@ private:
std::unordered_map<chunk_coords_, chunk> _chunks;
tsl::robin_map<object_id, std::weak_ptr<entity>, object_id_hasher> _entities;
size_t _last_collection = 0;
- size_t _collect_every = 64;
+ size_t _collect_every = initial_collect_every;
std::shared_ptr<char> _unique_id = std::make_shared<char>('A');
object_id _entity_counter = entity_counter_init;
uint64_t _current_frame = 1; // zero is special for struct entity
@@ -49,6 +49,7 @@ private:
void do_make_entity(const std::shared_ptr<entity>& e, global_coords pos, bool sorted);
void do_kill_entity(object_id id);
std::shared_ptr<entity> find_entity_(object_id id);
+ [[noreturn]] static void throw_on_wrong_entity_type(object_id id, entity_type actual, entity_type expected);
friend struct entity;
@@ -114,7 +115,8 @@ std::shared_ptr<T> world::find_entity(object_id id)
return ptr;
else
{
- fm_soft_assert(ptr->type() == entity_type_<T>::value);
+ if (!(ptr->type() == entity_type_<T>::value)) [[unlikely]]
+ throw_on_wrong_entity_type(id, ptr->type(), entity_type_<T>::value);
return std::static_pointer_cast<T>(std::move(ptr));
}
}