pass 1
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
|
||||
#include "RuntimeStore.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
||||
RuntimeCoordinator::RuntimeCoordinator(RuntimeStore& runtimeStore) :
|
||||
mRuntimeStore(runtimeStore)
|
||||
{
|
||||
@@ -9,55 +12,110 @@ RuntimeCoordinator::RuntimeCoordinator(RuntimeStore& runtimeStore) :
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::AddLayer(const std::string& shaderId)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
if (!ValidateShaderExists(shaderId, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.CreateStoredLayer(shaderId, error), error, true, true);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::RemoveLayer(const std::string& layerId)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
if (!ValidateLayerExists(layerId, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.DeleteStoredLayer(layerId, error), error, true, true);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::MoveLayer(const std::string& layerId, int direction)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
bool shouldMove = false;
|
||||
if (!ResolveLayerMove(layerId, direction, shouldMove, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
if (!shouldMove)
|
||||
return BuildAcceptedNoReloadResult();
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.MoveStoredLayer(layerId, direction, error), error, true, true);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::MoveLayerToIndex(const std::string& layerId, std::size_t targetIndex)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
bool shouldMove = false;
|
||||
if (!ResolveLayerMoveToIndex(layerId, targetIndex, shouldMove, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
if (!shouldMove)
|
||||
return BuildAcceptedNoReloadResult();
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.MoveStoredLayerToIndex(layerId, targetIndex, error), error, true, true);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::SetLayerBypass(const std::string& layerId, bool bypassed)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
if (!ValidateLayerExists(layerId, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.SetStoredLayerBypassState(layerId, bypassed, error), error, true, false);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::SetLayerShader(const std::string& layerId, const std::string& shaderId)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
if (!ValidateLayerExists(layerId, error) || !ValidateShaderExists(shaderId, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.SetStoredLayerShaderSelection(layerId, shaderId, error), error, true, false);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::UpdateLayerParameter(const std::string& layerId, const std::string& parameterId, const JsonValue& newValue)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
return ApplyStoreMutation(mRuntimeStore.SetStoredParameterValue(layerId, parameterId, newValue, error), error, false, false);
|
||||
ResolvedParameterMutation mutation;
|
||||
if (!BuildParameterMutationById(layerId, parameterId, newValue, true, mutation, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.SetStoredParameterValue(mutation.layerId, mutation.parameterId, mutation.value, mutation.persistState, error), error, false, false);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::UpdateLayerParameterByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
return ApplyStoreMutation(mRuntimeStore.SetStoredParameterValueByControlKey(layerKey, parameterKey, newValue, error), error, false, false);
|
||||
ResolvedParameterMutation mutation;
|
||||
if (!BuildParameterMutationByControlKey(layerKey, parameterKey, newValue, true, mutation, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.SetStoredParameterValue(mutation.layerId, mutation.parameterId, mutation.value, mutation.persistState, error), error, false, false);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::CommitOscParameterByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
ResolvedParameterMutation mutation;
|
||||
if (!BuildParameterMutationByControlKey(layerKey, parameterKey, newValue, false, mutation, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.SetStoredParameterValue(mutation.layerId, mutation.parameterId, mutation.value, mutation.persistState, error), error, false, false);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::ResetLayerParameters(const std::string& layerId)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
if (!ValidateLayerExists(layerId, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
RuntimeCoordinatorResult result = ApplyStoreMutation(mRuntimeStore.ResetStoredLayerParameterValues(layerId, error), error, false, false);
|
||||
if (!result.accepted)
|
||||
return result;
|
||||
@@ -69,21 +127,51 @@ RuntimeCoordinatorResult RuntimeCoordinator::ResetLayerParameters(const std::str
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::SaveStackPreset(const std::string& presetName)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
if (!ValidatePresetName(presetName, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.SaveStackPresetSnapshot(presetName, error), error, false, false);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::LoadStackPreset(const std::string& presetName)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
std::string error;
|
||||
if (!ValidatePresetName(presetName, error))
|
||||
return ApplyStoreMutation(false, error, false, false);
|
||||
|
||||
return ApplyStoreMutation(mRuntimeStore.LoadStackPresetSnapshot(presetName, error), error, true, false);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::RequestShaderReload(bool preserveFeedbackState)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
return BuildQueuedReloadResult(preserveFeedbackState);
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::PollRuntimeStoreChanges(bool& registryChanged)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
|
||||
registryChanged = false;
|
||||
bool reloadRequested = false;
|
||||
std::string error;
|
||||
if (!mRuntimeStore.PollStoredFileChanges(registryChanged, reloadRequested, error))
|
||||
return HandleRuntimePollFailure(error);
|
||||
|
||||
if (reloadRequested)
|
||||
return BuildQueuedReloadResult(false);
|
||||
|
||||
if (registryChanged)
|
||||
return BuildAcceptedNoReloadResult();
|
||||
|
||||
RuntimeCoordinatorResult result;
|
||||
result.accepted = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::HandleRuntimePollFailure(const std::string& error)
|
||||
{
|
||||
RuntimeCoordinatorResult result;
|
||||
@@ -97,6 +185,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::HandleRuntimePollFailure(const std:
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::HandlePreparedShaderBuildFailure(const std::string& error)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
mPreserveFeedbackOnNextShaderBuild = false;
|
||||
mUseCommittedLayerStates = true;
|
||||
|
||||
@@ -112,6 +201,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::HandlePreparedShaderBuildFailure(co
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::HandlePreparedShaderBuildSuccess()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
mUseCommittedLayerStates = false;
|
||||
|
||||
RuntimeCoordinatorResult result;
|
||||
@@ -127,11 +217,13 @@ RuntimeCoordinatorResult RuntimeCoordinator::HandlePreparedShaderBuildSuccess()
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::HandleRuntimeReloadRequest()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
return BuildQueuedReloadResult(false);
|
||||
}
|
||||
|
||||
void RuntimeCoordinator::ApplyCommittedStateMode(RuntimeCoordinatorCommittedStateMode mode)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
switch (mode)
|
||||
{
|
||||
case RuntimeCoordinatorCommittedStateMode::UseCommittedStates:
|
||||
@@ -153,9 +245,158 @@ bool RuntimeCoordinator::UseCommittedLayerStates() const
|
||||
|
||||
bool RuntimeCoordinator::PreserveFeedbackOnNextShaderBuild() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
return mPreserveFeedbackOnNextShaderBuild;
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::BuildParameterMutationById(const std::string& layerId, const std::string& parameterId, const JsonValue& newValue,
|
||||
bool persistState, ResolvedParameterMutation& mutation, std::string& error) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeStore.mRuntimeHost.mMutex);
|
||||
|
||||
RuntimeHost::LayerPersistentState* layer = mRuntimeStore.mRuntimeHost.FindLayerById(layerId);
|
||||
if (!layer)
|
||||
{
|
||||
error = "Unknown layer id: " + layerId;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto shaderIt = mRuntimeStore.mRuntimeHost.mPackagesById.find(layer->shaderId);
|
||||
if (shaderIt == mRuntimeStore.mRuntimeHost.mPackagesById.end())
|
||||
{
|
||||
error = "Unknown shader id: " + layer->shaderId;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto parameterIt = std::find_if(shaderIt->second.parameters.begin(), shaderIt->second.parameters.end(),
|
||||
[¶meterId](const ShaderParameterDefinition& definition) { return definition.id == parameterId; });
|
||||
if (parameterIt == shaderIt->second.parameters.end())
|
||||
{
|
||||
error = "Unknown parameter id: " + parameterId;
|
||||
return false;
|
||||
}
|
||||
|
||||
return BuildParameterMutationLocked(*layer, *parameterIt, newValue, persistState, mutation, error);
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::BuildParameterMutationByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue,
|
||||
bool persistState, ResolvedParameterMutation& mutation, std::string& error) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeStore.mRuntimeHost.mMutex);
|
||||
|
||||
RuntimeHost::LayerPersistentState* matchedLayer = nullptr;
|
||||
const ShaderPackage* matchedPackage = nullptr;
|
||||
std::vector<ShaderParameterDefinition>::const_iterator parameterIt;
|
||||
if (!mRuntimeStore.TryResolveStoredLayerAndParameterByControlKeyLocked(layerKey, parameterKey, matchedLayer, matchedPackage, parameterIt, error))
|
||||
return false;
|
||||
|
||||
return BuildParameterMutationLocked(*matchedLayer, *parameterIt, newValue, persistState, mutation, error);
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::BuildParameterMutationLocked(RuntimeHost::LayerPersistentState& layer, const ShaderParameterDefinition& definition, const JsonValue& newValue,
|
||||
bool persistState, ResolvedParameterMutation& mutation, std::string& error) const
|
||||
{
|
||||
mutation.layerId = layer.id;
|
||||
mutation.parameterId = definition.id;
|
||||
mutation.persistState = persistState;
|
||||
|
||||
if (definition.type == ShaderParameterType::Trigger)
|
||||
{
|
||||
const auto existingValue = layer.parameterValues.find(definition.id);
|
||||
const double previousCount = existingValue == layer.parameterValues.end() || existingValue->second.numberValues.empty()
|
||||
? 0.0
|
||||
: existingValue->second.numberValues[0];
|
||||
const double triggerTime = std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
std::chrono::steady_clock::now() - mRuntimeStore.mRuntimeHost.mStartTime).count();
|
||||
mutation.value.numberValues = { previousCount + 1.0, triggerTime };
|
||||
mutation.persistState = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return mRuntimeStore.mRuntimeHost.NormalizeAndValidateValue(definition, newValue, mutation.value, error);
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::HasLayerLocked(const std::string& layerId) const
|
||||
{
|
||||
return mRuntimeStore.mRuntimeHost.FindLayerById(layerId) != nullptr;
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::HasShaderLocked(const std::string& shaderId) const
|
||||
{
|
||||
return mRuntimeStore.mRuntimeHost.mPackagesById.find(shaderId) != mRuntimeStore.mRuntimeHost.mPackagesById.end();
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::ValidateLayerExists(const std::string& layerId, std::string& error) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeStore.mRuntimeHost.mMutex);
|
||||
if (HasLayerLocked(layerId))
|
||||
return true;
|
||||
|
||||
error = "Unknown layer id: " + layerId;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::ValidateShaderExists(const std::string& shaderId, std::string& error) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeStore.mRuntimeHost.mMutex);
|
||||
if (HasShaderLocked(shaderId))
|
||||
return true;
|
||||
|
||||
error = "Unknown shader id: " + shaderId;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::ResolveLayerMove(const std::string& layerId, int direction, bool& shouldMove, std::string& error) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeStore.mRuntimeHost.mMutex);
|
||||
const auto& layers = mRuntimeStore.mRuntimeHost.mPersistentState.layers;
|
||||
auto it = std::find_if(layers.begin(), layers.end(),
|
||||
[&layerId](const RuntimeHost::LayerPersistentState& layer) { return layer.id == layerId; });
|
||||
if (it == layers.end())
|
||||
{
|
||||
error = "Unknown layer id: " + layerId;
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::ptrdiff_t index = std::distance(layers.begin(), it);
|
||||
const std::ptrdiff_t newIndex = index + direction;
|
||||
shouldMove = newIndex >= 0 && newIndex < static_cast<std::ptrdiff_t>(layers.size()) && newIndex != index;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::ResolveLayerMoveToIndex(const std::string& layerId, std::size_t targetIndex, bool& shouldMove, std::string& error) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeStore.mRuntimeHost.mMutex);
|
||||
const auto& layers = mRuntimeStore.mRuntimeHost.mPersistentState.layers;
|
||||
auto it = std::find_if(layers.begin(), layers.end(),
|
||||
[&layerId](const RuntimeHost::LayerPersistentState& layer) { return layer.id == layerId; });
|
||||
if (it == layers.end())
|
||||
{
|
||||
error = "Unknown layer id: " + layerId;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (layers.empty())
|
||||
{
|
||||
shouldMove = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::size_t clampedTargetIndex = (std::min)(targetIndex, layers.size() - 1);
|
||||
const std::size_t sourceIndex = static_cast<std::size_t>(std::distance(layers.begin(), it));
|
||||
shouldMove = sourceIndex != clampedTargetIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RuntimeCoordinator::ValidatePresetName(const std::string& presetName, std::string& error) const
|
||||
{
|
||||
if (!mRuntimeStore.MakeSafePresetFileStem(presetName).empty())
|
||||
return true;
|
||||
|
||||
error = "Preset name must include at least one letter or number.";
|
||||
return false;
|
||||
}
|
||||
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::ApplyStoreMutation(bool succeeded, const std::string& errorMessage, bool reloadRequired, bool preserveFeedbackState)
|
||||
{
|
||||
if (!succeeded)
|
||||
|
||||
Reference in New Issue
Block a user