Skip to content

Commit

Permalink
Merge pull request #1692 from heinezen/fix/render_entity_threadsafe
Browse files Browse the repository at this point in the history
Fix thread-safe access for render entities
  • Loading branch information
TheJJ authored Oct 31, 2024
2 parents 3db8afd + 8314b6c commit a1fad1c
Show file tree
Hide file tree
Showing 34 changed files with 312 additions and 286 deletions.
4 changes: 2 additions & 2 deletions libopenage/gamestate/game_entity.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022-2023 the openage authors. See copying.md for legal info.
// Copyright 2022-2024 the openage authors. See copying.md for legal info.

#include "game_entity.h"

Expand Down Expand Up @@ -30,7 +30,7 @@ entity_id_t GameEntity::get_id() const {
return this->id;
}

void GameEntity::set_render_entity(const std::shared_ptr<renderer::world::WorldRenderEntity> &entity) {
void GameEntity::set_render_entity(const std::shared_ptr<renderer::world::RenderEntity> &entity) {
// TODO: Transfer state from old render entity to new one?

this->render_entity = entity;
Expand Down
6 changes: 3 additions & 3 deletions libopenage/gamestate/game_entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace openage {

namespace renderer::world {
class WorldRenderEntity;
class RenderEntity;
}

namespace gamestate {
Expand Down Expand Up @@ -62,7 +62,7 @@ class GameEntity {
*
* @param entity New render entity.
*/
void set_render_entity(const std::shared_ptr<renderer::world::WorldRenderEntity> &entity);
void set_render_entity(const std::shared_ptr<renderer::world::RenderEntity> &entity);

/**
* Set the event manager of this entity.
Expand Down Expand Up @@ -142,7 +142,7 @@ class GameEntity {
/**
* Render entity for pushing updates to the renderer. Can be \p nullptr.
*/
std::shared_ptr<renderer::world::WorldRenderEntity> render_entity;
std::shared_ptr<renderer::world::RenderEntity> render_entity;

/**
* Event manager.
Expand Down
2 changes: 1 addition & 1 deletion libopenage/gamestate/terrain_chunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ TerrainChunk::TerrainChunk(const util::Vector2s size,
}
}

void TerrainChunk::set_render_entity(const std::shared_ptr<renderer::terrain::TerrainRenderEntity> &entity) {
void TerrainChunk::set_render_entity(const std::shared_ptr<renderer::terrain::RenderEntity> &entity) {
this->render_entity = entity;
}

Expand Down
4 changes: 2 additions & 2 deletions libopenage/gamestate/terrain_chunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class TerrainChunk {
*
* @param entity New render entity.
*/
void set_render_entity(const std::shared_ptr<renderer::terrain::TerrainRenderEntity> &entity);
void set_render_entity(const std::shared_ptr<renderer::terrain::RenderEntity> &entity);

/**
* Get the size of this terrain chunk.
Expand Down Expand Up @@ -78,7 +78,7 @@ class TerrainChunk {
/**
* Render entity for pushing updates to the renderer. Can be \p nullptr.
*/
std::shared_ptr<renderer::terrain::TerrainRenderEntity> render_entity;
std::shared_ptr<renderer::terrain::RenderEntity> render_entity;
};

} // namespace openage::gamestate
8 changes: 4 additions & 4 deletions libopenage/input/controller/hud/controller.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023-2023 the openage authors. See copying.md for legal info.
// Copyright 2023-2024 the openage authors. See copying.md for legal info.

#include "controller.h"

Expand Down Expand Up @@ -27,19 +27,19 @@ bool Controller::process(const event_arguments &ev_args,
return true;
}

void Controller::set_drag_entity(const std::shared_ptr<renderer::hud::HudDragRenderEntity> &entity) {
void Controller::set_drag_entity(const std::shared_ptr<renderer::hud::DragRenderEntity> &entity) {
this->drag_entity = entity;
}

const std::shared_ptr<renderer::hud::HudDragRenderEntity> &Controller::get_drag_entity() const {
const std::shared_ptr<renderer::hud::DragRenderEntity> &Controller::get_drag_entity() const {
return this->drag_entity;
}

void setup_defaults(const std::shared_ptr<BindingContext> &ctx,
const std::shared_ptr<renderer::hud::HudRenderStage> &hud_renderer) {
binding_func_t drag_selection_init{[&](const event_arguments &args,
const std::shared_ptr<Controller> controller) {
auto render_entity = std::make_shared<renderer::hud::HudDragRenderEntity>(args.mouse);
auto render_entity = std::make_shared<renderer::hud::DragRenderEntity>(args.mouse);
hud_renderer->add_drag_entity(render_entity);
controller->set_drag_entity(render_entity);
}};
Expand Down
8 changes: 4 additions & 4 deletions libopenage/input/controller/hud/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace openage {

namespace renderer::hud {
class HudDragRenderEntity;
class DragRenderEntity;
class HudRenderStage;
} // namespace renderer::hud

Expand Down Expand Up @@ -42,20 +42,20 @@ class Controller : public std::enable_shared_from_this<Controller> {
*
* @param entity New render entity.
*/
void set_drag_entity(const std::shared_ptr<renderer::hud::HudDragRenderEntity> &entity);
void set_drag_entity(const std::shared_ptr<renderer::hud::DragRenderEntity> &entity);

/**
* Get the render entity for the selection box.
*
* @return Render entity for the selection box.
*/
const std::shared_ptr<renderer::hud::HudDragRenderEntity> &get_drag_entity() const;
const std::shared_ptr<renderer::hud::DragRenderEntity> &get_drag_entity() const;

private:
/**
* Render entity for the selection box.
*/
std::shared_ptr<renderer::hud::HudDragRenderEntity> drag_entity;
std::shared_ptr<renderer::hud::DragRenderEntity> drag_entity;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion libopenage/renderer/demo/demo_3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void renderer_demo_3(const util::Path &path) {

// Fill a 10x10 terrain grid with height values
auto terrain_size = util::Vector2s{10, 10};
std::vector<std::pair<terrain::TerrainRenderEntity::terrain_elevation_t, std::string>> tiles{};
std::vector<std::pair<terrain::RenderEntity::terrain_elevation_t, std::string>> tiles{};
tiles.reserve(terrain_size[0] * terrain_size[1]);
for (size_t i = 0; i < terrain_size[0] * terrain_size[1]; ++i) {
tiles.emplace_back(0.0f, "./textures/test_terrain.terrain");
Expand Down
4 changes: 2 additions & 2 deletions libopenage/renderer/demo/stresstest_0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void renderer_stresstest_0(const util::Path &path) {

// Fill a 10x10 terrain grid with height values
auto terrain_size = util::Vector2s{10, 10};
std::vector<std::pair<terrain::TerrainRenderEntity::terrain_elevation_t, std::string>> tiles{};
std::vector<std::pair<terrain::RenderEntity::terrain_elevation_t, std::string>> tiles{};
tiles.reserve(terrain_size[0] * terrain_size[1]);
for (size_t i = 0; i < terrain_size[0] * terrain_size[1]; ++i) {
tiles.emplace_back(0.0f, "./textures/test_terrain.terrain");
Expand All @@ -147,7 +147,7 @@ void renderer_stresstest_0(const util::Path &path) {
terrain0->update(terrain_size, tiles);

// World entities
std::vector<std::shared_ptr<renderer::world::WorldRenderEntity>> render_entities{};
std::vector<std::shared_ptr<renderer::world::RenderEntity>> render_entities{};
auto add_world_entity = [&](const coord::phys3 initial_pos,
const time::time_t time) {
const auto animation_path = "./textures/test_tank_mirrored.sprite";
Expand Down
4 changes: 2 additions & 2 deletions libopenage/renderer/demo/stresstest_1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void renderer_stresstest_1(const util::Path &path) {

// Fill a 10x10 terrain grid with height values
auto terrain_size = util::Vector2s{10, 10};
std::vector<std::pair<terrain::TerrainRenderEntity::terrain_elevation_t, std::string>> tiles{};
std::vector<std::pair<terrain::RenderEntity::terrain_elevation_t, std::string>> tiles{};
tiles.reserve(terrain_size[0] * terrain_size[1]);
for (size_t i = 0; i < terrain_size[0] * terrain_size[1]; ++i) {
tiles.emplace_back(0.0f, "./textures/test_terrain.terrain");
Expand All @@ -151,7 +151,7 @@ void renderer_stresstest_1(const util::Path &path) {
// send the terrain data to the terrain renderer
terrain0->update(terrain_size, tiles);

std::vector<std::shared_ptr<renderer::world::WorldRenderEntity>> render_entities{};
std::vector<std::shared_ptr<renderer::world::RenderEntity>> render_entities{};
auto add_world_entity = [&](const coord::phys3 initial_pos,
const time::time_t time) {
const auto animation_path = "./textures/test_tank_mirrored.sprite";
Expand Down
12 changes: 6 additions & 6 deletions libopenage/renderer/render_factory.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022-2023 the openage authors. See copying.md for legal info.
// Copyright 2022-2024 the openage authors. See copying.md for legal info.

#include "render_factory.h"

Expand All @@ -15,16 +15,16 @@ RenderFactory::RenderFactory(const std::shared_ptr<terrain::TerrainRenderStage>
world_renderer{world_renderer} {
}

std::shared_ptr<terrain::TerrainRenderEntity> RenderFactory::add_terrain_render_entity(const util::Vector2s chunk_size,
const coord::tile_delta chunk_offset) {
auto entity = std::make_shared<terrain::TerrainRenderEntity>();
std::shared_ptr<terrain::RenderEntity> RenderFactory::add_terrain_render_entity(const util::Vector2s chunk_size,
const coord::tile_delta chunk_offset) {
auto entity = std::make_shared<terrain::RenderEntity>();
this->terrain_renderer->add_render_entity(entity, chunk_size, chunk_offset.to_phys2().to_scene2());

return entity;
}

std::shared_ptr<world::WorldRenderEntity> RenderFactory::add_world_render_entity() {
auto entity = std::make_shared<world::WorldRenderEntity>();
std::shared_ptr<world::RenderEntity> RenderFactory::add_world_render_entity() {
auto entity = std::make_shared<world::RenderEntity>();
this->world_renderer->add_render_entity(entity);

return entity;
Expand Down
10 changes: 5 additions & 5 deletions libopenage/renderer/render_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
namespace openage::renderer {
namespace terrain {
class TerrainRenderStage;
class TerrainRenderEntity;
class RenderEntity;
} // namespace terrain

namespace world {
class WorldRenderStage;
class WorldRenderEntity;
class RenderEntity;
} // namespace world

/**
Expand Down Expand Up @@ -47,15 +47,15 @@ class RenderFactory {
*
* @return Render entity for pushing terrain updates.
*/
std::shared_ptr<terrain::TerrainRenderEntity> add_terrain_render_entity(const util::Vector2s chunk_size,
const coord::tile_delta chunk_offset);
std::shared_ptr<terrain::RenderEntity> add_terrain_render_entity(const util::Vector2s chunk_size,
const coord::tile_delta chunk_offset);

/**
* Create a new world render entity and register it at the world renderer.
*
* @return Render entity for pushing terrain updates.
*/
std::shared_ptr<world::WorldRenderEntity> add_world_render_entity();
std::shared_ptr<world::RenderEntity> add_world_render_entity();

private:
/**
Expand Down
4 changes: 4 additions & 0 deletions libopenage/renderer/stages/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
add_sources(libopenage
render_entity.cpp
)

add_subdirectory(camera/)
add_subdirectory(hud/)
add_subdirectory(screen/)
Expand Down
11 changes: 9 additions & 2 deletions libopenage/renderer/stages/hud/object.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023-2023 the openage authors. See copying.md for legal info.
// Copyright 2023-2024 the openage authors. See copying.md for legal info.

#include "object.h"

Expand All @@ -21,7 +21,7 @@ HudDragObject::HudDragObject(const std::shared_ptr<renderer::resources::AssetMan
last_update{0.0} {
}

void HudDragObject::set_render_entity(const std::shared_ptr<HudDragRenderEntity> &entity) {
void HudDragObject::set_render_entity(const std::shared_ptr<DragRenderEntity> &entity) {
this->render_entity = entity;
this->fetch_updates();
}
Expand All @@ -38,8 +38,15 @@ void HudDragObject::fetch_updates(const time::time_t &time) {

// Get data from render entity
this->drag_start = this->render_entity->get_drag_start();

// Thread-safe access to curves needs a lock on the render entity's mutex
auto read_lock = this->render_entity->get_read_lock();

this->drag_pos.sync(this->render_entity->get_drag_pos() /* , this->last_update */);

// Unlock the render entity mutex
read_lock.unlock();

// Set self to changed so that world renderer can update the renderable
this->changed = true;
this->render_entity->clear_changed_flag();
Expand Down
6 changes: 3 additions & 3 deletions libopenage/renderer/stages/hud/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Animation2dInfo;
} // namespace resources

namespace hud {
class HudDragRenderEntity;
class DragRenderEntity;

/**
* Stores the state of a renderable object in the HUD render stage.
Expand All @@ -46,7 +46,7 @@ class HudDragObject {
*
* @param entity New world render entity.
*/
void set_render_entity(const std::shared_ptr<HudDragRenderEntity> &entity);
void set_render_entity(const std::shared_ptr<DragRenderEntity> &entity);

/**
* Set the current camera of the scene.
Expand Down Expand Up @@ -147,7 +147,7 @@ class HudDragObject {
/**
* Source for positional and texture data.
*/
std::shared_ptr<HudDragRenderEntity> render_entity;
std::shared_ptr<DragRenderEntity> render_entity;

/**
* Position of the dragged corner.
Expand Down
31 changes: 8 additions & 23 deletions libopenage/renderer/stages/hud/render_entity.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023-2023 the openage authors. See copying.md for legal info.
// Copyright 2023-2024 the openage authors. See copying.md for legal info.

#include "render_entity.h"

Expand All @@ -7,15 +7,14 @@

namespace openage::renderer::hud {

HudDragRenderEntity::HudDragRenderEntity(const coord::input drag_start) :
changed{false},
last_update{0.0},
DragRenderEntity::DragRenderEntity(const coord::input drag_start) :
renderer::RenderEntity{},
drag_pos{nullptr, 0, "", nullptr, drag_start},
drag_start{drag_start} {
}

void HudDragRenderEntity::update(const coord::input drag_pos,
const time::time_t time) {
void DragRenderEntity::update(const coord::input drag_pos,
const time::time_t time) {
std::unique_lock lock{this->mutex};

this->drag_pos.set_insert(time, drag_pos);
Expand All @@ -24,30 +23,16 @@ void HudDragRenderEntity::update(const coord::input drag_pos,
this->changed = true;
}

time::time_t HudDragRenderEntity::get_update_time() {
const curve::Continuous<coord::input> &DragRenderEntity::get_drag_pos() {
std::shared_lock lock{this->mutex};

return this->last_update;
}

const curve::Continuous<coord::input> &HudDragRenderEntity::get_drag_pos() {
return this->drag_pos;
}

const coord::input &HudDragRenderEntity::get_drag_start() {
return this->drag_start;
}

bool HudDragRenderEntity::is_changed() {
const coord::input DragRenderEntity::get_drag_start() {
std::shared_lock lock{this->mutex};

return this->changed;
}

void HudDragRenderEntity::clear_changed_flag() {
std::unique_lock lock{this->mutex};

this->changed = false;
return this->drag_start;
}

} // namespace openage::renderer::hud
Loading

0 comments on commit a1fad1c

Please sign in to comment.