step 2
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m41s
CI / Windows Release Package (push) Successful in 2m46s

This commit is contained in:
Aiden
2026-05-11 19:49:05 +10:00
parent 68503256dc
commit ab38bfad24
7 changed files with 113 additions and 43 deletions

View File

@@ -0,0 +1,44 @@
#include "PersistenceWriter.h"
#include <windows.h>
#include <filesystem>
#include <fstream>
bool PersistenceWriter::WriteSnapshot(const PersistenceSnapshot& snapshot, std::string& error) const
{
if (snapshot.targetPath.empty())
{
error = "Persistence snapshot target path is empty.";
return false;
}
std::error_code fsError;
std::filesystem::create_directories(snapshot.targetPath.parent_path(), fsError);
const std::filesystem::path temporaryPath = snapshot.targetPath.string() + ".tmp";
std::ofstream output(temporaryPath, std::ios::binary | std::ios::trunc);
if (!output)
{
error = "Could not write file: " + temporaryPath.string();
return false;
}
output << snapshot.contents;
output.close();
if (!output.good())
{
error = "Could not finish writing file: " + temporaryPath.string();
return false;
}
if (!MoveFileExA(temporaryPath.string().c_str(), snapshot.targetPath.string().c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
{
const DWORD lastError = GetLastError();
std::filesystem::remove(temporaryPath, fsError);
error = "Could not replace file: " + snapshot.targetPath.string() + " (Win32 error " + std::to_string(lastError) + ")";
return false;
}
return true;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "PersistenceRequest.h"
#include <string>
class PersistenceWriter
{
public:
bool WriteSnapshot(const PersistenceSnapshot& snapshot, std::string& error) const;
};

View File

@@ -7,7 +7,6 @@
#include <mutex>
#include <random>
#include <sstream>
#include <windows.h>
namespace
{
@@ -99,6 +98,23 @@ std::string RuntimeStore::BuildPersistentStateJson() const
return RuntimeStatePresenter::BuildRuntimeStateJson(*this);
}
PersistenceSnapshot RuntimeStore::BuildRuntimeStatePersistenceSnapshot(const PersistenceRequest& request) const
{
std::lock_guard<std::mutex> lock(mMutex);
return BuildRuntimeStatePersistenceSnapshotLocked(request);
}
PersistenceSnapshot RuntimeStore::BuildRuntimeStatePersistenceSnapshotLocked(const PersistenceRequest& request) const
{
PersistenceSnapshot snapshot;
snapshot.targetKind = PersistenceTargetKind::RuntimeState;
snapshot.targetPath = mConfigStore.GetRuntimeStatePath();
snapshot.contents = SerializeJson(mCommittedLiveState.BuildPersistentStateValue(mShaderCatalog), true);
snapshot.reason = request.reason;
snapshot.generation = request.sequence;
return snapshot;
}
bool RuntimeStore::PollStoredFileChanges(bool& registryChanged, bool& reloadRequested, std::string& error)
{
try
@@ -270,10 +286,7 @@ bool RuntimeStore::SaveStackPresetSnapshot(const std::string& presetName, std::s
return false;
}
JsonValue root = JsonValue::MakeObject();
root = mCommittedLiveState.BuildStackPresetValue(mShaderCatalog, presetName);
return WriteTextFile(mConfigStore.GetPresetRoot() / (safeStem + ".json"), SerializeJson(root, true), error);
return mPersistenceWriter.WriteSnapshot(BuildStackPresetPersistenceSnapshot(presetName), error);
}
bool RuntimeStore::LoadStackPresetSnapshot(const std::string& presetName, std::string& error)
@@ -465,7 +478,20 @@ bool RuntimeStore::LoadPersistentState(std::string& error)
bool RuntimeStore::SavePersistentState(std::string& error) const
{
return WriteTextFile(mConfigStore.GetRuntimeStatePath(), SerializeJson(mCommittedLiveState.BuildPersistentStateValue(mShaderCatalog), true), error);
return mPersistenceWriter.WriteSnapshot(BuildRuntimeStatePersistenceSnapshotLocked(PersistenceRequest::RuntimeStateRequest("SavePersistentState")), error);
}
PersistenceSnapshot RuntimeStore::BuildStackPresetPersistenceSnapshot(const std::string& presetName) const
{
const std::string safeStem = LayerStackStore::MakeSafePresetFileStem(presetName);
PersistenceSnapshot snapshot;
snapshot.targetKind = PersistenceTargetKind::StackPreset;
snapshot.targetPath = mConfigStore.GetPresetRoot() / (safeStem + ".json");
snapshot.contents = SerializeJson(mCommittedLiveState.BuildStackPresetValue(mShaderCatalog, presetName), true);
snapshot.reason = "SaveStackPreset";
snapshot.generation = 0;
return snapshot;
}
bool RuntimeStore::ScanShaderPackages(std::string& error)
@@ -493,38 +519,6 @@ std::string RuntimeStore::ReadTextFile(const std::filesystem::path& path, std::s
return buffer.str();
}
bool RuntimeStore::WriteTextFile(const std::filesystem::path& path, const std::string& contents, std::string& error) const
{
std::error_code fsError;
std::filesystem::create_directories(path.parent_path(), fsError);
const std::filesystem::path temporaryPath = path.string() + ".tmp";
std::ofstream output(temporaryPath, std::ios::binary | std::ios::trunc);
if (!output)
{
error = "Could not write file: " + temporaryPath.string();
return false;
}
output << contents;
output.close();
if (!output.good())
{
error = "Could not finish writing file: " + temporaryPath.string();
return false;
}
if (!MoveFileExA(temporaryPath.string().c_str(), path.string().c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
{
const DWORD lastError = GetLastError();
std::filesystem::remove(temporaryPath, fsError);
error = "Could not replace file: " + path.string() + " (Win32 error " + std::to_string(lastError) + ")";
return false;
}
return true;
}
std::vector<std::string> RuntimeStore::GetStackPresetNamesLocked() const
{
std::vector<std::string> presetNames;

View File

@@ -3,6 +3,7 @@
#include "HealthTelemetry.h"
#include "CommittedLiveState.h"
#include "LayerStackStore.h"
#include "PersistenceWriter.h"
#include "RenderSnapshotBuilder.h"
#include "RuntimeConfigStore.h"
#include "RuntimeJson.h"
@@ -30,6 +31,7 @@ public:
bool InitializeStore(std::string& error);
std::string BuildPersistentStateJson() const;
PersistenceSnapshot BuildRuntimeStatePersistenceSnapshot(const PersistenceRequest& request) const;
bool PollStoredFileChanges(bool& registryChanged, bool& reloadRequested, std::string& error);
bool CreateStoredLayer(const std::string& shaderId, std::string& error);
@@ -82,14 +84,16 @@ public:
private:
bool LoadPersistentState(std::string& error);
bool SavePersistentState(std::string& error) const;
PersistenceSnapshot BuildRuntimeStatePersistenceSnapshotLocked(const PersistenceRequest& request) const;
PersistenceSnapshot BuildStackPresetPersistenceSnapshot(const std::string& presetName) const;
bool ScanShaderPackages(std::string& error);
std::string ReadTextFile(const std::filesystem::path& path, std::string& error) const;
bool WriteTextFile(const std::filesystem::path& path, const std::string& contents, std::string& error) const;
std::vector<std::string> GetStackPresetNamesLocked() const;
void MarkRenderStateDirtyLocked();
void MarkParameterStateDirtyLocked();
RenderSnapshotBuilder mRenderSnapshotBuilder;
PersistenceWriter mPersistenceWriter;
RuntimeConfigStore mConfigStore;
ShaderPackageCatalog mShaderCatalog;
CommittedLiveState mCommittedLiveState;