فهرست منبع

world: use ListNode to maintain the list of callbacks

Daniele Bartolini 7 سال پیش
والد
کامیت
fa115b6687

+ 6 - 2
src/world/animation_state_machine.cpp

@@ -29,12 +29,16 @@ AnimationStateMachine::AnimationStateMachine(Allocator& a, ResourceManager& rm,
 	, _animations(a)
 	, _animations(a)
 	, _events(a)
 	, _events(a)
 {
 {
-	um.register_destroy_function(unit_destroyed_callback_bridge, this);
+	_unit_destroy_callback.destroy = unit_destroyed_callback_bridge;
+	_unit_destroy_callback.user_data = this;
+	_unit_destroy_callback.node.next = NULL;
+	_unit_destroy_callback.node.prev = NULL;
+	um.register_destroy_callback(&_unit_destroy_callback);
 }
 }
 
 
 AnimationStateMachine::~AnimationStateMachine()
 AnimationStateMachine::~AnimationStateMachine()
 {
 {
-	_unit_manager->unregister_destroy_function(this);
+	_unit_manager->unregister_destroy_callback(&_unit_destroy_callback);
 	_marker = 0;
 	_marker = 0;
 }
 }
 
 

+ 1 - 0
src/world/animation_state_machine.h

@@ -41,6 +41,7 @@ struct AnimationStateMachine
 	HashMap<UnitId, u32> _map;
 	HashMap<UnitId, u32> _map;
 	Array<Animation> _animations;
 	Array<Animation> _animations;
 	EventStream _events;
 	EventStream _events;
+	UnitDestroyCallback _unit_destroy_callback;
 
 
 	///
 	///
 	AnimationStateMachine(Allocator& a, ResourceManager& rm, UnitManager& um);
 	AnimationStateMachine(Allocator& a, ResourceManager& rm, UnitManager& um);

+ 1 - 0
src/world/gui.h

@@ -5,6 +5,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include "core/list.h"
 #include "core/math/types.h"
 #include "core/math/types.h"
 #include "resource/types.h"
 #include "resource/types.h"
 #include "world/types.h"
 #include "world/types.h"

+ 1 - 0
src/world/level.h

@@ -6,6 +6,7 @@
 #pragma once
 #pragma once
 
 
 #include "core/containers/types.h"
 #include "core/containers/types.h"
+#include "core/list.h"
 #include "core/math/types.h"
 #include "core/math/types.h"
 #include "core/memory/types.h"
 #include "core/memory/types.h"
 #include "resource/types.h"
 #include "resource/types.h"

+ 7 - 2
src/world/physics_world_bullet.cpp

@@ -192,6 +192,7 @@ struct PhysicsWorldImpl
 	MyDebugDrawer _debug_drawer;
 	MyDebugDrawer _debug_drawer;
 
 
 	EventStream _events;
 	EventStream _events;
+	UnitDestroyCallback _unit_destroy_callback;
 
 
 	const PhysicsConfigResource* _config_resource;
 	const PhysicsConfigResource* _config_resource;
 	bool _debug_drawing;
 	bool _debug_drawing;
@@ -221,12 +222,16 @@ struct PhysicsWorldImpl
 
 
 		_config_resource = (const PhysicsConfigResource*)rm.get(RESOURCE_TYPE_PHYSICS_CONFIG, StringId64("global"));
 		_config_resource = (const PhysicsConfigResource*)rm.get(RESOURCE_TYPE_PHYSICS_CONFIG, StringId64("global"));
 
 
-		um.register_destroy_function(PhysicsWorldImpl::unit_destroyed_callback, this);
+		_unit_destroy_callback.destroy = PhysicsWorldImpl::unit_destroyed_callback;
+		_unit_destroy_callback.user_data = this;
+		_unit_destroy_callback.node.next = NULL;
+		_unit_destroy_callback.node.prev = NULL;
+		um.register_destroy_callback(&_unit_destroy_callback);
 	}
 	}
 
 
 	~PhysicsWorldImpl()
 	~PhysicsWorldImpl()
 	{
 	{
-		_unit_manager->unregister_destroy_function(this);
+		_unit_manager->unregister_destroy_callback(&_unit_destroy_callback);
 
 
 		for (u32 i = 0; i < array::size(_actor); ++i)
 		for (u32 i = 0; i < array::size(_actor); ++i)
 		{
 		{

+ 6 - 2
src/world/render_world.cpp

@@ -38,7 +38,11 @@ RenderWorld::RenderWorld(Allocator& a, ResourceManager& rm, ShaderManager& sm, M
 	, _sprite_manager(a)
 	, _sprite_manager(a)
 	, _light_manager(a)
 	, _light_manager(a)
 {
 {
-	um.register_destroy_function(unit_destroyed_callback_bridge, this);
+	_unit_destroy_callback.destroy = unit_destroyed_callback_bridge;
+	_unit_destroy_callback.user_data = this;
+	_unit_destroy_callback.node.next = NULL;
+	_unit_destroy_callback.node.prev = NULL;
+	um.register_destroy_callback(&_unit_destroy_callback);
 
 
 	_u_light_position  = bgfx::createUniform("u_light_position", bgfx::UniformType::Vec4);
 	_u_light_position  = bgfx::createUniform("u_light_position", bgfx::UniformType::Vec4);
 	_u_light_direction = bgfx::createUniform("u_light_direction", bgfx::UniformType::Vec4);
 	_u_light_direction = bgfx::createUniform("u_light_direction", bgfx::UniformType::Vec4);
@@ -49,7 +53,7 @@ RenderWorld::RenderWorld(Allocator& a, ResourceManager& rm, ShaderManager& sm, M
 
 
 RenderWorld::~RenderWorld()
 RenderWorld::~RenderWorld()
 {
 {
-	_unit_manager->unregister_destroy_function(this);
+	_unit_manager->unregister_destroy_callback(&_unit_destroy_callback);
 
 
 	bgfx::destroy(_u_light_intensity);
 	bgfx::destroy(_u_light_intensity);
 	bgfx::destroy(_u_light_range);
 	bgfx::destroy(_u_light_range);

+ 2 - 0
src/world/render_world.h

@@ -295,6 +295,8 @@ struct RenderWorld
 	MeshManager _mesh_manager;
 	MeshManager _mesh_manager;
 	SpriteManager _sprite_manager;
 	SpriteManager _sprite_manager;
 	LightManager _light_manager;
 	LightManager _light_manager;
+
+	UnitDestroyCallback _unit_destroy_callback;
 };
 };
 
 
 } // namespace crown
 } // namespace crown

+ 6 - 2
src/world/scene_graph.cpp

@@ -41,12 +41,16 @@ SceneGraph::SceneGraph(Allocator& a, UnitManager& um)
 	, _unit_manager(&um)
 	, _unit_manager(&um)
 	, _map(a)
 	, _map(a)
 {
 {
-	um.register_destroy_function(unit_destroyed_callback_bridge, this);
+	_unit_destroy_callback.destroy = unit_destroyed_callback_bridge;
+	_unit_destroy_callback.user_data = this;
+	_unit_destroy_callback.node.next = NULL;
+	_unit_destroy_callback.node.prev = NULL;
+	um.register_destroy_callback(&_unit_destroy_callback);
 }
 }
 
 
 SceneGraph::~SceneGraph()
 SceneGraph::~SceneGraph()
 {
 {
-	_unit_manager->unregister_destroy_function(this);
+	_unit_manager->unregister_destroy_callback(&_unit_destroy_callback);
 
 
 	_allocator->deallocate(_data.buffer);
 	_allocator->deallocate(_data.buffer);
 
 

+ 1 - 0
src/world/scene_graph.h

@@ -63,6 +63,7 @@ struct SceneGraph
 	UnitManager* _unit_manager;
 	UnitManager* _unit_manager;
 	InstanceData _data;
 	InstanceData _data;
 	HashMap<UnitId, u32> _map;
 	HashMap<UnitId, u32> _map;
+	UnitDestroyCallback _unit_destroy_callback;
 
 
 	///
 	///
 	SceneGraph(Allocator& a, UnitManager& um);
 	SceneGraph(Allocator& a, UnitManager& um);

+ 6 - 2
src/world/script_world.cpp

@@ -207,12 +207,16 @@ ScriptWorld::ScriptWorld(Allocator& a, UnitManager& um, ResourceManager& rm, Lua
 	, _lua_environment(&le)
 	, _lua_environment(&le)
 	, _world(&w)
 	, _world(&w)
 {
 {
-	um.register_destroy_function(script_world_internal::unit_destroyed_callback_bridge, this);
+	_unit_destroy_callback.destroy = script_world_internal::unit_destroyed_callback_bridge;
+	_unit_destroy_callback.user_data = this;
+	_unit_destroy_callback.node.next = NULL;
+	_unit_destroy_callback.node.prev = NULL;
+	um.register_destroy_callback(&_unit_destroy_callback);
 }
 }
 
 
 ScriptWorld::~ScriptWorld()
 ScriptWorld::~ScriptWorld()
 {
 {
-	_unit_manager->unregister_destroy_function(this);
+	_unit_manager->unregister_destroy_callback(&_unit_destroy_callback);
 	_marker = 0;
 	_marker = 0;
 }
 }
 
 

+ 1 - 0
src/world/script_world.h

@@ -36,6 +36,7 @@ struct ScriptWorld
 	ResourceManager* _resource_manager;
 	ResourceManager* _resource_manager;
 	LuaEnvironment* _lua_environment;
 	LuaEnvironment* _lua_environment;
 	World* _world;
 	World* _world;
+	UnitDestroyCallback _unit_destroy_callback;
 
 
 	ScriptWorld(Allocator& a, UnitManager& um, ResourceManager& rm, LuaEnvironment& le, World& w);
 	ScriptWorld(Allocator& a, UnitManager& um, ResourceManager& rm, LuaEnvironment& le, World& w);
 	~ScriptWorld();
 	~ScriptWorld();

+ 9 - 0
src/world/types.h

@@ -252,6 +252,15 @@ struct hash<UnitId>
 	}
 	}
 };
 };
 
 
+typedef void (*UnitDestroyFunction)(UnitId unit, void* user_data);
+
+struct UnitDestroyCallback
+{
+	UnitDestroyFunction destroy;
+	void* user_data;
+	ListNode node;
+};
+
 #define INSTANCE_ID(name)            \
 #define INSTANCE_ID(name)            \
 	struct name                      \
 	struct name                      \
 	{                                \
 	{                                \

+ 12 - 20
src/world/unit_manager.cpp

@@ -15,8 +15,8 @@ namespace crown
 UnitManager::UnitManager(Allocator& a)
 UnitManager::UnitManager(Allocator& a)
 	: _generation(a)
 	: _generation(a)
 	, _free_indices(a)
 	, _free_indices(a)
-	, _destroy_callbacks(a)
 {
 {
+	list::init_head(_callbacks.node);
 }
 }
 
 
 UnitId UnitManager::make_unit(u32 idx, u8 gen)
 UnitId UnitManager::make_unit(u32 idx, u8 gen)
@@ -63,33 +63,25 @@ void UnitManager::destroy(UnitId id)
 	trigger_destroy_callbacks(id);
 	trigger_destroy_callbacks(id);
 }
 }
 
 
-void UnitManager::register_destroy_function(DestroyFunction fn, void* user_data)
+void UnitManager::register_destroy_callback(UnitDestroyCallback* udc)
 {
 {
-	DestroyData dd;
-	dd.destroy = fn;
-	dd.user_data = user_data;
-	array::push_back(_destroy_callbacks, dd);
+	list::add(udc->node, _callbacks.node);
 }
 }
 
 
-void UnitManager::unregister_destroy_function(void* user_data)
+void UnitManager::unregister_destroy_callback(UnitDestroyCallback* udc)
 {
 {
-	for (u32 i = 0, n = array::size(_destroy_callbacks); i < n; ++i)
-	{
-		if (_destroy_callbacks[i].user_data == user_data)
-		{
-			_destroy_callbacks[i] = _destroy_callbacks[n - 1];
-			array::pop_back(_destroy_callbacks);
-			return;
-		}
-	}
-
-	CE_FATAL("Unknown destroy function");
+	list::remove(udc->node);
 }
 }
 
 
 void UnitManager::trigger_destroy_callbacks(UnitId id)
 void UnitManager::trigger_destroy_callbacks(UnitId id)
 {
 {
-	for (u32 i = 0; i < array::size(_destroy_callbacks); ++i)
-		_destroy_callbacks[i].destroy(id, _destroy_callbacks[i].user_data);
+	ListNode* cur = _callbacks.node.next;
+	while (cur != &_callbacks.node)
+	{
+		UnitDestroyCallback* udc = (UnitDestroyCallback*)container_of(cur, UnitDestroyCallback, node);
+		udc->destroy(id, udc->user_data);
+		cur = cur->next;
+	}
 }
 }
 
 
 } // namespace crown
 } // namespace crown

+ 6 - 11
src/world/unit_manager.h

@@ -17,17 +17,9 @@ namespace crown
 /// @ingroup World
 /// @ingroup World
 struct UnitManager
 struct UnitManager
 {
 {
-	typedef void (*DestroyFunction)(UnitId unit, void* user_data);
-
-	struct DestroyData
-	{
-		DestroyFunction destroy;
-		void* user_data;
-	};
-
 	Array<u8> _generation;
 	Array<u8> _generation;
 	Queue<u32> _free_indices;
 	Queue<u32> _free_indices;
-	Array<DestroyData> _destroy_callbacks;
+	UnitDestroyCallback _callbacks;
 
 
 	///
 	///
 	UnitManager(Allocator& a);
 	UnitManager(Allocator& a);
@@ -47,10 +39,13 @@ struct UnitManager
 	/// Destroys the unit @a id.
 	/// Destroys the unit @a id.
 	void destroy(UnitId id);
 	void destroy(UnitId id);
 
 
-	void register_destroy_function(DestroyFunction fn, void* user_data);
+	///
+	void register_destroy_callback(UnitDestroyCallback* udc);
 
 
-	void unregister_destroy_function(void* user_data);
+	///
+	void unregister_destroy_callback(UnitDestroyCallback* udc);
 
 
+	///
 	void trigger_destroy_callbacks(UnitId id);
 	void trigger_destroy_callbacks(UnitId id);
 };
 };