Skip to content

Commit 21fd275

Browse files
committed
feat: Add memory management options for scene transitions
- Add optimizeMemoryOnSceneUnload flag to control memory optimization on scene unload - Add clearOnSceneUnload flag to optionally clear event queue during scene transitions - Improve Clear() method to properly dispose events and reset internal state - Fix Schedule<T> method to avoid redundant event creation in configure overload
1 parent fd8b547 commit 21fd275

File tree

2 files changed

+117
-10
lines changed

2 files changed

+117
-10
lines changed

Assets/UnityEventTimeline/Runtime/EventTimeline.cs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,28 @@ public class EventTimeline : EventTimelineQueue
4747
/// </remarks>
4848
private static readonly object SingletonLock = new();
4949

50+
/// <summary>
51+
/// Determines whether memory optimizations are performed when a scene is unloaded.
52+
/// </summary>
53+
/// <remarks>
54+
/// If enabled, memory resources are optimized after a scene unload, potentially reducing memory usage
55+
/// by clearing or recycling unused objects. This setting complements the system's ability to manage
56+
/// resources and maintain performance stability during scene transitions.
57+
/// </remarks>
58+
[SerializeField]
59+
private bool optimizeMemoryOnSceneUnload = true;
60+
61+
/// <summary>
62+
/// Determines whether the event queue should be cleared automatically when a scene is unloaded.
63+
/// </summary>
64+
/// <remarks>
65+
/// When enabled, this setting ensures that all scheduled events are removed from the queue during a scene unload process,
66+
/// preventing potential memory leaks or unintended execution of events from the previous scene.
67+
/// This is particularly useful in scenarios where scene transitions are frequent or where event lifespan is tied to specific scenes.
68+
/// </remarks>
69+
[SerializeField]
70+
private bool clearOnSceneUnload;
71+
5072
/// <summary>
5173
/// Gets the singleton instance of the EventTimeline.
5274
/// </summary>
@@ -91,6 +113,30 @@ private EventTimeline()
91113
{
92114
}
93115

116+
/// <summary>
117+
/// Configures the memory optimization behavior during scene unloads.
118+
/// </summary>
119+
/// <param name="optimize">
120+
/// Determines whether to enable or disable memory optimizations when unloading a scene.
121+
/// If set to true, memory optimization actions are performed to reduce resource usage.
122+
/// </param>
123+
public void SetOptimizeMemoryOnSceneUnload(bool optimize)
124+
{
125+
optimizeMemoryOnSceneUnload = optimize;
126+
}
127+
128+
/// <summary>
129+
/// Sets whether the event timeline should automatically clear events when the scene is unloaded.
130+
/// </summary>
131+
/// <param name="clear">
132+
/// A boolean indicating if events should be cleared on scene unload.
133+
/// If true, events will be cleared; otherwise, they will persist through scene changes.
134+
/// </param>
135+
public void SetClearOnSceneUnload(bool clear)
136+
{
137+
clearOnSceneUnload = clear;
138+
}
139+
94140
/// <summary>
95141
/// Unity Awake callback that handles singleton instance setup.
96142
/// </summary>
@@ -183,11 +229,23 @@ private void HandleSceneUnloaded(Scene scene)
183229
AsyncLogger.LogFormat("[EventTimeline] Scene unloaded: {0}", scene.name);
184230
#endif
185231

186-
OptimizeMemory();
232+
if (optimizeMemoryOnSceneUnload)
233+
{
234+
OptimizeMemory();
235+
236+
#if __EVENTTIMELINE_DEBUG_VERBOSE
237+
AsyncLogger.Log("[EventTimeline] Memory optimization completed after scene unload");
238+
#endif
239+
}
240+
241+
if (clearOnSceneUnload)
242+
{
243+
Clear();
187244

188245
#if __EVENTTIMELINE_DEBUG_VERBOSE
189-
AsyncLogger.Log("[EventTimeline] Memory optimization completed after scene unload");
246+
AsyncLogger.Log("[EventTimeline] Queue cleared successfully after scene unload");
190247
#endif
248+
}
191249
}
192250
}
193251
}

