diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e6b514..f295d0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,6 +117,8 @@ set(APP_SOURCES "${APP_DIR}/runtime/events/RuntimeEventPayloads.h" "${APP_DIR}/runtime/events/RuntimeEventQueue.h" "${APP_DIR}/runtime/events/RuntimeEventType.h" + "${APP_DIR}/runtime/live/CommittedLiveState.cpp" + "${APP_DIR}/runtime/live/CommittedLiveState.h" "${APP_DIR}/runtime/live/RenderStateComposer.cpp" "${APP_DIR}/runtime/live/RenderStateComposer.h" "${APP_DIR}/runtime/live/RuntimeStateLayerModel.cpp" @@ -337,6 +339,7 @@ add_test(NAME RuntimeStateLayerModelTests COMMAND RuntimeStateLayerModelTests) add_executable(RuntimeSubsystemTests "${APP_DIR}/runtime/coordination/RuntimeCoordinator.cpp" + "${APP_DIR}/runtime/live/CommittedLiveState.cpp" "${APP_DIR}/runtime/snapshot/RenderSnapshotBuilder.cpp" "${APP_DIR}/runtime/store/LayerStackStore.cpp" "${APP_DIR}/runtime/store/RuntimeConfigStore.cpp" @@ -359,6 +362,7 @@ target_include_directories(RuntimeSubsystemTests PRIVATE "${APP_DIR}/runtime" "${APP_DIR}/runtime/coordination" "${APP_DIR}/runtime/events" + "${APP_DIR}/runtime/live" "${APP_DIR}/runtime/presentation" "${APP_DIR}/runtime/snapshot" "${APP_DIR}/runtime/store" diff --git a/apps/LoopThroughWithOpenGLCompositing/runtime/live/CommittedLiveState.cpp b/apps/LoopThroughWithOpenGLCompositing/runtime/live/CommittedLiveState.cpp new file mode 100644 index 0000000..e928ab9 --- /dev/null +++ b/apps/LoopThroughWithOpenGLCompositing/runtime/live/CommittedLiveState.cpp @@ -0,0 +1,144 @@ +#include "CommittedLiveState.h" + +bool CommittedLiveState::LoadPersistentStateValue(const JsonValue& root) +{ + return mLayerStack.LoadPersistentStateValue(root); +} + +JsonValue CommittedLiveState::BuildPersistentStateValue(const ShaderPackageCatalog& shaderCatalog) const +{ + return mLayerStack.BuildPersistentStateValue(shaderCatalog); +} + +void CommittedLiveState::NormalizeLayerIds() +{ + mLayerStack.NormalizeLayerIds(); +} + +void CommittedLiveState::EnsureDefaultsForAllLayers(const ShaderPackageCatalog& shaderCatalog) +{ + mLayerStack.EnsureDefaultsForAllLayers(shaderCatalog); +} + +void CommittedLiveState::EnsureDefaultLayer(const ShaderPackageCatalog& shaderCatalog) +{ + mLayerStack.EnsureDefaultLayer(shaderCatalog); +} + +void CommittedLiveState::RemoveLayersWithMissingPackages(const ShaderPackageCatalog& shaderCatalog) +{ + mLayerStack.RemoveLayersWithMissingPackages(shaderCatalog); +} + +bool CommittedLiveState::CreateLayer(const ShaderPackageCatalog& shaderCatalog, const std::string& shaderId, std::string& error) +{ + return mLayerStack.CreateLayer(shaderCatalog, shaderId, error); +} + +bool CommittedLiveState::DeleteLayer(const std::string& layerId, std::string& error) +{ + return mLayerStack.DeleteLayer(layerId, error); +} + +bool CommittedLiveState::MoveLayer(const std::string& layerId, int direction, std::string& error) +{ + return mLayerStack.MoveLayer(layerId, direction, error); +} + +bool CommittedLiveState::MoveLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error) +{ + return mLayerStack.MoveLayerToIndex(layerId, targetIndex, error); +} + +bool CommittedLiveState::SetLayerBypassState(const std::string& layerId, bool bypassed, std::string& error) +{ + return mLayerStack.SetLayerBypassState(layerId, bypassed, error); +} + +bool CommittedLiveState::SetLayerShaderSelection(const ShaderPackageCatalog& shaderCatalog, const std::string& layerId, const std::string& shaderId, std::string& error) +{ + return mLayerStack.SetLayerShaderSelection(shaderCatalog, layerId, shaderId, error); +} + +bool CommittedLiveState::SetParameterValue(const std::string& layerId, const std::string& parameterId, const ShaderParameterValue& value, std::string& error) +{ + return mLayerStack.SetParameterValue(layerId, parameterId, value, error); +} + +bool CommittedLiveState::ResetLayerParameterValues(const ShaderPackageCatalog& shaderCatalog, const std::string& layerId, std::string& error) +{ + return mLayerStack.ResetLayerParameterValues(shaderCatalog, layerId, error); +} + +bool CommittedLiveState::HasLayer(const std::string& layerId) const +{ + return mLayerStack.HasLayer(layerId); +} + +bool CommittedLiveState::TryGetParameterById(const ShaderPackageCatalog& shaderCatalog, const std::string& layerId, const std::string& parameterId, StoredParameterSnapshot& snapshot, std::string& error) const +{ + return mLayerStack.TryGetParameterById(shaderCatalog, layerId, parameterId, snapshot, error); +} + +bool CommittedLiveState::TryGetParameterByControlKey(const ShaderPackageCatalog& shaderCatalog, const std::string& layerKey, const std::string& parameterKey, StoredParameterSnapshot& snapshot, std::string& error) const +{ + return mLayerStack.TryGetParameterByControlKey(shaderCatalog, layerKey, parameterKey, snapshot, error); +} + +bool CommittedLiveState::ResolveLayerMove(const std::string& layerId, int direction, bool& shouldMove, std::string& error) const +{ + return mLayerStack.ResolveLayerMove(layerId, direction, shouldMove, error); +} + +bool CommittedLiveState::ResolveLayerMoveToIndex(const std::string& layerId, std::size_t targetIndex, bool& shouldMove, std::string& error) const +{ + return mLayerStack.ResolveLayerMoveToIndex(layerId, targetIndex, shouldMove, error); +} + +JsonValue CommittedLiveState::BuildStackPresetValue(const ShaderPackageCatalog& shaderCatalog, const std::string& presetName) const +{ + return mLayerStack.BuildStackPresetValue(shaderCatalog, presetName); +} + +bool CommittedLiveState::LoadStackPresetValue(const ShaderPackageCatalog& shaderCatalog, const JsonValue& root, std::string& error) +{ + return mLayerStack.LoadStackPresetValue(shaderCatalog, root, error); +} + +CommittedLiveStateReadModel CommittedLiveState::BuildReadModel(const ShaderPackageCatalog& shaderCatalog) const +{ + CommittedLiveStateReadModel model; + model.layers = mLayerStack.Layers(); + model.packagesById = shaderCatalog.CaptureSnapshot().packagesById; + return model; +} + +std::vector CommittedLiveState::CopyLayerStates() const +{ + return mLayerStack.Layers(); +} + +const std::vector& CommittedLiveState::Layers() const +{ + return mLayerStack.Layers(); +} + +std::vector& CommittedLiveState::Layers() +{ + return mLayerStack.Layers(); +} + +const CommittedLiveState::LayerPersistentState* CommittedLiveState::FindLayerById(const std::string& layerId) const +{ + return mLayerStack.FindLayerById(layerId); +} + +const LayerStackStore& CommittedLiveState::LayerStack() const +{ + return mLayerStack; +} + +LayerStackStore& CommittedLiveState::LayerStack() +{ + return mLayerStack; +} diff --git a/apps/LoopThroughWithOpenGLCompositing/runtime/live/CommittedLiveState.h b/apps/LoopThroughWithOpenGLCompositing/runtime/live/CommittedLiveState.h new file mode 100644 index 0000000..4e9c1aa --- /dev/null +++ b/apps/LoopThroughWithOpenGLCompositing/runtime/live/CommittedLiveState.h @@ -0,0 +1,52 @@ +#pragma once + +#include "LayerStackStore.h" +#include "RuntimeStoreReadModels.h" +#include "ShaderPackageCatalog.h" + +#include +#include +#include + +class CommittedLiveState +{ +public: + using LayerPersistentState = LayerStackStore::LayerPersistentState; + using StoredParameterSnapshot = LayerStackStore::StoredParameterSnapshot; + + bool LoadPersistentStateValue(const JsonValue& root); + JsonValue BuildPersistentStateValue(const ShaderPackageCatalog& shaderCatalog) const; + void NormalizeLayerIds(); + void EnsureDefaultsForAllLayers(const ShaderPackageCatalog& shaderCatalog); + void EnsureDefaultLayer(const ShaderPackageCatalog& shaderCatalog); + void RemoveLayersWithMissingPackages(const ShaderPackageCatalog& shaderCatalog); + + bool CreateLayer(const ShaderPackageCatalog& shaderCatalog, const std::string& shaderId, std::string& error); + bool DeleteLayer(const std::string& layerId, std::string& error); + bool MoveLayer(const std::string& layerId, int direction, std::string& error); + bool MoveLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error); + bool SetLayerBypassState(const std::string& layerId, bool bypassed, std::string& error); + bool SetLayerShaderSelection(const ShaderPackageCatalog& shaderCatalog, const std::string& layerId, const std::string& shaderId, std::string& error); + bool SetParameterValue(const std::string& layerId, const std::string& parameterId, const ShaderParameterValue& value, std::string& error); + bool ResetLayerParameterValues(const ShaderPackageCatalog& shaderCatalog, const std::string& layerId, std::string& error); + + bool HasLayer(const std::string& layerId) const; + bool TryGetParameterById(const ShaderPackageCatalog& shaderCatalog, const std::string& layerId, const std::string& parameterId, StoredParameterSnapshot& snapshot, std::string& error) const; + bool TryGetParameterByControlKey(const ShaderPackageCatalog& shaderCatalog, const std::string& layerKey, const std::string& parameterKey, StoredParameterSnapshot& snapshot, std::string& error) const; + bool ResolveLayerMove(const std::string& layerId, int direction, bool& shouldMove, std::string& error) const; + bool ResolveLayerMoveToIndex(const std::string& layerId, std::size_t targetIndex, bool& shouldMove, std::string& error) const; + + JsonValue BuildStackPresetValue(const ShaderPackageCatalog& shaderCatalog, const std::string& presetName) const; + bool LoadStackPresetValue(const ShaderPackageCatalog& shaderCatalog, const JsonValue& root, std::string& error); + + CommittedLiveStateReadModel BuildReadModel(const ShaderPackageCatalog& shaderCatalog) const; + std::vector CopyLayerStates() const; + const std::vector& Layers() const; + std::vector& Layers(); + const LayerPersistentState* FindLayerById(const std::string& layerId) const; + const LayerStackStore& LayerStack() const; + LayerStackStore& LayerStack(); + +private: + LayerStackStore mLayerStack; +}; diff --git a/apps/LoopThroughWithOpenGLCompositing/runtime/live/RuntimeStateLayerModel.cpp b/apps/LoopThroughWithOpenGLCompositing/runtime/live/RuntimeStateLayerModel.cpp index 906c791..5d63152 100644 --- a/apps/LoopThroughWithOpenGLCompositing/runtime/live/RuntimeStateLayerModel.cpp +++ b/apps/LoopThroughWithOpenGLCompositing/runtime/live/RuntimeStateLayerModel.cpp @@ -92,7 +92,7 @@ std::vector GetRuntimeStateLayerInventory() { RuntimeStateLayerKind::CommittedLive, "Committed live state", - "RuntimeCoordinator, physically backed by RuntimeStore during migration", + "RuntimeCoordinator / CommittedLiveState", "Current running session", "May request persistence depending on mutation policy", "Operator/session truth until changed again" @@ -152,14 +152,14 @@ std::vector GetRuntimeStateFieldInventory() RuntimeStateField::CommittedSessionParameterValues, ClassifyRuntimeStateField(RuntimeStateField::CommittedSessionParameterValues), "committed session parameter values", - "RuntimeCoordinator policy, RuntimeStore backing during migration", + "RuntimeCoordinator policy, CommittedLiveState backing", "Operator/API truth after accepted mutations" }, { RuntimeStateField::CommittedLayerBypass, ClassifyRuntimeStateField(RuntimeStateField::CommittedLayerBypass), "committed layer bypass", - "RuntimeCoordinator policy, RuntimeStore backing during migration", + "RuntimeCoordinator policy, CommittedLiveState backing", "Current operator/API bypass state" }, { @@ -227,4 +227,3 @@ std::vector GetRuntimeStateFieldInventory() } }; } - diff --git a/apps/LoopThroughWithOpenGLCompositing/runtime/store/RuntimeStore.cpp b/apps/LoopThroughWithOpenGLCompositing/runtime/store/RuntimeStore.cpp index 1d9e750..720968d 100644 --- a/apps/LoopThroughWithOpenGLCompositing/runtime/store/RuntimeStore.cpp +++ b/apps/LoopThroughWithOpenGLCompositing/runtime/store/RuntimeStore.cpp @@ -72,9 +72,9 @@ bool RuntimeStore::InitializeStore(std::string& error) return false; if (!ScanShaderPackages(error)) return false; - mLayerStack.NormalizeLayerIds(); - mLayerStack.EnsureDefaultsForAllLayers(mShaderCatalog); - mLayerStack.EnsureDefaultLayer(mShaderCatalog); + mCommittedLiveState.NormalizeLayerIds(); + mCommittedLiveState.EnsureDefaultsForAllLayers(mShaderCatalog); + mCommittedLiveState.EnsureDefaultLayer(mShaderCatalog); mServerPort = mConfigStore.GetConfig().serverPort; mAutoReloadEnabled = mConfigStore.GetConfig().autoReload; @@ -133,8 +133,8 @@ bool RuntimeStore::PollStoredFileChanges(bool& registryChanged, bool& reloadRequ registryChanged = mShaderCatalog.HasCatalogChangedSince(previousCatalog); - mLayerStack.EnsureDefaultsForAllLayers(mShaderCatalog); - for (RuntimeStore::LayerPersistentState& layer : mLayerStack.Layers()) + mCommittedLiveState.EnsureDefaultsForAllLayers(mShaderCatalog); + for (RuntimeStore::LayerPersistentState& layer : mCommittedLiveState.Layers()) { const ShaderPackage* active = mShaderCatalog.FindPackage(layer.shaderId); if (!active) @@ -163,7 +163,7 @@ bool RuntimeStore::PollStoredFileChanges(bool& registryChanged, bool& reloadRequ bool RuntimeStore::CreateStoredLayer(const std::string& shaderId, std::string& error) { std::lock_guard lock(mMutex); - if (!mLayerStack.CreateLayer(mShaderCatalog, shaderId, error)) + if (!mCommittedLiveState.CreateLayer(mShaderCatalog, shaderId, error)) return false; mReloadRequested = true; @@ -174,7 +174,7 @@ bool RuntimeStore::CreateStoredLayer(const std::string& shaderId, std::string& e bool RuntimeStore::DeleteStoredLayer(const std::string& layerId, std::string& error) { std::lock_guard lock(mMutex); - if (!mLayerStack.DeleteLayer(layerId, error)) + if (!mCommittedLiveState.DeleteLayer(layerId, error)) return false; mReloadRequested = true; @@ -186,12 +186,12 @@ bool RuntimeStore::MoveStoredLayer(const std::string& layerId, int direction, st { std::lock_guard lock(mMutex); bool shouldMove = false; - if (!mLayerStack.ResolveLayerMove(layerId, direction, shouldMove, error)) + if (!mCommittedLiveState.ResolveLayerMove(layerId, direction, shouldMove, error)) return false; if (!shouldMove) return true; - if (!mLayerStack.MoveLayer(layerId, direction, error)) + if (!mCommittedLiveState.MoveLayer(layerId, direction, error)) return false; mReloadRequested = true; @@ -203,12 +203,12 @@ bool RuntimeStore::MoveStoredLayerToIndex(const std::string& layerId, std::size_ { std::lock_guard lock(mMutex); bool shouldMove = false; - if (!mLayerStack.ResolveLayerMoveToIndex(layerId, targetIndex, shouldMove, error)) + if (!mCommittedLiveState.ResolveLayerMoveToIndex(layerId, targetIndex, shouldMove, error)) return false; if (!shouldMove) return true; - if (!mLayerStack.MoveLayerToIndex(layerId, targetIndex, error)) + if (!mCommittedLiveState.MoveLayerToIndex(layerId, targetIndex, error)) return false; mReloadRequested = true; @@ -219,7 +219,7 @@ bool RuntimeStore::MoveStoredLayerToIndex(const std::string& layerId, std::size_ bool RuntimeStore::SetStoredLayerBypassState(const std::string& layerId, bool bypassed, std::string& error) { std::lock_guard lock(mMutex); - if (!mLayerStack.SetLayerBypassState(layerId, bypassed, error)) + if (!mCommittedLiveState.SetLayerBypassState(layerId, bypassed, error)) return false; mReloadRequested = true; @@ -230,7 +230,7 @@ bool RuntimeStore::SetStoredLayerBypassState(const std::string& layerId, bool by bool RuntimeStore::SetStoredLayerShaderSelection(const std::string& layerId, const std::string& shaderId, std::string& error) { std::lock_guard lock(mMutex); - if (!mLayerStack.SetLayerShaderSelection(mShaderCatalog, layerId, shaderId, error)) + if (!mCommittedLiveState.SetLayerShaderSelection(mShaderCatalog, layerId, shaderId, error)) return false; mReloadRequested = true; @@ -242,7 +242,7 @@ bool RuntimeStore::SetStoredParameterValue(const std::string& layerId, const std { std::lock_guard lock(mMutex); - if (!mLayerStack.SetParameterValue(layerId, parameterId, value, error)) + if (!mCommittedLiveState.SetParameterValue(layerId, parameterId, value, error)) return false; MarkParameterStateDirtyLocked(); @@ -253,7 +253,7 @@ bool RuntimeStore::ResetStoredLayerParameterValues(const std::string& layerId, s { std::lock_guard lock(mMutex); - if (!mLayerStack.ResetLayerParameterValues(mShaderCatalog, layerId, error)) + if (!mCommittedLiveState.ResetLayerParameterValues(mShaderCatalog, layerId, error)) return false; MarkParameterStateDirtyLocked(); @@ -271,7 +271,7 @@ bool RuntimeStore::SaveStackPresetSnapshot(const std::string& presetName, std::s } JsonValue root = JsonValue::MakeObject(); - root = mLayerStack.BuildStackPresetValue(mShaderCatalog, presetName); + root = mCommittedLiveState.BuildStackPresetValue(mShaderCatalog, presetName); return WriteTextFile(mConfigStore.GetPresetRoot() / (safeStem + ".json"), SerializeJson(root, true), error); } @@ -295,7 +295,7 @@ bool RuntimeStore::LoadStackPresetSnapshot(const std::string& presetName, std::s if (!ParseJson(presetText, root, error)) return false; - if (!mLayerStack.LoadStackPresetValue(mShaderCatalog, root, error)) + if (!mCommittedLiveState.LoadStackPresetValue(mShaderCatalog, root, error)) return false; mReloadRequested = true; @@ -306,7 +306,7 @@ bool RuntimeStore::LoadStackPresetSnapshot(const std::string& presetName, std::s bool RuntimeStore::HasStoredLayer(const std::string& layerId) const { std::lock_guard lock(mMutex); - return mLayerStack.HasLayer(layerId); + return mCommittedLiveState.HasLayer(layerId); } bool RuntimeStore::HasStoredShader(const std::string& shaderId) const @@ -319,26 +319,26 @@ bool RuntimeStore::TryGetStoredParameterById(const std::string& layerId, const s { std::lock_guard lock(mMutex); - return mLayerStack.TryGetParameterById(mShaderCatalog, layerId, parameterId, snapshot, error); + return mCommittedLiveState.TryGetParameterById(mShaderCatalog, layerId, parameterId, snapshot, error); } bool RuntimeStore::TryGetStoredParameterByControlKey(const std::string& layerKey, const std::string& parameterKey, StoredParameterSnapshot& snapshot, std::string& error) const { std::lock_guard lock(mMutex); - return mLayerStack.TryGetParameterByControlKey(mShaderCatalog, layerKey, parameterKey, snapshot, error); + return mCommittedLiveState.TryGetParameterByControlKey(mShaderCatalog, layerKey, parameterKey, snapshot, error); } bool RuntimeStore::ResolveStoredLayerMove(const std::string& layerId, int direction, bool& shouldMove, std::string& error) const { std::lock_guard lock(mMutex); - return mLayerStack.ResolveLayerMove(layerId, direction, shouldMove, error); + return mCommittedLiveState.ResolveLayerMove(layerId, direction, shouldMove, error); } bool RuntimeStore::ResolveStoredLayerMoveToIndex(const std::string& layerId, std::size_t targetIndex, bool& shouldMove, std::string& error) const { std::lock_guard lock(mMutex); - return mLayerStack.ResolveLayerMoveToIndex(layerId, targetIndex, shouldMove, error); + return mCommittedLiveState.ResolveLayerMoveToIndex(layerId, targetIndex, shouldMove, error); } bool RuntimeStore::IsValidStackPresetName(const std::string& presetName) const @@ -460,12 +460,12 @@ bool RuntimeStore::LoadPersistentState(std::string& error) if (!ParseJson(stateText, root, error)) return false; - return mLayerStack.LoadPersistentStateValue(root); + return mCommittedLiveState.LoadPersistentStateValue(root); } bool RuntimeStore::SavePersistentState(std::string& error) const { - return WriteTextFile(mConfigStore.GetRuntimeStatePath(), SerializeJson(mLayerStack.BuildPersistentStateValue(mShaderCatalog), true), error); + return WriteTextFile(mConfigStore.GetRuntimeStatePath(), SerializeJson(mCommittedLiveState.BuildPersistentStateValue(mShaderCatalog), true), error); } bool RuntimeStore::ScanShaderPackages(std::string& error) @@ -473,7 +473,7 @@ bool RuntimeStore::ScanShaderPackages(std::string& error) if (!mShaderCatalog.Scan(mConfigStore.GetShaderRoot(), mConfigStore.GetConfig().maxTemporalHistoryFrames, error)) return false; - mLayerStack.RemoveLayersWithMissingPackages(mShaderCatalog); + mCommittedLiveState.RemoveLayersWithMissingPackages(mShaderCatalog); MarkRenderStateDirtyLocked(); return true; @@ -548,7 +548,7 @@ std::vector RuntimeStore::GetStackPresetNamesLocked() const bool RuntimeStore::CopyShaderPackageForStoredLayer(const std::string& layerId, ShaderPackage& shaderPackage, std::string& error) const { std::lock_guard lock(mMutex); - const RuntimeStore::LayerPersistentState* layer = mLayerStack.FindLayerById(layerId); + const RuntimeStore::LayerPersistentState* layer = mCommittedLiveState.FindLayerById(layerId); if (!layer) { error = "Unknown layer id: " + layerId; @@ -578,11 +578,8 @@ ShaderCompilerInputs RuntimeStore::GetShaderCompilerInputs() const CommittedLiveStateReadModel RuntimeStore::BuildCommittedLiveStateReadModel() const { - CommittedLiveStateReadModel model; std::lock_guard lock(mMutex); - model.layers = mLayerStack.Layers(); - model.packagesById = mShaderCatalog.CaptureSnapshot().packagesById; - return model; + return mCommittedLiveState.BuildReadModel(mShaderCatalog); } RenderSnapshotReadModel RuntimeStore::BuildRenderSnapshotReadModel() const @@ -599,7 +596,7 @@ RenderSnapshotReadModel RuntimeStore::BuildRenderSnapshotReadModel() const std::vector RuntimeStore::CopyCommittedLiveLayerStates() const { std::lock_guard lock(mMutex); - return mLayerStack.Layers(); + return mCommittedLiveState.CopyLayerStates(); } std::vector RuntimeStore::CopyLayerStates() const @@ -622,7 +619,7 @@ RuntimeStatePresentationReadModel RuntimeStore::BuildRuntimeStatePresentationRea model.telemetry = mHealthTelemetry.GetSnapshot(); std::lock_guard lock(mMutex); model.config = mConfigStore.GetConfig(); - model.layerStack = mLayerStack; + model.layerStack = mCommittedLiveState.LayerStack(); model.shaderCatalog = mShaderCatalog.CaptureSnapshot(); model.packageStatuses = mShaderCatalog.PackageStatuses(); model.stackPresetNames = GetStackPresetNamesLocked(); diff --git a/apps/LoopThroughWithOpenGLCompositing/runtime/store/RuntimeStore.h b/apps/LoopThroughWithOpenGLCompositing/runtime/store/RuntimeStore.h index 4678a30..36eab92 100644 --- a/apps/LoopThroughWithOpenGLCompositing/runtime/store/RuntimeStore.h +++ b/apps/LoopThroughWithOpenGLCompositing/runtime/store/RuntimeStore.h @@ -1,6 +1,7 @@ #pragma once #include "HealthTelemetry.h" +#include "CommittedLiveState.h" #include "LayerStackStore.h" #include "RenderSnapshotBuilder.h" #include "RuntimeConfigStore.h" @@ -91,7 +92,7 @@ private: RenderSnapshotBuilder mRenderSnapshotBuilder; RuntimeConfigStore mConfigStore; ShaderPackageCatalog mShaderCatalog; - LayerStackStore mLayerStack; + CommittedLiveState mCommittedLiveState; HealthTelemetry mHealthTelemetry; mutable std::mutex mMutex; bool mReloadRequested; diff --git a/docs/PHASE_5_LIVE_STATE_LAYERING_DESIGN.md b/docs/PHASE_5_LIVE_STATE_LAYERING_DESIGN.md index 13df73f..8d808e0 100644 --- a/docs/PHASE_5_LIVE_STATE_LAYERING_DESIGN.md +++ b/docs/PHASE_5_LIVE_STATE_LAYERING_DESIGN.md @@ -8,7 +8,7 @@ Phase 1 named the subsystems. Phase 2 added the typed event substrate. Phase 3 m - Phase 5 design package: proposed. - Phase 5 implementation: Step 5 complete. -- Current alignment: Phase 3 introduced the first pure composition boundary and transient OSC overlay owner. Phase 5 now has a small `RuntimeStateLayerModel` inventory that names the current state categories, `RenderStateComposer` consumes a `LayeredRenderStateInput` whose fields make base persisted, committed live, and transient automation inputs explicit, `RuntimeLiveState` owns transient-overlay invalidation against current layer/parameter compatibility, settled OSC commits have an explicit session-only persistence policy, and snapshot publication consumes a named `CommittedLiveStateReadModel`. Committed runtime values are still physically backed by `RuntimeStore`/`LayerStackStore` during this conservative migration step. +- Current alignment: Phase 3 introduced the first pure composition boundary and transient OSC overlay owner. Phase 5 now has a small `RuntimeStateLayerModel` inventory that names the current state categories, `RenderStateComposer` consumes a `LayeredRenderStateInput` whose fields make base persisted, committed live, and transient automation inputs explicit, `RuntimeLiveState` owns transient-overlay invalidation against current layer/parameter compatibility, settled OSC commits have an explicit session-only persistence policy, and `CommittedLiveState` physically owns current session layer state. `RuntimeStore` still owns file IO, config, package metadata, preset persistence, and persistence requests. Current live-state footholds: @@ -21,7 +21,7 @@ Current live-state footholds: - `RuntimeStateLayerModel` names the Phase 5 state categories and classifies current fields as base persisted, committed live, transient automation, render-local, or health/config state. - `RuntimeCoordinator` can request layer-scoped transient OSC invalidation, while `RuntimeLiveState` prunes overlays that no longer map to the current render-facing layer/parameter definitions. - `RuntimeCoordinator::CommitOscParameterByControlKey(...)` commits settled OSC values into session state without requesting persistence by default. -- `CommittedLiveStateReadModel` names the current committed/session read boundary that feeds render snapshot publication while remaining physically backed by `RuntimeStore`. +- `CommittedLiveState` owns current committed/session layer state and exposes `CommittedLiveStateReadModel` for render snapshot publication. ## Why Phase 5 Exists @@ -116,7 +116,7 @@ This may be a small set of structs rather than a large class. The value is in na ### `CommittedLiveState` -Optional runtime/session collaborator if committed session state needs to move out of `RuntimeStore`. +Runtime/session collaborator for committed current-session state that has moved out of `RuntimeStore` physical ownership. Responsibilities: @@ -131,7 +131,7 @@ Non-responsibilities: - disk writes - GL resources -Phase 5 can defer this physical split if the policy is documented and covered by tests. The key is that committed-live state becomes a distinct concept even if it still lives inside existing storage temporarily. +Phase 5 now uses this physical split. `RuntimeStore` still wraps it for compatibility and persistence IO, but committed values no longer live directly as store fields. ### `AutomationOverlayState` @@ -309,26 +309,26 @@ Current policy: Decide whether to physically split committed-live state now or introduce a read/model boundary first. -Conservative option: +Earlier conservative option: -- [x] leave storage physically in `RuntimeStore` - [x] add a named committed-live read model - [x] keep persistence decisions in `RuntimeCoordinator` Stronger option: -- introduce `CommittedLiveState` -- make `RuntimeSnapshotProvider` consume committed live state through a read model -- leave durable writes in `RuntimeStore` +- [x] introduce `CommittedLiveState` +- [x] make `RuntimeSnapshotProvider` consume committed live state through a read model +- [x] leave durable writes in `RuntimeStore` Phase 5 does not need a flag-day split. It needs the concept to stop being implicit. Current implementation: +- `CommittedLiveState` physically owns the current committed/session layer stack. - `CommittedLiveStateReadModel` carries the current committed/session layer stack and shader package metadata used by snapshot publication. - `RenderSnapshotReadModel` contains `committedLiveState` rather than exposing layer-stack fields directly. - `RenderSnapshotBuilder` builds render snapshots and parameter refreshes from committed-live read APIs. -- `RuntimeStore` still provides the physical backing during this phase, but session-only committed changes can be observed through the committed-live read model without requiring durable persistence. +- `RuntimeStore` still owns config, package metadata, disk IO, preset files, and persistent-state serialization, but delegates current-session layer mutations to `CommittedLiveState`. ### Step 6. Update Docs And Exit Criteria diff --git a/docs/subsystems/RenderEngine.md b/docs/subsystems/RenderEngine.md index 8f5d468..b45fca7 100644 --- a/docs/subsystems/RenderEngine.md +++ b/docs/subsystems/RenderEngine.md @@ -113,7 +113,7 @@ Phase 5's `RuntimeStateLayerModel` explicitly keeps temporal history, feedback s `RuntimeLiveState` now owns transient automation invalidation for render-facing compatibility. It can clear overlays for a target layer/control key and prunes overlays that no longer resolve to the current layer and parameter definitions before applying them to a frame. This keeps shader reload, preset load, and layer removal behavior local to the live-state/composition boundary instead of scattering it through GL drawing code. -Render snapshots now flow through a named `CommittedLiveStateReadModel`, so render-facing committed state is distinct from durable storage even while both are physically backed by the same store during migration. +Render snapshots now flow through a named `CommittedLiveStateReadModel`, so render-facing committed state is distinct from durable storage and physically owned by `CommittedLiveState`. ### 5. Shader Build Application diff --git a/docs/subsystems/RuntimeCoordinator.md b/docs/subsystems/RuntimeCoordinator.md index fceea75..332d212 100644 --- a/docs/subsystems/RuntimeCoordinator.md +++ b/docs/subsystems/RuntimeCoordinator.md @@ -274,7 +274,7 @@ For OSC specifically, the coordinator should eventually decide: Phase 5 sets the default settled OSC policy to session-only. `CommitOscParameterByControlKey(...)` updates committed session state through the store with persistence disabled, publishes ordinary mutation/state-change observations, and does not request a persistence write unless a future explicit policy opts into durable OSC commits. -The committed-live concept now has a named read model, `CommittedLiveStateReadModel`. The coordinator remains the owner of whether a mutation should be durable or session-only, while `RuntimeStore` temporarily backs the read model until a physical `CommittedLiveState` collaborator is worth extracting. +The committed-live concept now has a physical owner, `CommittedLiveState`, plus a named read model, `CommittedLiveStateReadModel`. The coordinator remains the owner of whether a mutation should be durable or session-only, while `RuntimeStore` persists or skips disk writes according to that policy. ### Health and timing state diff --git a/docs/subsystems/RuntimeStore.md b/docs/subsystems/RuntimeStore.md index 994117d..5d1cc70 100644 --- a/docs/subsystems/RuntimeStore.md +++ b/docs/subsystems/RuntimeStore.md @@ -97,7 +97,7 @@ Those are coordinator concerns, not store concerns. Phase 5 names this boundary in code through `RuntimeStateLayerModel`: persisted layer stack data, saved parameter values, and stack presets are classified as base persisted state. Operator/session values may still be backed by the store during migration, but their mutation policy is committed-live policy owned by the coordinator, not durable-store policy by default. -Phase 5 also adds `CommittedLiveStateReadModel` as the named read boundary for current session/operator state. During the conservative migration, `RuntimeStore` still backs that model physically, but snapshot publication consumes the committed-live read model rather than treating render-facing state as raw durable storage. +Phase 5 also adds `CommittedLiveState` as the physical owner of current session/operator layer state and `CommittedLiveStateReadModel` as the named read boundary for render snapshot publication. `RuntimeStore` still owns file IO, config, package metadata, preset persistence, and persistence requests, but it delegates current-session layer mutations to `CommittedLiveState`. ### Runtime Configuration