Bladeren bron

world: unit reloading skeleton

Daniele Bartolini 5 maanden geleden
bovenliggende
commit
eefbce2db1
3 gewijzigde bestanden met toevoegingen van 66 en 3 verwijderingen
  1. 8 0
      src/device/device.cpp
  2. 48 3
      src/world/world.cpp
  3. 10 0
      src/world/world.h

+ 8 - 0
src/device/device.cpp

@@ -870,6 +870,7 @@ void Device::refresh(const char *json)
 			|| resource_type == RESOURCE_TYPE_SHADER
 			|| resource_type == RESOURCE_TYPE_SHADER
 			|| resource_type == RESOURCE_TYPE_MATERIAL
 			|| resource_type == RESOURCE_TYPE_MATERIAL
 			|| resource_type == RESOURCE_TYPE_RENDER_CONFIG
 			|| resource_type == RESOURCE_TYPE_RENDER_CONFIG
+			|| resource_type == RESOURCE_TYPE_UNIT
 			;
 			;
 
 
 		if (is_type_reloadable && _resource_manager->can_get(resource_type, resource_name)) {
 		if (is_type_reloadable && _resource_manager->can_get(resource_type, resource_name)) {
@@ -896,6 +897,13 @@ void Device::refresh(const char *json)
 					_pipeline->destroy();
 					_pipeline->destroy();
 					_pipeline->create(_width, _height, _render_config_resource->render_settings);
 					_pipeline->create(_width, _height, _render_config_resource->render_settings);
 				}
 				}
+			} else if (resource_type == RESOURCE_TYPE_UNIT) {
+				ListNode *cur;
+				list_for_each(cur, &_worlds)
+				{
+					World *w = (World *)container_of(cur, World, _node);
+					w->reload_units((UnitResource *)old_resource, (UnitResource *)new_resource);
+				}
 			}
 			}
 		}
 		}
 	}
 	}

+ 48 - 3
src/world/world.cpp

@@ -185,6 +185,9 @@ World::World(Allocator &a
 	, _changed_world(a)
 	, _changed_world(a)
 	, _gui_buffer(sm)
 	, _gui_buffer(sm)
 	, _skydome_unit(UNIT_INVALID)
 	, _skydome_unit(UNIT_INVALID)
+#if CROWN_CAN_RELOAD
+	, _unit_resources(a)
+#endif
 {
 {
 	_lines = create_debug_line(true);
 	_lines = create_debug_line(true);
 	_scene_graph   = CE_NEW(*_allocator, SceneGraph)(*_allocator, um);
 	_scene_graph   = CE_NEW(*_allocator, SceneGraph)(*_allocator, um);
@@ -234,10 +237,8 @@ World::~World()
 	_marker = 0;
 	_marker = 0;
 }
 }
 
 
-UnitId World::spawn_unit(StringId64 name, const Vector3 &pos, const Quaternion &rot, const Vector3 &scl)
+UnitId World::spawn_unit(const UnitResource *ur, const Vector3 &pos, const Quaternion &rot, const Vector3 &scl)
 {
 {
-	const UnitResource *ur = (UnitResource *)_resource_manager->get(RESOURCE_TYPE_UNIT, name);
-
 	UnitId *unit_lookup = (UnitId *)default_scratch_allocator().allocate(sizeof(*unit_lookup) * ur->num_units);
 	UnitId *unit_lookup = (UnitId *)default_scratch_allocator().allocate(sizeof(*unit_lookup) * ur->num_units);
 	for (u32 i = 0; i < ur->num_units; ++i)
 	for (u32 i = 0; i < ur->num_units; ++i)
 		unit_lookup[i] = _unit_manager->create();
 		unit_lookup[i] = _unit_manager->create();
@@ -245,6 +246,10 @@ UnitId World::spawn_unit(StringId64 name, const Vector3 &pos, const Quaternion &
 	create_components(*this, ur, pos, rot, scl, unit_lookup);
 	create_components(*this, ur, pos, rot, scl, unit_lookup);
 
 
 	array::push(_units, unit_lookup, ur->num_units);
 	array::push(_units, unit_lookup, ur->num_units);
+#if CROWN_CAN_RELOAD
+	for (u32 i = 0; i < ur->num_units; ++i)
+		array::push_back(_unit_resources, ur);
+#endif
 	post_unit_spawned_events(unit_lookup, ur->num_units);
 	post_unit_spawned_events(unit_lookup, ur->num_units);
 
 
 	UnitId root_unit = unit_lookup[0];
 	UnitId root_unit = unit_lookup[0];
@@ -252,10 +257,19 @@ UnitId World::spawn_unit(StringId64 name, const Vector3 &pos, const Quaternion &
 	return root_unit;
 	return root_unit;
 }
 }
 
 
+UnitId World::spawn_unit(StringId64 name, const Vector3 &pos, const Quaternion &rot, const Vector3 &scl)
+{
+	const UnitResource *ur = (UnitResource *)_resource_manager->get(RESOURCE_TYPE_UNIT, name);
+	return spawn_unit(ur, pos, rot, scl);
+}
+
 UnitId World::spawn_empty_unit()
 UnitId World::spawn_empty_unit()
 {
 {
 	UnitId unit = _unit_manager->create();
 	UnitId unit = _unit_manager->create();
 	array::push_back(_units, unit);
 	array::push_back(_units, unit);
+#if CROWN_CAN_RELOAD
+	array::push_back(_unit_resources, (const UnitResource *)NULL);
+#endif
 	post_unit_spawned_events(&unit, 1);
 	post_unit_spawned_events(&unit, 1);
 	return unit;
 	return unit;
 }
 }
@@ -275,6 +289,10 @@ void World::destroy_unit(UnitId unit)
 		if (_units[i] == unit) {
 		if (_units[i] == unit) {
 			_units[i] = _units[n - 1];
 			_units[i] = _units[n - 1];
 			array::pop_back(_units);
 			array::pop_back(_units);
+#if CROWN_CAN_RELOAD
+			_unit_resources[i] = _unit_resources[n - 1];
+			array::pop_back(_unit_resources);
+#endif
 			break;
 			break;
 		}
 		}
 	}
 	}
@@ -763,4 +781,31 @@ void World::reload_materials(const MaterialResource *old_resource, const Materia
 #endif
 #endif
 }
 }
 
 
