Daniele Bartolini 10 rokov pred
rodič
commit
5ec0f27736
2 zmenil súbory, kde vykonal 137 pridanie a 0 odobranie
  1. 84 0
      src/world/unit_manager.cpp
  2. 53 0
      src/world/unit_manager.h

+ 84 - 0
src/world/unit_manager.cpp

@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012-2016 Daniele Bartolini and individual contributors.
+ * License: https://github.com/taylor001/crown/blob/master/LICENSE
+ */
+
+#include "unit_manager.h"
+#include "memory.h"
+#include "array.h"
+#include "queue.h"
+#include "world.h"
+
+#define MINIMUM_FREE_INDICES 1024
+
+namespace crown
+{
+
+UnitManager::UnitManager(Allocator& a)
+	: _generation(a)
+	, _free_indices(a)
+	, _destroy_callbacks(a)
+{
+}
+
+UnitId UnitManager::make_unit(uint32_t idx, uint8_t gen)
+{
+	UnitId id = { 0 | idx | uint32_t(gen) << UNIT_INDEX_BITS };
+	return id;
+}
+
+UnitId UnitManager::create()
+{
+	uint32_t idx;
+
+	if (queue::size(_free_indices) > MINIMUM_FREE_INDICES)
+	{
+		idx = queue::front(_free_indices);
+		queue::pop_front(_free_indices);
+	}
+	else
+	{
+		array::push_back(_generation, uint8_t(0));
+		idx = array::size(_generation) - 1;
+		CE_ASSERT(idx < (1 << UNIT_INDEX_BITS), "Indices out of bounds");
+	}
+
+	return make_unit(idx, _generation[idx]);
+}
+
+UnitId UnitManager::create(World& world)
+{
+	UnitId id = create();
+	world.spawn_empty_unit(id);
+	return id;
+}
+
+bool UnitManager::alive(UnitId id) const
+{
+	return _generation[id.index()] == id.id();
+}
+
+void UnitManager::destroy(UnitId id)
+{
+	const uint32_t idx = id.index();
+	++_generation[idx];
+	queue::push_back(_free_indices, idx);
+
+	trigger_destroy_callbacks(id);
+}
+
+void UnitManager::register_destroy_function(DestroyFunction fn, void* user_ptr)
+{
+	DestroyData dd;
+	dd.destroy = fn;
+	dd.user_ptr = user_ptr;
+	array::push_back(_destroy_callbacks, dd);
+}
+
+void UnitManager::trigger_destroy_callbacks(UnitId id)
+{
+	for (uint32_t i = 0; i < array::size(_destroy_callbacks); ++i)
+		_destroy_callbacks[i].destroy(id, _destroy_callbacks[i].user_ptr);
+}
+
+} // namespace crown

+ 53 - 0
src/world/unit_manager.h

@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012-2016 Daniele Bartolini and individual contributors.
+ * License: https://github.com/taylor001/crown/blob/master/LICENSE
+ */
+
+#pragma once
+
+#include "container_types.h"
+#include "world_types.h"
+
+namespace crown
+{
+
+// http://bitsquid.blogspot.it/2014/08/building-data-oriented-entity-system.html
+class UnitManager
+{
+	Array<uint8_t> _generation;
+	Queue<uint32_t> _free_indices;
+
+	typedef void (*DestroyFunction)(UnitId unit, void* user_ptr);
+
+	struct DestroyData
+	{
+		DestroyFunction destroy;
+		void* user_ptr;
+	};
+
+	Array<DestroyData> _destroy_callbacks;
+
+public:
+
+	UnitManager(Allocator& a);
+
+	UnitId make_unit(uint32_t idx, uint8_t gen);
+
+	/// Creates a new empty unit.
+	UnitId create();
+
+	/// Creates a new empty unit in the given @a world.
+	UnitId create(World& world);
+
+	/// Returns whether the unit @id is alive.
+	bool alive(UnitId id) const;
+
+	/// Destroys the unit @a id.
+	void destroy(UnitId id);
+
+	void register_destroy_function(DestroyFunction fn, void* user_ptr);
+
+	void trigger_destroy_callbacks(UnitId id);
+};
+
+} // namespace crown