ROADMAP.md

This commit is contained in:
2026-01-09 21:08:51 +00:00
parent 3e64f398f0
commit 228cb5fe94
17 changed files with 380 additions and 198 deletions

View File

@@ -295,6 +295,14 @@ set(WORKFLOW_SOURCES
src/services/impl/workflow_default_step_registrar.cpp
)
set(MATERIALX_SCRIPT_SOURCES
src/services/impl/materialx_path_resolver.cpp
src/services/impl/materialx_search_path_builder.cpp
src/services/impl/materialx_document_loader.cpp
src/services/impl/materialx_surface_node_resolver.cpp
src/services/impl/materialx_surface_parameter_reader.cpp
)
if(BUILD_SDL3_APP)
add_executable(sdl3_app
src/main.cpp
@@ -303,6 +311,7 @@ if(BUILD_SDL3_APP)
src/events/event_bus.cpp
${JSON_CONFIG_SOURCES}
${WORKFLOW_SOURCES}
${MATERIALX_SCRIPT_SOURCES}
src/services/impl/config_compiler_service.cpp
src/services/impl/command_line_service.cpp
src/services/impl/json_config_writer_service.cpp
@@ -428,6 +437,7 @@ add_executable(script_engine_tests
src/services/impl/physics_bridge_service.cpp
src/services/impl/platform_service.cpp
src/services/impl/script_engine_service.cpp
${MATERIALX_SCRIPT_SOURCES}
src/services/impl/lua_helpers.cpp
src/services/impl/scene_script_service.cpp
src/services/impl/shader_script_service.cpp

View File

@@ -160,6 +160,7 @@ Treat JSON config as a declarative control plane that compiles into scene, resou
### Phase A: Mechanical Extraction (1-3 days)
- [~] JsonConfigService: extracted config document load/merge helpers into `src/services/impl/json_config_document_loader.cpp` plus small parser/extend/merge services to keep files <100 LOC.
- [~] JsonConfigService: split schema validation/versioning/migration into `json_config_*` services (`schema_validator`, `version_validator`, `migration_service`).
- [~] ScriptEngineService: extracted MaterialX helpers into micro services (`materialx_path_resolver`, `materialx_search_path_builder`, `materialx_document_loader`, `materialx_surface_node_resolver`, `materialx_surface_parameter_reader`).
- Move self-contained helpers into `*_helpers.cpp` with clear headers.
- Extract pure data transforms into free functions with unit tests.
- Preserve public interfaces; no behavior change in this phase.
@@ -231,6 +232,7 @@ Option B: per-shader only
- Describe boot + frame pipelines as a declarative JSON workflow graph.
- Keep each step tiny (<100 LOC), with explicit inputs/outputs and DI-backed plugin lookup.
- Package common pipelines as templates so users don't start from scratch.
- Only register/instantiate step plugins that are referenced by the active workflow.
### Status
- [~] Workflow core: step registry + executor + JSON definition parser.

View File

@@ -38,6 +38,7 @@
#include "services/impl/pipeline_compiler_service.hpp"
#include "services/impl/validation_tour_service.hpp"
#include "services/impl/workflow_default_step_registrar.hpp"
#include "services/impl/workflow_definition_parser.hpp"
#include "services/impl/workflow_executor.hpp"
#include "services/impl/workflow_step_registry.hpp"
#include "services/interfaces/i_platform_service.hpp"
@@ -49,6 +50,7 @@
#include "services/interfaces/i_workflow_step_registry.hpp"
#include "services/interfaces/i_config_compiler_service.hpp"
#include <iostream>
#include <filesystem>
#include <stdexcept>
#include <utility>
@@ -233,10 +235,26 @@ void ServiceBasedApp::RegisterServices() {
registry_.RegisterService<services::IWorkflowExecutor, services::impl::WorkflowExecutor>(
registry_.GetService<services::IWorkflowStepRegistry>(),
registry_.GetService<services::ILogger>());
services::impl::WorkflowDefaultStepRegistrar workflowRegistrar(
registry_.GetService<services::ILogger>(),
registry_.GetService<services::IProbeService>());
workflowRegistrar.RegisterDefaults(registry_.GetService<services::IWorkflowStepRegistry>());
services::impl::WorkflowDefinitionParser workflowParser;
services::WorkflowDefinition workflowDefinition;
bool workflowLoaded = false;
try {
const std::filesystem::path workflowPath =
std::filesystem::current_path() / "config" / "workflows" / "templates" / "boot_default.json";
workflowDefinition = workflowParser.ParseFile(workflowPath);
workflowLoaded = true;
} catch (const std::exception& e) {
logger_->Warn("ServiceBasedApp::RegisterServices: Failed to load workflow template: " +
std::string(e.what()));
}
if (workflowLoaded) {
services::impl::WorkflowDefaultStepRegistrar workflowRegistrar(
registry_.GetService<services::ILogger>(),
registry_.GetService<services::IProbeService>());
workflowRegistrar.RegisterUsedSteps(
workflowDefinition,
registry_.GetService<services::IWorkflowStepRegistry>());
}
// Configuration service
registry_.RegisterService<services::IConfigService, services::impl::JsonConfigService>(

View File

@@ -0,0 +1,31 @@
#include "materialx_document_loader.hpp"
#include "materialx_search_path_builder.hpp"
#include <MaterialXFormat/Util.h>
#include <MaterialXFormat/XmlIo.h>
namespace sdl3cpp::services::impl {
MaterialX::DocumentPtr MaterialXDocumentLoader::Load(const std::filesystem::path& documentPath,
const MaterialXConfig& config,
const std::filesystem::path& scriptDirectory) const {
MaterialX::DocumentPtr document = MaterialX::createDocument();
MaterialXSearchPathBuilder builder;
auto searchPath = builder.Build(config, scriptDirectory);
MaterialX::readFromXmlFile(document, MaterialX::FilePath(documentPath.string()), searchPath);
if (!config.libraryFolders.empty()) {
MaterialX::DocumentPtr stdLib = MaterialX::createDocument();
MaterialX::FilePathVec folders;
folders.reserve(config.libraryFolders.size());
for (const auto& folder : config.libraryFolders) {
folders.emplace_back(folder);
}
MaterialX::loadLibraries(folders, searchPath, stdLib);
document->importLibrary(stdLib);
}
return document;
}
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,18 @@
#pragma once
#include "../interfaces/config_types.hpp"
#include <MaterialXCore/Document.h>
#include <filesystem>
namespace sdl3cpp::services::impl {
class MaterialXDocumentLoader {
public:
MaterialX::DocumentPtr Load(const std::filesystem::path& documentPath,
const MaterialXConfig& config,
const std::filesystem::path& scriptDirectory) const;
};
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,33 @@
#include "materialx_path_resolver.hpp"
#include <system_error>
namespace sdl3cpp::services::impl {
std::filesystem::path MaterialXPathResolver::Resolve(const std::filesystem::path& path,
const std::filesystem::path& scriptDirectory) const {
if (path.empty()) {
return {};
}
if (path.is_absolute()) {
return path;
}
if (!scriptDirectory.empty()) {
auto projectRoot = scriptDirectory.parent_path();
if (!projectRoot.empty()) {
std::error_code ec;
auto resolved = std::filesystem::weakly_canonical(projectRoot / path, ec);
if (!ec) {
return resolved;
}
}
}
std::error_code ec;
auto resolved = std::filesystem::weakly_canonical(path, ec);
if (ec) {
return {};
}
return resolved;
}
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,13 @@
#pragma once
#include <filesystem>
namespace sdl3cpp::services::impl {
class MaterialXPathResolver {
public:
std::filesystem::path Resolve(const std::filesystem::path& path,
const std::filesystem::path& scriptDirectory) const;
};
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,26 @@
#include "materialx_search_path_builder.hpp"
#include "materialx_path_resolver.hpp"
#include <filesystem>
namespace sdl3cpp::services::impl {
MaterialX::FileSearchPath MaterialXSearchPathBuilder::Build(
const MaterialXConfig& config,
const std::filesystem::path& scriptDirectory) const {
MaterialX::FileSearchPath searchPath;
MaterialXPathResolver resolver;
std::filesystem::path libraryPath = resolver.Resolve(config.libraryPath, scriptDirectory);
if (libraryPath.empty() && !scriptDirectory.empty()) {
auto fallback = scriptDirectory.parent_path() / "MaterialX" / "libraries";
if (std::filesystem::exists(fallback)) {
libraryPath = fallback;
}
}
if (!libraryPath.empty()) {
searchPath.append(MaterialX::FilePath(libraryPath.string()));
}
return searchPath;
}
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,17 @@
#pragma once
#include "../interfaces/config_types.hpp"
#include <MaterialXFormat/Util.h>
#include <filesystem>
namespace sdl3cpp::services::impl {
class MaterialXSearchPathBuilder {
public:
MaterialX::FileSearchPath Build(const MaterialXConfig& config,
const std::filesystem::path& scriptDirectory) const;
};
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,41 @@
#include "materialx_surface_node_resolver.hpp"
namespace sdl3cpp::services::impl {
MaterialX::NodePtr MaterialXSurfaceNodeResolver::ResolveSurfaceNode(
const MaterialX::DocumentPtr& document,
const std::string& materialName) const {
if (!materialName.empty()) {
MaterialX::NodePtr candidate = document->getNode(materialName);
if (candidate && candidate->getCategory() == "surfacematerial") {
MaterialX::NodePtr surfaceNode = candidate->getConnectedNode("surfaceshader");
if (surfaceNode) {
return surfaceNode;
}
}
if (candidate && (candidate->getCategory() == "standard_surface"
|| candidate->getCategory() == "usd_preview_surface")) {
return candidate;
}
}
for (const auto& node : document->getNodes()) {
if (node->getCategory() == "surfacematerial") {
MaterialX::NodePtr surfaceNode = node->getConnectedNode("surfaceshader");
if (surfaceNode) {
return surfaceNode;
}
}
}
for (const auto& node : document->getNodes()) {
if (node->getCategory() == "standard_surface"
|| node->getCategory() == "usd_preview_surface") {
return node;
}
}
return {};
}
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,15 @@
#pragma once
#include <MaterialXCore/Document.h>
#include <string>
namespace sdl3cpp::services::impl {
class MaterialXSurfaceNodeResolver {
public:
MaterialX::NodePtr ResolveSurfaceNode(const MaterialX::DocumentPtr& document,
const std::string& materialName) const;
};
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,81 @@
#include "materialx_surface_parameter_reader.hpp"
namespace sdl3cpp::services::impl {
bool MaterialXSurfaceParameterReader::TryReadColor3(const MaterialX::NodePtr& node,
const char* name,
std::array<float, 3>& outColor) const {
if (!node) {
return false;
}
MaterialX::InputPtr input = node->getInput(name);
if (!input || !input->hasValueString()) {
return false;
}
MaterialX::ValuePtr value = input->getValue();
if (!value || !value->isA<MaterialX::Color3>()) {
return false;
}
const MaterialX::Color3& color = value->asA<MaterialX::Color3>();
outColor = {color[0], color[1], color[2]};
return true;
}
bool MaterialXSurfaceParameterReader::TryReadFloat(const MaterialX::NodePtr& node,
const char* name,
float& outValue) const {
if (!node) {
return false;
}
MaterialX::InputPtr input = node->getInput(name);
if (!input || !input->hasValueString()) {
return false;
}
MaterialX::ValuePtr value = input->getValue();
if (!value || !value->isA<float>()) {
return false;
}
outValue = value->asA<float>();
return true;
}
MaterialXSurfaceParameters MaterialXSurfaceParameterReader::ReadStandardSurfaceParameters(
const MaterialX::NodePtr& node) const {
MaterialXSurfaceParameters parameters;
std::array<float, 3> baseColor = parameters.albedo;
bool hasBaseColor = TryReadColor3(node, "base_color", baseColor);
if (!hasBaseColor) {
hasBaseColor = TryReadColor3(node, "diffuse_color", baseColor);
}
float baseStrength = 1.0f;
bool hasBaseStrength = TryReadFloat(node, "base", baseStrength);
if (hasBaseColor) {
parameters.albedo = {
baseColor[0] * baseStrength,
baseColor[1] * baseStrength,
baseColor[2] * baseStrength
};
parameters.hasAlbedo = true;
} else if (hasBaseStrength) {
parameters.albedo = {baseStrength, baseStrength, baseStrength};
parameters.hasAlbedo = true;
}
float roughness = parameters.roughness;
if (TryReadFloat(node, "specular_roughness", roughness)
|| TryReadFloat(node, "roughness", roughness)) {
parameters.roughness = roughness;
parameters.hasRoughness = true;
}
float metallic = parameters.metallic;
if (TryReadFloat(node, "metalness", metallic)
|| TryReadFloat(node, "metallic", metallic)) {
parameters.metallic = metallic;
parameters.hasMetallic = true;
}
return parameters;
}
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,20 @@
#pragma once
#include "materialx_surface_parameters.hpp"
#include <MaterialXCore/Document.h>
#include <MaterialXCore/Types.h>
namespace sdl3cpp::services::impl {
class MaterialXSurfaceParameterReader {
public:
MaterialXSurfaceParameters ReadStandardSurfaceParameters(const MaterialX::NodePtr& node) const;
private:
bool TryReadColor3(const MaterialX::NodePtr& node, const char* name,
std::array<float, 3>& outColor) const;
bool TryReadFloat(const MaterialX::NodePtr& node, const char* name, float& outValue) const;
};
} // namespace sdl3cpp::services::impl

View File

@@ -0,0 +1,16 @@
#pragma once
#include <array>
namespace sdl3cpp::services::impl {
struct MaterialXSurfaceParameters {
std::array<float, 3> albedo = {1.0f, 1.0f, 1.0f};
float roughness = 0.3f;
float metallic = 0.0f;
bool hasAlbedo = false;
bool hasRoughness = false;
bool hasMetallic = false;
};
} // namespace sdl3cpp::services::impl

View File

@@ -1,15 +1,14 @@
#include "script_engine_service.hpp"
#include "lua_helpers.hpp"
#include "materialx_document_loader.hpp"
#include "materialx_path_resolver.hpp"
#include "materialx_surface_node_resolver.hpp"
#include "materialx_surface_parameter_reader.hpp"
#include "services/interfaces/i_logger.hpp"
#include <btBulletDynamicsCommon.h>
#include <lua.hpp>
#include <MaterialXCore/Document.h>
#include <MaterialXCore/Types.h>
#include <MaterialXFormat/File.h>
#include <MaterialXFormat/Util.h>
#include <MaterialXFormat/XmlIo.h>
#include <SDL3/SDL.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
@@ -24,17 +23,6 @@
#include <vector>
namespace {
namespace mx = MaterialX;
struct MaterialXSurfaceParameters {
std::array<float, 3> albedo = {1.0f, 1.0f, 1.0f};
float roughness = 0.3f;
float metallic = 0.0f;
bool hasAlbedo = false;
bool hasRoughness = false;
bool hasMetallic = false;
};
std::array<float, 3> TransformPoint(const std::array<float, 16>& matrix,
const std::array<float, 3>& point) {
const float x = point[0];
@@ -47,174 +35,6 @@ std::array<float, 3> TransformPoint(const std::array<float, 16>& matrix,
};
}
std::filesystem::path ResolveMaterialXPath(const std::filesystem::path& path,
const std::filesystem::path& scriptDirectory) {
if (path.empty()) {
return {};
}
if (path.is_absolute()) {
return path;
}
if (!scriptDirectory.empty()) {
auto projectRoot = scriptDirectory.parent_path();
if (!projectRoot.empty()) {
std::error_code ec;
auto resolved = std::filesystem::weakly_canonical(projectRoot / path, ec);
if (!ec) {
return resolved;
}
}
}
std::error_code ec;
auto resolved = std::filesystem::weakly_canonical(path, ec);
if (ec) {
return {};
}
return resolved;
}
mx::FileSearchPath BuildMaterialXSearchPath(const sdl3cpp::services::MaterialXConfig& config,
const std::filesystem::path& scriptDirectory) {
mx::FileSearchPath searchPath;
std::filesystem::path libraryPath = ResolveMaterialXPath(config.libraryPath, scriptDirectory);
if (libraryPath.empty() && !scriptDirectory.empty()) {
auto fallback = scriptDirectory.parent_path() / "MaterialX" / "libraries";
if (std::filesystem::exists(fallback)) {
libraryPath = fallback;
}
}
if (!libraryPath.empty()) {
searchPath.append(mx::FilePath(libraryPath.string()));
}
return searchPath;
}
mx::DocumentPtr LoadMaterialXDocument(const std::filesystem::path& documentPath,
const sdl3cpp::services::MaterialXConfig& config,
const std::filesystem::path& scriptDirectory) {
mx::DocumentPtr document = mx::createDocument();
mx::FileSearchPath searchPath = BuildMaterialXSearchPath(config, scriptDirectory);
mx::readFromXmlFile(document, mx::FilePath(documentPath.string()), searchPath);
if (!config.libraryFolders.empty()) {
mx::DocumentPtr stdLib = mx::createDocument();
mx::FilePathVec folders;
folders.reserve(config.libraryFolders.size());
for (const auto& folder : config.libraryFolders) {
folders.emplace_back(folder);
}
mx::loadLibraries(folders, searchPath, stdLib);
document->importLibrary(stdLib);
}
return document;
}
mx::NodePtr ResolveSurfaceNode(const mx::DocumentPtr& document, const std::string& materialName) {
if (!materialName.empty()) {
mx::NodePtr candidate = document->getNode(materialName);
if (candidate && candidate->getCategory() == "surfacematerial") {
mx::NodePtr surfaceNode = candidate->getConnectedNode("surfaceshader");
if (surfaceNode) {
return surfaceNode;
}
}
if (candidate && (candidate->getCategory() == "standard_surface"
|| candidate->getCategory() == "usd_preview_surface")) {
return candidate;
}
}
for (const auto& node : document->getNodes()) {
if (node->getCategory() == "surfacematerial") {
mx::NodePtr surfaceNode = node->getConnectedNode("surfaceshader");
if (surfaceNode) {
return surfaceNode;
}
}
}
for (const auto& node : document->getNodes()) {
if (node->getCategory() == "standard_surface"
|| node->getCategory() == "usd_preview_surface") {
return node;
}
}
return {};
}
bool TryReadColor3(const mx::NodePtr& node, const char* name, std::array<float, 3>& outColor) {
if (!node) {
return false;
}
mx::InputPtr input = node->getInput(name);
if (!input || !input->hasValueString()) {
return false;
}
mx::ValuePtr value = input->getValue();
if (!value || !value->isA<mx::Color3>()) {
return false;
}
const mx::Color3& color = value->asA<mx::Color3>();
outColor = {color[0], color[1], color[2]};
return true;
}
bool TryReadFloat(const mx::NodePtr& node, const char* name, float& outValue) {
if (!node) {
return false;
}
mx::InputPtr input = node->getInput(name);
if (!input || !input->hasValueString()) {
return false;
}
mx::ValuePtr value = input->getValue();
if (!value || !value->isA<float>()) {
return false;
}
outValue = value->asA<float>();
return true;
}
MaterialXSurfaceParameters ReadStandardSurfaceParameters(const mx::NodePtr& node) {
MaterialXSurfaceParameters parameters;
std::array<float, 3> baseColor = parameters.albedo;
bool hasBaseColor = TryReadColor3(node, "base_color", baseColor);
if (!hasBaseColor) {
hasBaseColor = TryReadColor3(node, "diffuse_color", baseColor);
}
float baseStrength = 1.0f;
bool hasBaseStrength = TryReadFloat(node, "base", baseStrength);
if (hasBaseColor) {
parameters.albedo = {
baseColor[0] * baseStrength,
baseColor[1] * baseStrength,
baseColor[2] * baseStrength
};
parameters.hasAlbedo = true;
} else if (hasBaseStrength) {
parameters.albedo = {baseStrength, baseStrength, baseStrength};
parameters.hasAlbedo = true;
}
float roughness = parameters.roughness;
if (TryReadFloat(node, "specular_roughness", roughness)
|| TryReadFloat(node, "roughness", roughness)) {
parameters.roughness = roughness;
parameters.hasRoughness = true;
}
float metallic = parameters.metallic;
if (TryReadFloat(node, "metalness", metallic)
|| TryReadFloat(node, "metallic", metallic)) {
parameters.metallic = metallic;
parameters.hasMetallic = true;
}
return parameters;
}
bool TryParseMouseButtonName(const char* name, uint8_t& button) {
if (!name) {
return false;
@@ -1356,7 +1176,8 @@ int ScriptEngineService::MaterialXGetSurfaceParameters(lua_State* L) {
", material=" + std::string(materialArg ? materialArg : ""));
}
std::filesystem::path documentPath = ResolveMaterialXPath(documentArg ? documentArg : "", scriptDirectory);
MaterialXPathResolver pathResolver;
std::filesystem::path documentPath = pathResolver.Resolve(documentArg ? documentArg : "", scriptDirectory);
if (documentPath.empty()) {
lua_pushnil(L);
lua_pushstring(L, "MaterialX document path could not be resolved");
@@ -1370,9 +1191,12 @@ int ScriptEngineService::MaterialXGetSurfaceParameters(lua_State* L) {
}
const auto& materialConfig = context->configService->GetMaterialXConfig();
mx::DocumentPtr document;
MaterialXDocumentLoader documentLoader;
MaterialXSurfaceNodeResolver nodeResolver;
MaterialXSurfaceParameterReader parameterReader;
MaterialX::DocumentPtr document;
try {
document = LoadMaterialXDocument(documentPath, materialConfig, scriptDirectory);
document = documentLoader.Load(documentPath, materialConfig, scriptDirectory);
} catch (const std::exception& ex) {
lua_pushnil(L);
std::string message = "MaterialX document load failed: ";
@@ -1381,14 +1205,14 @@ int ScriptEngineService::MaterialXGetSurfaceParameters(lua_State* L) {
return 2;
}
mx::NodePtr surfaceNode = ResolveSurfaceNode(document, materialArg ? materialArg : "");
auto surfaceNode = nodeResolver.ResolveSurfaceNode(document, materialArg ? materialArg : "");
if (!surfaceNode) {
lua_pushnil(L);
lua_pushstring(L, "MaterialX document has no standard_surface material");
return 2;
}
MaterialXSurfaceParameters parameters = ReadStandardSurfaceParameters(surfaceNode);
MaterialXSurfaceParameters parameters = parameterReader.ReadStandardSurfaceParameters(surfaceNode);
if (!parameters.hasAlbedo && !parameters.hasRoughness && !parameters.hasMetallic) {
lua_pushnil(L);
lua_pushstring(L, "MaterialX material does not expose supported PBR parameters");

View File

@@ -4,6 +4,7 @@
#include "workflow_config_version_step.hpp"
#include <stdexcept>
#include <unordered_set>
#include <utility>
namespace sdl3cpp::services::impl {
@@ -13,13 +14,27 @@ WorkflowDefaultStepRegistrar::WorkflowDefaultStepRegistrar(std::shared_ptr<ILogg
: logger_(std::move(logger)),
probeService_(std::move(probeService)) {}
void WorkflowDefaultStepRegistrar::RegisterDefaults(const std::shared_ptr<IWorkflowStepRegistry>& registry) const {
void WorkflowDefaultStepRegistrar::RegisterUsedSteps(
const WorkflowDefinition& workflow,
const std::shared_ptr<IWorkflowStepRegistry>& registry) const {
if (!registry) {
throw std::runtime_error("WorkflowDefaultStepRegistrar: registry is null");
}
registry->RegisterStep(std::make_shared<WorkflowConfigLoadStep>(logger_));
registry->RegisterStep(std::make_shared<WorkflowConfigVersionStep>(logger_));
registry->RegisterStep(std::make_shared<WorkflowConfigSchemaStep>(logger_, probeService_));
std::unordered_set<std::string> plugins;
for (const auto& step : workflow.steps) {
plugins.insert(step.plugin);
}
if (plugins.contains("config.load")) {
registry->RegisterStep(std::make_shared<WorkflowConfigLoadStep>(logger_));
}
if (plugins.contains("config.version.validate")) {
registry->RegisterStep(std::make_shared<WorkflowConfigVersionStep>(logger_));
}
if (plugins.contains("config.schema.validate")) {
registry->RegisterStep(std::make_shared<WorkflowConfigSchemaStep>(logger_, probeService_));
}
}
} // namespace sdl3cpp::services::impl

View File

@@ -3,6 +3,7 @@
#include "../interfaces/i_logger.hpp"
#include "../interfaces/i_probe_service.hpp"
#include "../interfaces/i_workflow_step_registry.hpp"
#include "../interfaces/workflow_definition.hpp"
namespace sdl3cpp::services::impl {
@@ -11,7 +12,8 @@ public:
WorkflowDefaultStepRegistrar(std::shared_ptr<ILogger> logger,
std::shared_ptr<IProbeService> probeService);
void RegisterDefaults(const std::shared_ptr<IWorkflowStepRegistry>& registry) const;
void RegisterUsedSteps(const WorkflowDefinition& workflow,
const std::shared_ptr<IWorkflowStepRegistry>& registry) const;
private:
std::shared_ptr<ILogger> logger_;