This commit is contained in:
2026-01-06 13:25:49 +00:00
parent 5d495d731b
commit 4e15e08b7f
1395 changed files with 295666 additions and 323 deletions
+19
View File
@@ -0,0 +1,19 @@
#include "ecs_service.hpp"
namespace sdl3cpp::services::impl {
EcsService::EcsService(std::shared_ptr<ILogger> logger)
: logger_(std::move(logger)) {
if (logger_) {
logger_->Trace("EcsService", "EcsService");
}
}
void EcsService::Shutdown() noexcept {
if (logger_) {
logger_->Trace("EcsService", "Shutdown");
}
registry_.clear();
}
} // namespace sdl3cpp::services::impl
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include "../interfaces/i_ecs_service.hpp"
#include "../interfaces/i_logger.hpp"
#include "../../di/lifecycle.hpp"
#include <memory>
namespace sdl3cpp::services::impl {
class EcsService : public IEcsService,
public di::IShutdownable {
public:
explicit EcsService(std::shared_ptr<ILogger> logger);
~EcsService() override = default;
entt::registry& GetRegistry() override { return registry_; }
const entt::registry& GetRegistry() const override { return registry_; }
void Shutdown() noexcept override;
private:
entt::registry registry_;
std::shared_ptr<ILogger> logger_;
};
} // namespace sdl3cpp::services::impl
+59 -14
View File
@@ -1,17 +1,24 @@
#include "scene_service.hpp"
#include <limits>
#include <stdexcept>
#include <utility>
namespace sdl3cpp::services::impl {
SceneService::SceneService(std::shared_ptr<ISceneScriptService> scriptService, std::shared_ptr<ILogger> logger)
: scriptService_(scriptService), logger_(logger) {
SceneService::SceneService(std::shared_ptr<ISceneScriptService> scriptService,
std::shared_ptr<IEcsService> ecsService,
std::shared_ptr<ILogger> logger)
: scriptService_(std::move(scriptService)),
ecsService_(std::move(ecsService)),
logger_(std::move(logger)) {
logger_->Trace("SceneService", "SceneService",
"scriptService=" + std::string(scriptService_ ? "set" : "null"));
"scriptService=" + std::string(scriptService_ ? "set" : "null") +
", ecsService=" + std::string(ecsService_ ? "set" : "null"));
if (!scriptService_) {
throw std::invalid_argument("Scene script service cannot be null");
if (!scriptService_ || !ecsService_) {
throw std::invalid_argument("Scene script service and ECS service cannot be null");
}
registry_ = &ecsService_->GetRegistry();
}
SceneService::~SceneService() {
@@ -25,6 +32,7 @@ void SceneService::LoadScene(const std::vector<SceneObject>& objects) {
logger_->Trace("SceneService", "LoadScene",
"objects.size=" + std::to_string(objects.size()));
ClearSceneEntities();
combinedVertices_.clear();
combinedIndices_.clear();
drawInfos_.clear();
@@ -34,6 +42,10 @@ void SceneService::LoadScene(const std::vector<SceneObject>& objects) {
return;
}
if (!registry_) {
throw std::runtime_error("ECS registry is not available");
}
size_t totalVertices = 0;
size_t totalIndices = 0;
for (const auto& obj : objects) {
@@ -52,6 +64,7 @@ void SceneService::LoadScene(const std::vector<SceneObject>& objects) {
combinedVertices_.reserve(totalVertices);
combinedIndices_.reserve(totalIndices);
drawInfos_.reserve(objects.size());
sceneEntities_.reserve(objects.size());
for (const auto& obj : objects) {
if (obj.vertices.empty() || obj.indices.empty()) {
@@ -61,8 +74,19 @@ void SceneService::LoadScene(const std::vector<SceneObject>& objects) {
throw std::runtime_error("Scene object missing vertex or index data");
}
auto entity = registry_->create();
sceneEntities_.push_back(entity);
registry_->emplace<SceneTag>(entity);
registry_->emplace<MeshComponent>(entity, obj.vertices, obj.indices);
registry_->emplace<RenderComponent>(entity, obj.computeModelMatrixRef, obj.shaderKey);
}
for (const auto entity : sceneEntities_) {
const auto& mesh = registry_->get<MeshComponent>(entity);
const auto& render = registry_->get<RenderComponent>(entity);
size_t vertexOffset = combinedVertices_.size();
if (vertexOffset + obj.vertices.size() > kMaxIndexValue) {
if (vertexOffset + mesh.vertices.size() > kMaxIndexValue) {
if (logger_) {
logger_->Error("Scene vertex data exceeds uint16_t index range");
}
@@ -70,9 +94,15 @@ void SceneService::LoadScene(const std::vector<SceneObject>& objects) {
}
uint32_t indexOffset = static_cast<uint32_t>(combinedIndices_.size());
combinedVertices_.insert(combinedVertices_.end(), obj.vertices.begin(), obj.vertices.end());
combinedIndices_.reserve(combinedIndices_.size() + obj.indices.size());
for (uint16_t index : obj.indices) {
combinedVertices_.insert(combinedVertices_.end(), mesh.vertices.begin(), mesh.vertices.end());
combinedIndices_.reserve(combinedIndices_.size() + mesh.indices.size());
if (logger_) {
logger_->Trace("SceneService", "LoadScene",
"Remapping indices for entity=" + std::to_string(entt::to_integral(entity)) +
", vertexOffset=" + std::to_string(vertexOffset) +
", indexCount=" + std::to_string(mesh.indices.size()));
}
for (uint16_t index : mesh.indices) {
uint32_t adjusted = static_cast<uint32_t>(index) + static_cast<uint32_t>(vertexOffset);
if (adjusted > kMaxIndexValue) {
if (logger_) {
@@ -80,15 +110,15 @@ void SceneService::LoadScene(const std::vector<SceneObject>& objects) {
}
throw std::runtime_error("Index offset exceeds uint16_t range");
}
combinedIndices_.push_back(index);
combinedIndices_.push_back(static_cast<uint16_t>(adjusted));
}
SceneDrawInfo drawInfo;
drawInfo.indexOffset = indexOffset;
drawInfo.indexCount = static_cast<uint32_t>(obj.indices.size());
drawInfo.indexCount = static_cast<uint32_t>(mesh.indices.size());
drawInfo.vertexOffset = static_cast<int32_t>(vertexOffset);
drawInfo.computeModelMatrixRef = obj.computeModelMatrixRef;
drawInfo.shaderKey = obj.shaderKey;
drawInfo.computeModelMatrixRef = render.computeModelMatrixRef;
drawInfo.shaderKey = render.shaderKey;
drawInfos_.push_back(std::move(drawInfo));
}
@@ -147,6 +177,7 @@ const std::vector<uint16_t>& SceneService::GetCombinedIndices() const {
void SceneService::Clear() {
logger_->Trace("SceneService", "Clear");
ClearSceneEntities();
combinedVertices_.clear();
combinedIndices_.clear();
drawInfos_.clear();
@@ -156,7 +187,7 @@ void SceneService::Clear() {
size_t SceneService::GetObjectCount() const {
logger_->Trace("SceneService", "GetObjectCount");
return drawInfos_.size();
return sceneEntities_.size();
}
void SceneService::Shutdown() noexcept {
@@ -165,4 +196,18 @@ void SceneService::Shutdown() noexcept {
Clear();
}
void SceneService::ClearSceneEntities() {
if (!registry_ || sceneEntities_.empty()) {
sceneEntities_.clear();
return;
}
for (const auto entity : sceneEntities_) {
if (registry_->valid(entity)) {
registry_->destroy(entity);
}
}
sceneEntities_.clear();
}
} // namespace sdl3cpp::services::impl
+24 -2
View File
@@ -2,10 +2,13 @@
#include "../interfaces/i_scene_service.hpp"
#include "../interfaces/i_scene_script_service.hpp"
#include "../interfaces/i_ecs_service.hpp"
#include "../interfaces/i_logger.hpp"
#include "../../di/lifecycle.hpp"
#include <vector>
#include <entt/entt.hpp>
#include <memory>
#include <string>
#include <vector>
namespace sdl3cpp::services::impl {
@@ -18,7 +21,9 @@ namespace sdl3cpp::services::impl {
class SceneService : public ISceneService,
public di::IShutdownable {
public:
explicit SceneService(std::shared_ptr<ISceneScriptService> scriptService, std::shared_ptr<ILogger> logger);
SceneService(std::shared_ptr<ISceneScriptService> scriptService,
std::shared_ptr<IEcsService> ecsService,
std::shared_ptr<ILogger> logger);
~SceneService() override;
// ISceneService interface
@@ -34,6 +39,18 @@ public:
void Shutdown() noexcept override;
private:
struct SceneTag {};
struct MeshComponent {
std::vector<core::Vertex> vertices;
std::vector<uint16_t> indices;
};
struct RenderComponent {
int computeModelMatrixRef = -1;
std::string shaderKey;
};
struct SceneDrawInfo {
uint32_t indexOffset = 0;
uint32_t indexCount = 0;
@@ -42,8 +59,13 @@ private:
std::string shaderKey;
};
void ClearSceneEntities();
std::shared_ptr<ISceneScriptService> scriptService_;
std::shared_ptr<IEcsService> ecsService_;
std::shared_ptr<ILogger> logger_;
entt::registry* registry_ = nullptr;
std::vector<entt::entity> sceneEntities_;
std::vector<core::Vertex> combinedVertices_;
std::vector<uint16_t> combinedIndices_;
std::vector<SceneDrawInfo> drawInfos_;