Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
EditorAutosaveManager.h
Go to the documentation of this file.
1/*
2 * Olympe Engine - EditorAutosaveManager
3 *
4 * Lightweight helper that persists node positions asynchronously.
5 * Two save triggers are combined:
6 * 1. Debounced immediate save: when ScheduleSave() is called, a debounce
7 * timer is (re)started. Once the timer expires the save runs on a
8 * background thread so the UI is never blocked.
9 * 2. Periodic flush: every m_periodicIntervalSec seconds a background save
10 * is forced regardless of the debounce state.
11 *
12 * Per-save lambda usage (preferred – serialization on UI thread):
13 * // Construction (once, no legacy saveFn needed):
14 * EditorAutosaveManager autosave;
15 * autosave.Init(nullptr, 1.5f, 60.0f);
16 *
17 * // Each frame:
18 * autosave.Tick(ImGui::GetTime());
19 *
20 * // When a node moves, supply a serializer + path:
21 * autosave.ScheduleSave(ImGui::GetTime(),
22 * [this]{ return SerializeToString(); },
23 * "path/to/file.json");
24 *
25 * // On shutdown:
26 * autosave.Flush(); // waits for any pending async task
27 *
28 * Legacy usage (saveFn runs entirely on background thread):
29 * autosave.Init([this]{ DoSave(); }, 1.5f, 60.0f);
30 * autosave.ScheduleSave(ImGui::GetTime());
31 */
32
33#pragma once
34
35#include <functional>
36#include <future>
37#include <string>
38
39namespace Olympe
40{
41
43{
44public:
47
48 /**
49 * @brief Set the timing parameters and an optional legacy save callback.
50 * @param saveFn Legacy callable executed on a background thread.
51 * Pass nullptr when using the per-save lambda overload.
52 * @param debounceSec Seconds to wait after the last ScheduleSave() before saving.
53 * @param periodicIntervalSec Maximum seconds between forced flushes (0 = disabled).
54 */
55 void Init(std::function<void()> saveFn,
56 float debounceSec = 1.5f,
57 float periodicIntervalSec = 60.0f);
58
59 /**
60 * @brief Notify the manager that a change occurred (legacy overload).
61 * Resets the debounce timer; uses the saveFn supplied to Init().
62 * @param nowSec Current time in seconds (e.g. ImGui::GetTime()).
63 */
64 void ScheduleSave(double nowSec);
65
66 /**
67 * @brief Notify the manager that a change occurred (per-save lambda overload).
68 * Serialization runs on the calling (UI) thread inside Tick() just
69 * before the background write is launched.
70 *
71 * @param nowSec Current time in seconds (e.g. ImGui::GetTime()).
72 * @param serializeFn Called on the UI thread to produce the data to write.
73 * Return an empty string to skip writing.
74 * @param filePath Destination path. If empty, the fallback path is used.
75 * @param fallbackPrefix Prefix for the fallback filename when filePath is empty.
76 * A monotonically-increasing counter is appended.
77 * Defaults to "GameData/AI/autosave_".
78 */
79 void ScheduleSave(double nowSec,
80 std::function<std::string()> serializeFn,
81 std::string filePath,
82 std::string fallbackPrefix = "GameData/AI/autosave_");
83
84 /**
85 * @brief Must be called once per frame to advance timers and launch saves.
86 * Must be called on the UI thread so that the per-save serializer
87 * runs on the correct thread.
88 * @param nowSec Current time in seconds (e.g. ImGui::GetTime()).
89 */
90 void Tick(double nowSec);
91
92 /**
93 * @brief Block until any running async save finishes.
94 * Call from Shutdown() or destructor.
95 */
96 void Flush();
97
98private:
99 void LaunchAsync();
100 void LaunchAsyncWrite(std::string data, std::string path);
101
102 // Legacy path
103 std::function<void()> m_saveFn;
104
105 // Per-save lambda path
106 std::function<std::string()> m_pendingSerializeFn;
107 std::string m_pendingFilePath;
110
111 float m_debounceSec = 1.5f;
113
114 double m_debounceDeadline = -1.0; // time at which the debounce save fires
115 double m_lastSaveTime = -1.0; // last time a save was launched
116
117 bool m_dirty = false; // a ScheduleSave() arrived since last save
118
119 std::future<void> m_future; // running async task (if any)
120};
121
122} // namespace Olympe
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
void Init(std::function< void()> saveFn, float debounceSec=1.5f, float periodicIntervalSec=60.0f)
Set the timing parameters and an optional legacy save callback.
void Flush()
Block until any running async save finishes.
void LaunchAsyncWrite(std::string data, std::string path)
void ScheduleSave(double nowSec)
Notify the manager that a change occurred (legacy overload).
std::function< std::string()> m_pendingSerializeFn
void Tick(double nowSec)
Must be called once per frame to advance timers and launch saves.
< Provides AssetID and INVALID_ASSET_ID