Skip to content
This repository was archived by the owner on Jul 29, 2026. It is now read-only.
Merged

Dev #296

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
31f013d
refactor!: remove fwd declarations for UpdateContext and GameWorld
ThorstenSuckow Apr 20, 2026
ef82f27
refactor!: remove dependency from GameWorld for Manager
ThorstenSuckow Apr 20, 2026
9c7870f
refactor!: update GameWorld to initialize managers with CommandHandle…
ThorstenSuckow Apr 20, 2026
4a49df1
refactor!: remove ResourceRegistry dependency from UpdateContext and …
ThorstenSuckow Apr 20, 2026
7756154
refactor!: remove init method from System's Concept interface and rel…
ThorstenSuckow Apr 20, 2026
942ff07
refactor!: update Session to import StateTransitionContext and adjust…
ThorstenSuckow Apr 20, 2026
ecc44e4
refactor!: adjust import path for concepts and add command buffer reg…
ThorstenSuckow Apr 20, 2026
9ec2dde
refactor!: replace UpdateContextFwd with UpdateContext in relevant co…
ThorstenSuckow Apr 20, 2026
b7807ca
refactor!: move timing module from gameplay to runtime
ThorstenSuckow Apr 20, 2026
0b5221f
refactor!: enforce non-copyable ownership semantics in EntityManager
ThorstenSuckow Apr 20, 2026
0089b03
refactor!: clean up module imports in runtime concepts
ThorstenSuckow Apr 20, 2026
bc9acf1
refactor: update import paths and clean up unused code in GameLoop an…
ThorstenSuckow Apr 20, 2026
321f381
feat: add PlatformCommandBuffer
ThorstenSuckow Apr 20, 2026
f39739b
refactor!: update systems to remove circular dependencies w/ GameWorl…
ThorstenSuckow Apr 20, 2026
7b3edd5
chore(fix): fix compiler errors
ThorstenSuckow Apr 20, 2026
2b24e11
refactor: simplify FramePacer by removing unique_ptr for Stopwatch
ThorstenSuckow Apr 20, 2026
3fbb2fb
fix(macos): downgrade GLSL version from 450 to 410 and update GLFW co…
ThorstenSuckow Apr 20, 2026
ead7604
fix: remove layout qualifiers from shader inputs and uniforms
ThorstenSuckow Apr 21, 2026
c4ac085
feat: add BindingComponent for entity relationship management
ThorstenSuckow Apr 22, 2026
180ba2b
feat: add SizeComponent for 2D size management in spatial transformat…
ThorstenSuckow Apr 22, 2026
fe708ee
Merge pull request #295 from ThorstenSuckow/ecs_rendering
ThorstenSuckow Apr 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/v0.0.1-alpha/ecs_rendering/Namespaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ using namespace helios::platform::opengl;
using namespace helios::gameplay::scoring;
using namespace helios::gameplay::scoring::systems;
using namespace helios::gameplay::scoring::types;
using namespace helios::gameplay::timing;
using namespace helios::gameplay::timing::systems;
using namespace helios::runtime::timing;
using namespace helios::runtime::timing::systems;
using namespace helios::gameplay::combat::components;
using namespace helios::gameplay::combat::systems;

Expand Down
29 changes: 16 additions & 13 deletions examples/v0.0.1-alpha/ecs_rendering/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import helios.ext;
import helios.examples.ecs_rendering.GameLoop;

#include "Namespaces.h"
#include <memory>