Assets/UnityEventTimeline/Runtime/Internal/EventTimelineQueue.cs

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,35 @@ public class EventTimelineQueue : EventTimelinePoolsManager
161161
/// </remarks>
162162
public T Schedule<T>(Action<T> configure, float delay = 0) where T : TimelineEvent<T>, new()
163163
{
164-
var evt = Schedule<T>(delay);
164+
#if __EVENTTIMELINE_DEBUG_VERBOSE
165+
AsyncLogger.LogFormat("[EventTimelineQueue] Scheduling event of type {0} with delay {1}s", typeof(T).Name, delay);
166+
#endif
167+
168+
var evt = GetFromPool<T>();
169+
165170
configure.Invoke(evt);
171+
172+
if (IsMainThread)
173+
{
174+
evt.ScheduledTime = Time.time + delay / timeScale;
175+
}
176+
else
177+
{
178+
RunOnMainThread(() => evt.ScheduledTime = Time.time + delay / timeScale);
179+
180+
#if __EVENTTIMELINE_DEBUG
181+
AsyncLogger.LogWarningFormat("[EventTimelineQueue] Background event schedule detected. Posting {0} to main thread.", typeof(T));
182+
#endif
183+
}
184+
185+
evt.IsCancelled = false;
186+
187+
_eventQueue.Enqueue(evt);
188+
189+
#if __EVENTTIMELINE_DEBUG_VERBOSE
190+
AsyncLogger.LogFormat("[EventTimelineQueue] Successfully scheduled event of type {0} for time {1:F3}s", typeof(T).Name, evt.ScheduledTime);
191+
#endif
192+
166193
return evt;
167194
}
168195

@@ -214,35 +241,57 @@ public Result<T> Reschedule<T>(T evt, float delay) where T : TimelineEvent
214241
}
215242

216243
/// <summary>
217-
/// Clears all scheduled events and event pools.
244+
/// Clears all scheduled events, disposes them properly, and cleans up all event pools.
218245
/// </summary>
219246
/// <remarks>
220-
/// Thread-safe operation protected by a lock.
221-
/// Trims excess capacity from event pools after clearing.
247+
/// This operation is thread-safe and performs complete cleanup by:
248+
/// <list type="bullet">
249+
/// <item>Removing and disposing all events from the main queue</item>
250+
/// <item>Processing any cancelled events awaiting cleanup</item>
251+
/// <item>Clearing and disposing all pooled events</item>
252+
/// <item>Resetting internal state</item>
253+
/// </list>
222254
/// </remarks>
223255
public void Clear()
224256
{
225257
#if __EVENTTIMELINE_DEBUG_VERBOSE
226-
AsyncLogger.LogFormat("[EventTimelineQueue] Clearing all events. Current queue size: {0}", _eventQueue.Count);
258+
AsyncLogger.LogFormat("[EventTimelineQueue] Beginning full queue cleanup. Current queue size: {0}", _eventQueue.Count);
227259
#endif
228260

261+
// Process all events in the main queue
262+
var remainingEvents = _eventQueue.DequeueRange(_eventQueue.Count);
263+
foreach (var evt in remainingEvents)
264+
{
265+
evt.Dispose();
266+
}
267+
229268
_eventQueue.Clear();
230269

231270
lock (_cancelledEventsLock)
232271
{
233-
// Return cancelled events to pool before clearing
272+
// Process any pending cancelled events
234273
foreach (var evt in _cancelledEvents)
235274
{
236-
ReturnToPool(evt);
275+
evt.Dispose();
237276
}
238277

239278
_cancelledEvents.Clear();
240279
}
241280

281+
// Clear all event pools and reset counters
242282
ClearEventPools();
283+
_framesSinceCleanup = 0;
284+
285+
// Clear temporary storage
286+
foreach (var evt in _futureEvents)
287+
{
288+
evt.Dispose();
289+
}
290+
291+
_futureEvents.Clear();
243292

244293
#if __EVENTTIMELINE_DEBUG_VERBOSE
245-
AsyncLogger.Log("[EventTimelineQueue] Successfully cleared all events and pools");
294+
AsyncLogger.Log("[EventTimelineQueue] Queue cleanup completed successfully");
246295
#endif
247296
}
248297

0 commit comments

Comments
 (0)