+void World::reload_units(const UnitResource *old_unit, const UnitResource *new_unit)
+{
+#if CROWN_CAN_RELOAD
+	for (u32 i = 0; i < array::size(_unit_resources); ++i) {
+		if (_unit_resources[i] == old_unit) {
+			Vector3 pos = VECTOR3_ZERO;
+			Quaternion rot = QUATERNION_IDENTITY;
+			Vector3 scl = VECTOR3_ONE;
+			TransformInstance ti = _scene_graph->instance(_units[i]);
+
+			if (is_valid(ti)) {
+				pos = _scene_graph->local_position(ti);
+				rot = _scene_graph->local_rotation(ti);
+				scl = _scene_graph->local_scale(ti);
+			}
+
+			_unit_manager->trigger_destroy_callbacks(_units[i]);
+			create_components(*this, new_unit, pos, rot, scl, &_units[i]);
+			_unit_resources[i] = new_unit;
+		}
+	}
+#else
+	CE_UNUSED_2(old_unit, new_unit);
+	CE_NOOP();
+#endif // if CROWN_CAN_RELOAD
+}
+
 } // namespace crown
 } // namespace crown

+ 10 - 0
src/world/world.h

@@ -71,6 +71,10 @@ struct World
 	ListNode _node;
 	ListNode _node;
 	UnitId _skydome_unit;
 	UnitId _skydome_unit;
 
 
+#if CROWN_CAN_RELOAD
+	Array<const UnitResource *> _unit_resources;
+#endif
+
 	CameraInstance camera_make_instance(u32 i)
 	CameraInstance camera_make_instance(u32 i)
 	{
 	{
 		CameraInstance inst = { i }; return inst;
 		CameraInstance inst = { i }; return inst;
@@ -89,6 +93,9 @@ struct World
 	///
 	///
 	~World();
 	~World();
 
 
+	/// Spawns a new instance of the unit @a ur at the given @a position, @a rotation and @a scale.
+	UnitId spawn_unit(const UnitResource *ur, const Vector3 &pos, const Quaternion &rot, const Vector3 &scl);
+
 	/// Spawns a new instance of the unit @a name at the given @a position, @a rotation and @a scale.
 	/// Spawns a new instance of the unit @a name at the given @a position, @a rotation and @a scale.
 	UnitId spawn_unit(StringId64 name, const Vector3 &pos = VECTOR3_ZERO, const Quaternion &rot = QUATERNION_IDENTITY, const Vector3 &scl = VECTOR3_ONE);
 	UnitId spawn_unit(StringId64 name, const Vector3 &pos = VECTOR3_ZERO, const Quaternion &rot = QUATERNION_IDENTITY, const Vector3 &scl = VECTOR3_ONE);
 
 
@@ -229,6 +236,9 @@ struct World
 
 
 	///
 	///
 	void reload_materials(const MaterialResource *old_resource, const MaterialResource *new_resource);
 	void reload_materials(const MaterialResource *old_resource, const MaterialResource *new_resource);
+
+	///
+	void reload_units(const UnitResource *old_unit, const UnitResource *new_unit);
 };
 };
 
 
 } // namespace crown
 } // namespace crown