int main() {

Expand All @@ -30,7 +31,7 @@ int main() {
// ==========================================================

// inputmanager
auto deadzoneStrategy = std::make_unique<RadialDeadzoneStrategy>();
auto deadzoneStrategy = RadialDeadzoneStrategy();
/*const auto inputManager = std::make_unique<InputManager>(
std::make_unique<helios::ext::glfw::input::GLFWInputAdapter>(std::move(deadzoneStrategy))
);*/
Expand All @@ -51,7 +52,9 @@ int main() {
);

// register additional managers
gameWorld.registerManager<GLFWPlatformManager<WindowHandle, /*InputHandle, */ StateCommandBuffer, EngineCommandBuffer>>();
gameWorld.registerManager<GLFWPlatformManager<WindowHandle, /*InputHandle, */ StateCommandBuffer, PlatformCommandBuffer>>(
gameWorld.platformWorld(), gameWorld.resourceRegistry().commandBufferRegistry()
);
gameWorld.registerManager<OpenGLShaderCompileManager<ShaderHandle>>(gameWorld.renderResourceWorld());
//gameWorld.registerManager<WarmupManager<OpenGLShaderSourcePool>>(shaderSourcePool);

Expand Down Expand Up @@ -152,13 +155,10 @@ int main() {
// ========================================
float DELTA_TIME = 0.0f;

auto stopwatch = std::make_unique<Stopwatch>();
auto framePacer = FramePacer(std::move(stopwatch));
auto framePacer = FramePacer();
framePacer.setTargetFps(0.0f);
FrameStats frameStats{};

gameLoop.init(gameWorld.init());

// ----------------------------------------
// GameLoop Config
// ----------------------------------------
Expand All @@ -168,12 +168,12 @@ int main() {
.addCommitPoint(CommitPoint::Structural)

.addPass<GameState>(GameState::Booting)
.addSystem<PlatformInitSystem<EngineCommandBuffer>>()
.addSystem<PlatformInitSystem<PlatformCommandBuffer>>()
.addCommitPoint(CommitPoint::Structural)

.addPass<GameState>(GameState::Booted | GameState::Live)
.addSystem<PollEventsSystem<EngineCommandBuffer>>()
.addSystem<WindowCreateSystem<WindowHandle, EngineCommandBuffer>>()
.addSystem<PollEventsSystem<PlatformCommandBuffer>>()
.addSystem<WindowCreateSystem<WindowHandle, PlatformCommandBuffer>>()
.addCommitPoint(CommitPoint::Structural)

.addPass<GameState>(GameState::Warmup)
Expand Down Expand Up @@ -201,16 +201,19 @@ int main() {
// Clear, bufferswapping
.addPass<GameState>(GameState::Live)
.addSystem<TransformClearSystem<GameObjectHandle>>()
.addSystem<SwapBuffersSystem<WindowHandle, EngineCommandBuffer>>()
.addSystem<GLFWWindowCloseSystem<WindowHandle, EngineCommandBuffer>>()
.addSystem<WindowBasedShutdownSystem<WindowHandle, EngineCommandBuffer>>()
.addSystem<SwapBuffersSystem<WindowHandle, PlatformCommandBuffer>>()
.addSystem<GLFWWindowCloseSystem<WindowHandle, PlatformCommandBuffer>>()
.addSystem<WindowBasedShutdownSystem<WindowHandle, PlatformCommandBuffer>>()
.addCommitPoint(CommitPoint::Structural)

.addPass<GameState>(GameState::Shutdown)
.addSystem<DestroySessionSystem>()
;


gameLoop.init(gameWorld.init());


while (gameLoop.isRunning(gameWorld)) {

framePacer.beginFrame();
Expand Down
4 changes: 2 additions & 2 deletions examples/v0.0.1-alpha/ecs_rendering/resources/cube.frag
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#version 450 core
#version 410 core

out vec4 FragColor;

layout (location=4) uniform vec4 color;
uniform vec4 color;


void main() {
Expand Down
10 changes: 5 additions & 5 deletions examples/v0.0.1-alpha/ecs_rendering/resources/cube.vert
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#version 450 core
#version 410 core

layout (location=0) in vec3 aPos;
in vec3 aPos;

layout (location=1) uniform mat4 modelMatrix;
layout (location=2) uniform mat4 viewMatrix;
layout (location=3) uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;


void main() {
Expand Down
3 changes: 2 additions & 1 deletion include/ext/opengl/rendering/OpenGLDevice.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module;
#include <stdexcept>
#include <utility>
#include <cassert>
#include <memory>

export module helios.ext.opengl.rendering.OpenGLDevice;

Expand Down Expand Up @@ -253,7 +254,7 @@ export namespace helios::ext::opengl::rendering {
*
* @see OpenGLGlyphTextRenderer::addFontFamily()
*/
[[nodiscard]] helios::rendering::text::TextRenderer& textRenderer() const noexcept {
[[nodiscard]] helios::rendering::text::TextRenderer& textRenderer() const noexcept override {
return *textRenderer_;
}

Expand Down
48 changes: 23 additions & 25 deletions include/ext/opengl/rendering/OpenGLGlyphTextRenderer.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -56,29 +56,6 @@ export namespace helios::ext::opengl::rendering {



friend class OpenGLDevice;

/**
* @brief Initializes OpenGL resources (VAO and VBO) for text rendering.
*
* Creates a vertex array object and vertex buffer for rendering glyph quads.
* The VBO is configured for dynamic updates (one quad per character).
*
* Must be called before any rendering operations.
*/
void init() {
glGenVertexArrays(1, &vao_);
glGenBuffers(1, &vbo_);
glBindVertexArray(vao_);
glBindBuffer(GL_ARRAY_BUFFER, vbo_);
// 2D quad for a texture requires 6 vertices with 4 floats each => 6*4
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6*4, nullptr, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}




Expand Down Expand Up @@ -166,7 +143,30 @@ export namespace helios::ext::opengl::rendering {

}

public:


/**
* @brief Initializes OpenGL resources (VAO and VBO) for text rendering.
*
* Creates a vertex array object and vertex buffer for rendering glyph quads.
* The VBO is configured for dynamic updates (one quad per character).
*
* Must be called before any rendering operations.
*/
void init() {
glGenVertexArrays(1, &vao_);
glGenBuffers(1, &vbo_);
glBindVertexArray(vao_);
glBindBuffer(GL_ARRAY_BUFFER, vbo_);
// 2D quad for a texture requires 6 vertices with 4 floats each => 6*4
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6*4, nullptr, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}

/**
* @brief Resets cached rendering state at the beginning of a render pass.
*
Expand All @@ -183,8 +183,6 @@ export namespace helios::ext::opengl::rendering {
lastVao_ = 0;
}

public:


/**
* @brief Destroys the OpenGLGlyphTextRenderer and releases all OpenGL resources.
Expand Down
10 changes: 3 additions & 7 deletions include/ext/opengl/rendering/OpenGLMeshRenderer.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,6 @@ export namespace helios::ext::opengl::rendering {
*/
class OpenGLMeshRenderer {



friend class OpenGLDevice;
friend class OpenGLBackend;

/**
* @brief Cached pointer to the last used shader for state optimization.
*
Expand All @@ -79,6 +74,9 @@ export namespace helios::ext::opengl::rendering {
*/
mutable unsigned int lastVao_ = 0;


public:

/**
* @brief Initializes the renderer.
*
Expand Down Expand Up @@ -106,8 +104,6 @@ export namespace helios::ext::opengl::rendering {
lastVao_ = 0;
}

public:


/**
* @brief Destructor that unbinds any currently bound VAO.
Expand Down
6 changes: 4 additions & 2 deletions include/helios/bootstrap.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import helios.runtime.gameloop;
import helios.runtime.world;

import helios.state.Bindings;
import helios.state.types.StateTransitionContext;
import helios.runtime.messaging.command;

import helios.platform;
Expand All @@ -32,7 +33,7 @@ import helios.rendering.registry;
import helios.runtime.registry;

import helios.gameplay.lifecycle;
import helios.gameplay.timing;
import helios.runtime.timing;
import helios.gameplay.gamestate;
import helios.gameplay.matchstate;

Expand Down Expand Up @@ -165,12 +166,13 @@ export namespace helios::bootstrap {

gameWorld->registerManager<helios::gameplay::matchstate::MatchStateManager>(
helios::gameplay::matchstate::rules::DefaultMatchStateTransitionRules::rules());
gameWorld->registerManager<helios::gameplay::timing::TimerManager>();
gameWorld->registerManager<helios::runtime::timing::TimerManager>();

gameWorld->session().trackState<helios::gameplay::gamestate::types::GameState>();
gameWorld->session().trackState<helios::gameplay::matchstate::types::MatchState>();

gameWorld->registerCommandBuffer<RenderCommandBuffer>();
gameWorld->registerCommandBuffer<PlatformCommandBuffer>();
gameWorld->registerCommandBuffer<EngineCommandBuffer>();
gameWorld->registerCommandBuffer<StateCommandBuffer>();

Expand Down
11 changes: 11 additions & 0 deletions include/helios/ecs/EntityManager.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export namespace helios::ecs {
* - **Entity Destruction:** Removes all components and invalidates the handle.
* - **Component Storage:** Maintains a vector of `SparseSet` instances, one per
* component type, indexed by `TypeIndexer`.
* - **Ownership Semantics:** Copy construction/assignment are deleted;
* `EntityManager` is move-enabled only.
*
* ## Usage
*
Expand Down Expand Up @@ -79,6 +81,15 @@ export namespace helios::ecs {
using ComponentTypeId_type = ComponentTypeId<Handle_type>;
using ComponentOpsRegistry_type = ComponentOpsRegistry<Handle_type>;

/**
* @brief Non-copyable: copying an EntityManager is explicitly disabled.
*/
EntityManager(const EntityManager&) = delete;
EntityManager& operator=(const EntityManager&) = delete;

EntityManager(EntityManager&&) noexcept = default;
EntityManager& operator=(EntityManager&&) noexcept = default;

/**
* @brief Constructs an EntityManager with the given capacity.
*
Expand Down
56 changes: 56 additions & 0 deletions include/helios/ecs/components/BindingComponent.ixx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
module;

#include <concepts>

export module helios.ecs.components.BindingComponent;

export namespace helios::ecs::components {

/**
* @brief Generic component that stores a handle reference to another entity.
*
* @details `BindingComponent` models a directed relationship from an owner entity
* to a target entity via the target's handle type. It is used as a lightweight
* link primitive for higher-level components such as scene, camera, and viewport
* bindings.
*
* @tparam TOwnerHandle Handle type of the entity owning this component.
* @tparam TTargetHandle Handle type of the referenced target entity.
*/
template<typename TOwnerHandle, typename TTargetHandle>
class BindingComponent {

TTargetHandle targetHandle_{};

public:

/**
* @brief Creates a binding from an explicit target handle.
*
* @param targetHandle Handle of the referenced target entity.
*/
explicit BindingComponent(const TTargetHandle targetHandle) : targetHandle_(targetHandle) {};

/**
* @brief Creates a binding from a target entity instance.
*
* @details This constructor is enabled only if the entity's `Handle_type`
* matches `TTargetHandle`.
*
* @tparam TTargetEntity Entity type exposing `Handle_type` and `handle()`.
* @param targetEntity Referenced target entity.
*/
template<typename TTargetEntity>
requires std::same_as<TTargetHandle, typename TTargetEntity::Handle_type>
explicit BindingComponent(const TTargetEntity targetEntity) : targetHandle_(targetEntity.handle()) {};

/**
* @brief Returns the bound target handle.
*
* @return Handle of the referenced target entity.
*/
[[nodiscard]] TTargetHandle targetHandle() const noexcept {
return targetHandle_;
}
};
}
3 changes: 2 additions & 1 deletion include/helios/ecs/components/_module.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export module helios.ecs.components;

export import helios.ecs.components.HierarchyComponent;
export import helios.ecs.components.Active;
export import helios.ecs.components.Inactive;
export import helios.ecs.components.Inactive;
export import helios.ecs.components.BindingComponent;
3 changes: 1 addition & 2 deletions include/helios/gameplay/_module.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ export import helios.gameplay.damage;
export import helios.gameplay.health;
export import helios.gameplay.scoring;
export import helios.gameplay.gamestate;
export import helios.gameplay.matchstate;
export import helios.gameplay.timing;
export import helios.gameplay.matchstate;
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export namespace helios::gameplay::bounds::systems {
public:
using Entity_type = THandle::Entity_type;
using EngineRoleTag = helios::runtime::tags::SystemRole;
using CommandBuffer_type = TCommandBuffer;

/**
* @brief Updates all entities that may have left level bounds.
Expand All @@ -92,7 +93,7 @@ export namespace helios::gameplay::bounds::systems {
*
* @param updateContext Context containing deltaTime and other frame data.
*/
void update(helios::runtime::world::UpdateContext& updateContext) noexcept {
void update(helios::runtime::world::UpdateContext& updateContext, TCommandBuffer& cmdBuffer) noexcept {

using namespace helios::physics::collision::types;

Expand Down Expand Up @@ -140,7 +141,7 @@ export namespace helios::gameplay::bounds::systems {
auto* sbp = entity.template get<helios::gameplay::spawn::components::SpawnedByProfileComponent<THandle>>();
assert(sbp && "Unexpected missing SpawnProfile");

updateContext.queueCommand<TCommandBuffer, helios::gameplay::spawn::commands::DespawnCommand<THandle>>(
cmdBuffer.template add<helios::gameplay::spawn::commands::DespawnCommand<THandle>>(
entity.handle(), sbp->spawnProfileId()
);

Expand Down
Loading
Loading