ROADMAP.md

This commit is contained in:
2026-01-10 12:06:51 +00:00
parent aaf6a80776
commit 7e0454771b
6 changed files with 16 additions and 74 deletions

View File

@@ -11,7 +11,7 @@ struct GuiCommand;
/** /**
* @brief GUI rendering service interface. * @brief GUI rendering service interface.
* *
* Consumes GUI commands produced by scripts and prepares any per-frame data. * Consumes GUI commands and prepares per-frame data.
*/ */
class IGuiService { class IGuiService {
public: public:
@@ -20,7 +20,7 @@ public:
/** /**
* @brief Prepare GUI commands for rendering. * @brief Prepare GUI commands for rendering.
* *
* Processes GUI commands from Lua and prepares rendering data. * Processes GUI commands and prepares rendering data.
* *
* @param commands Vector of GUI commands to render * @param commands Vector of GUI commands to render
* @param width Viewport width in pixels * @param width Viewport width in pixels

View File

@@ -6,7 +6,7 @@
namespace sdl3cpp::services { namespace sdl3cpp::services {
/** /**
* @brief Script-facing mesh loading service interface. * @brief Mesh loading service interface.
*/ */
class IMeshService { class IMeshService {
public: public:

View File

@@ -10,7 +10,7 @@ namespace sdl3cpp::services {
* @brief Scene management service interface. * @brief Scene management service interface.
* *
* Maintains the scene graph and generates render commands for the graphics service. * Maintains the scene graph and generates render commands for the graphics service.
* Separated from script service to decouple scene state from Lua execution. * Separated from runtime input to decouple scene state from scripting concerns.
*/ */
class ISceneService { class ISceneService {
public: public:

View File

@@ -87,29 +87,21 @@ void CopyConfigAssets(const std::filesystem::path& targetDir) {
} }
} }
std::filesystem::path WriteLuaScript(const std::filesystem::path& rootDir) {
auto scriptPath = rootDir / "scripts" / "cube_logic.lua";
WriteFile(scriptPath, "-- test script\n");
return scriptPath;
}
TEST(JsonConfigMergeTest, OverlayOverridesBaseFields) { TEST(JsonConfigMergeTest, OverlayOverridesBaseFields) {
ScopedTempDir tempDir; ScopedTempDir tempDir;
CopyConfigAssets(tempDir.Path()); CopyConfigAssets(tempDir.Path());
WriteLuaScript(tempDir.Path());
auto logger = std::make_shared<NullLogger>(); auto logger = std::make_shared<NullLogger>();
const std::string baseConfig = R"({ const std::string baseConfig = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false },
"window": { "size": { "width": 800, "height": 600 } } "window": { "size": { "width": 800, "height": 600 } }
})"; })";
const std::string overlayConfig = R"({ const std::string overlayConfig = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"extends": "base.json", "extends": "base.json",
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false },
"window": { "size": { "width": 1024 } } "window": { "size": { "width": 1024 } }
})"; })";
@@ -127,13 +119,11 @@ TEST(JsonConfigMergeTest, OverlayOverridesBaseFields) {
TEST(JsonConfigMergeTest, DeleteDirectiveRemovesObject) { TEST(JsonConfigMergeTest, DeleteDirectiveRemovesObject) {
ScopedTempDir tempDir; ScopedTempDir tempDir;
CopyConfigAssets(tempDir.Path()); CopyConfigAssets(tempDir.Path());
WriteLuaScript(tempDir.Path());
auto logger = std::make_shared<NullLogger>(); auto logger = std::make_shared<NullLogger>();
const std::string baseConfig = R"({ const std::string baseConfig = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false },
"window": { "window": {
"title": "Base Title", "title": "Base Title",
"mouse_grab": { "enabled": true } "mouse_grab": { "enabled": true }
@@ -143,7 +133,6 @@ TEST(JsonConfigMergeTest, DeleteDirectiveRemovesObject) {
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"extends": "base.json", "extends": "base.json",
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false },
"window": { "window": {
"@delete": ["mouse_grab"], "@delete": ["mouse_grab"],
"title": "Overlay Title" "title": "Overlay Title"
@@ -164,26 +153,22 @@ TEST(JsonConfigMergeTest, DeleteDirectiveRemovesObject) {
TEST(JsonConfigMergeTest, ExtendsArrayAppliesInOrder) { TEST(JsonConfigMergeTest, ExtendsArrayAppliesInOrder) {
ScopedTempDir tempDir; ScopedTempDir tempDir;
CopyConfigAssets(tempDir.Path()); CopyConfigAssets(tempDir.Path());
WriteLuaScript(tempDir.Path());
auto logger = std::make_shared<NullLogger>(); auto logger = std::make_shared<NullLogger>();
const std::string baseOne = R"({ const std::string baseOne = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false },
"window": { "title": "Base One" } "window": { "title": "Base One" }
})"; })";
const std::string baseTwo = R"({ const std::string baseTwo = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false },
"window": { "title": "Base Two" } "window": { "title": "Base Two" }
})"; })";
const std::string overlayConfig = R"({ const std::string overlayConfig = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"extends": ["base_one.json", "base_two.json"], "extends": ["base_one.json", "base_two.json"],
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false }
})"; })";
WriteFile(tempDir.Path() / "base_one.json", baseOne); WriteFile(tempDir.Path() / "base_one.json", baseOne);
@@ -200,20 +185,17 @@ TEST(JsonConfigMergeTest, ExtendsArrayAppliesInOrder) {
TEST(JsonConfigMergeTest, ExtendsCycleThrows) { TEST(JsonConfigMergeTest, ExtendsCycleThrows) {
ScopedTempDir tempDir; ScopedTempDir tempDir;
CopyConfigAssets(tempDir.Path()); CopyConfigAssets(tempDir.Path());
WriteLuaScript(tempDir.Path());
auto logger = std::make_shared<NullLogger>(); auto logger = std::make_shared<NullLogger>();
const std::string baseA = R"({ const std::string baseA = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"extends": "base_b.json", "extends": "base_b.json",
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false }
})"; })";
const std::string baseB = R"({ const std::string baseB = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"extends": "base_a.json", "extends": "base_a.json",
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false }
})"; })";
WriteFile(tempDir.Path() / "base_a.json", baseA); WriteFile(tempDir.Path() / "base_a.json", baseA);

View File

@@ -87,20 +87,15 @@ void CopyConfigAssets(const std::filesystem::path& targetDir) {
} }
} }
void WriteLuaScript(const std::filesystem::path& rootDir) {
WriteFile(rootDir / "scripts" / "cube_logic.lua", "-- test script\n");
}
TEST(JsonConfigSchemaValidationTest, RejectsInvalidWindowWidthType) { TEST(JsonConfigSchemaValidationTest, RejectsInvalidWindowWidthType) {
ScopedTempDir tempDir; ScopedTempDir tempDir;
CopyConfigAssets(tempDir.Path()); CopyConfigAssets(tempDir.Path());
WriteLuaScript(tempDir.Path());
auto logger = std::make_shared<NullLogger>(); auto logger = std::make_shared<NullLogger>();
const std::string config = R"({ const std::string config = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false },
"window": { "size": { "width": "wide", "height": 600 } } "window": { "size": { "width": "wide", "height": 600 } }
})"; })";
@@ -111,17 +106,15 @@ TEST(JsonConfigSchemaValidationTest, RejectsInvalidWindowWidthType) {
std::runtime_error); std::runtime_error);
} }
TEST(JsonConfigSchemaValidationTest, RejectsInvalidSceneSourceEnum) { TEST(JsonConfigSchemaValidationTest, RejectsInvalidProjectRootType) {
ScopedTempDir tempDir; ScopedTempDir tempDir;
CopyConfigAssets(tempDir.Path()); CopyConfigAssets(tempDir.Path());
WriteLuaScript(tempDir.Path());
auto logger = std::make_shared<NullLogger>(); auto logger = std::make_shared<NullLogger>();
const std::string config = R"({ const std::string config = R"({
"schema_version": 2, "schema_version": 2,
"configVersion": 2, "configVersion": 2,
"scripts": { "entry": "scripts/cube_logic.lua", "lua_debug": false }, "paths": { "project_root": 42 }
"runtime": { "scene_source": "broken" }
})"; })";
WriteFile(tempDir.Path() / "config.json", config); WriteFile(tempDir.Path() / "config.json", config);

View File

@@ -2,9 +2,8 @@
#include "services/impl/render/render_coordinator_service.hpp" #include "services/impl/render/render_coordinator_service.hpp"
#include "services/interfaces/i_config_compiler_service.hpp" #include "services/interfaces/i_config_compiler_service.hpp"
#include "services/interfaces/i_config_service.hpp"
#include "services/interfaces/i_graphics_service.hpp" #include "services/interfaces/i_graphics_service.hpp"
#include "services/interfaces/i_shader_script_service.hpp" #include "services/interfaces/i_shader_system_registry.hpp"
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
@@ -61,53 +60,21 @@ public:
void* GetGraphicsQueue() const override { return nullptr; } void* GetGraphicsQueue() const override { return nullptr; }
}; };
class StubShaderScriptService : public sdl3cpp::services::IShaderScriptService { class StubShaderSystemRegistry : public sdl3cpp::services::IShaderSystemRegistry {
public: public:
std::unordered_map<std::string, sdl3cpp::services::ShaderPaths> LoadShaderPathsMap() override { std::unordered_map<std::string, sdl3cpp::services::ShaderPaths> BuildShaderMap() override {
return {}; return {};
} }
}; sdl3cpp::services::ShaderReflection GetReflection(const std::string&) const override {
return {};
class StubConfigService final : public sdl3cpp::services::IConfigService {
public:
explicit StubConfigService(sdl3cpp::services::SceneSource sceneSource = sdl3cpp::services::SceneSource::Lua)
: sceneSource_(sceneSource) {}
uint32_t GetWindowWidth() const override { return 1; }
uint32_t GetWindowHeight() const override { return 1; }
std::filesystem::path GetScriptPath() const override { return {}; }
bool IsLuaDebugEnabled() const override { return false; }
std::string GetWindowTitle() const override { return ""; }
sdl3cpp::services::SceneSource GetSceneSource() const override {
return sceneSource_;
} }
const sdl3cpp::services::InputBindings& GetInputBindings() const override { return inputBindings_; } std::vector<sdl3cpp::services::ShaderPaths::TextureBinding> GetDefaultTextures(
const sdl3cpp::services::MouseGrabConfig& GetMouseGrabConfig() const override { return mouseGrabConfig_; } const std::string&) const override {
const sdl3cpp::services::BgfxConfig& GetBgfxConfig() const override { return bgfxConfig_; } return {};
const sdl3cpp::services::MaterialXConfig& GetMaterialXConfig() const override { return materialXConfig_; }
const std::vector<sdl3cpp::services::MaterialXMaterialConfig>& GetMaterialXMaterialConfigs() const override {
return materialXMaterials_;
} }
const sdl3cpp::services::GuiFontConfig& GetGuiFontConfig() const override { return guiFontConfig_; } std::string GetActiveSystemId() const override {
const sdl3cpp::services::RenderBudgetConfig& GetRenderBudgetConfig() const override { return budgets_; } return "materialx";
const sdl3cpp::services::CrashRecoveryConfig& GetCrashRecoveryConfig() const override { return crashRecovery_; }
const sdl3cpp::services::ValidationTourConfig& GetValidationTourConfig() const override {
return validationTour_;
} }
const std::string& GetConfigJson() const override { return configJson_; }
private:
sdl3cpp::services::SceneSource sceneSource_;
sdl3cpp::services::InputBindings inputBindings_{};
sdl3cpp::services::MouseGrabConfig mouseGrabConfig_{};
sdl3cpp::services::BgfxConfig bgfxConfig_{};
sdl3cpp::services::MaterialXConfig materialXConfig_{};
std::vector<sdl3cpp::services::MaterialXMaterialConfig> materialXMaterials_{};
sdl3cpp::services::GuiFontConfig guiFontConfig_{};
sdl3cpp::services::RenderBudgetConfig budgets_{};
sdl3cpp::services::CrashRecoveryConfig crashRecovery_{};
sdl3cpp::services::ValidationTourConfig validationTour_{};
std::string configJson_{};
}; };
class StubConfigCompilerService final : public sdl3cpp::services::IConfigCompilerService { class StubConfigCompilerService final : public sdl3cpp::services::IConfigCompilerService {