Cleanup branch work

This commit is contained in:
Michal Pikulski
2025-11-04 11:47:09 +01:00
parent c57e3aa7e0
commit 379a033d6b
8 changed files with 588 additions and 1877 deletions

View File

@@ -51,12 +51,9 @@ namespace Bootstrap
// Subscribe to loading screen completion event
initialLoadingScreen.OnLoadingScreenFullyHidden += OnInitialLoadingComplete;
RegisterManagedEvent(initialLoadingScreen, nameof(initialLoadingScreen.OnLoadingScreenFullyHidden),
(Action)OnInitialLoadingComplete);
// Subscribe to boot progress for real-time updates during bootstrap
CustomBoot.OnBootProgressChanged += OnBootProgressChanged;
// Note: Static events need manual cleanup in OnDestroy
_logVerbosity = DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>().bootstrapLogVerbosity;
@@ -83,10 +80,14 @@ namespace Bootstrap
protected override void OnDestroy()
{
// Manual cleanup for static event (RegisterManagedEvent doesn't handle static events properly)
CustomBoot.OnBootProgressChanged -= OnBootProgressChanged;
base.OnDestroy();
base.OnDestroy(); // Handles other managed event cleanup
// Manual cleanup for events
if (initialLoadingScreen != null)
{
initialLoadingScreen.OnLoadingScreenFullyHidden -= OnInitialLoadingComplete;
}
CustomBoot.OnBootProgressChanged -= OnBootProgressChanged;
}
/// <summary>

View File

@@ -73,7 +73,6 @@ namespace Core.Lifecycle
#region Private Fields
private ManagedEventManager _eventManager;
private bool _isRegistered;
#endregion
@@ -86,8 +85,6 @@ namespace Core.Lifecycle
/// </summary>
protected virtual void Awake()
{
_eventManager = new ManagedEventManager();
if (LifecycleManager.Instance != null)
{
LifecycleManager.Instance.Register(this);
@@ -114,9 +111,6 @@ namespace Core.Lifecycle
LifecycleManager.Instance.Unregister(this);
}
// Auto-cleanup managed events
_eventManager?.UnregisterAllEvents();
// Auto-unregister from GameManager if auto-registered
if (AutoRegisterPausable && this is AppleHills.Core.Interfaces.IPausable pausable)
@@ -197,28 +191,6 @@ namespace Core.Lifecycle
}
#endregion
#region Helper Methods
/// <summary>
/// Register an event subscription for automatic cleanup on destroy.
/// Prevents memory leaks by ensuring the event is unsubscribed when this component is destroyed.
/// </summary>
/// <param name="target">The object that owns the event</param>
/// <param name="eventName">Name of the event (e.g., "SceneLoadCompleted")</param>
/// <param name="handler">The delegate/handler for the event</param>
protected void RegisterManagedEvent(object target, string eventName, Delegate handler)
{
if (_eventManager == null)
{
Debug.LogWarning($"[ManagedBehaviour] Event manager not initialized for {gameObject.name}");
return;
}
_eventManager.RegisterEvent(target, eventName, handler);
}
#endregion
}
}

View File

@@ -1,102 +0,0 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace Core.Lifecycle
{
/// <summary>
/// Stores information about a single event subscription for automatic cleanup.
/// </summary>
internal class EventSubscriptionInfo
{
public object Target { get; set; }
public Delegate Handler { get; set; }
public string EventName { get; set; }
}
/// <summary>
/// Manages event subscriptions for a ManagedBehaviour with automatic cleanup on destroy.
/// Prevents memory leaks by ensuring all event subscriptions are properly unsubscribed.
/// </summary>
public class ManagedEventManager
{
private readonly List<EventSubscriptionInfo> _subscriptions = new List<EventSubscriptionInfo>();
/// <summary>
/// Register an event subscription for automatic cleanup.
/// </summary>
/// <param name="target">The object that owns the event</param>
/// <param name="eventName">Name of the event (e.g., "OnSomethingHappened")</param>
/// <param name="handler">The delegate/handler for the event</param>
public void RegisterEvent(object target, string eventName, Delegate handler)
{
if (target == null)
{
Debug.LogWarning("[ManagedEventManager] Cannot register event on null target");
return;
}
if (string.IsNullOrEmpty(eventName))
{
Debug.LogWarning("[ManagedEventManager] Event name cannot be null or empty");
return;
}
if (handler == null)
{
Debug.LogWarning("[ManagedEventManager] Handler cannot be null");
return;
}
_subscriptions.Add(new EventSubscriptionInfo
{
Target = target,
EventName = eventName,
Handler = handler
});
}
/// <summary>
/// Unregister all event subscriptions. Called automatically on ManagedBehaviour destruction.
/// </summary>
public void UnregisterAllEvents()
{
foreach (var subscription in _subscriptions)
{
try
{
if (subscription.Target == null)
continue;
// Use reflection to get the event and unsubscribe
var eventInfo = subscription.Target.GetType().GetEvent(
subscription.EventName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static
);
if (eventInfo != null)
{
eventInfo.RemoveEventHandler(subscription.Target, subscription.Handler);
}
else
{
Debug.LogWarning($"[ManagedEventManager] Could not find event '{subscription.EventName}' on type '{subscription.Target.GetType().Name}'");
}
}
catch (Exception ex)
{
Debug.LogError($"[ManagedEventManager] Error unsubscribing from event '{subscription.EventName}': {ex.Message}");
}
}
_subscriptions.Clear();
}
/// <summary>
/// Get the count of registered event subscriptions (for debugging).
/// </summary>
public int SubscriptionCount => _subscriptions.Count;
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 63e107279fdbf1542a9d93d57e60285c

View File

@@ -129,15 +129,13 @@ namespace Minigames.DivingForPictures
protected override void OnSceneReady()
{
InitializeGame();
CinematicsManager.Instance.OnCinematicStopped += EndGame;
}
private void Start()
{
// Subscribe to player damage events (this doesn't depend on initialization)
PlayerCollisionBehavior.OnDamageTaken += OnPlayerDamageTaken;
// Validate rope references (this doesn't depend on initialization)
// Subscribe to scene-specific events
CinematicsManager.Instance.OnCinematicStopped += EndGame;
PlayerCollisionBehavior.OnDamageTaken += OnPlayerDamageTaken;
OnMonsterSpawned += DoMonsterSpawned;
// Validate rope references
ValidateRopeReferences();
viewfinderManager = CameraViewfinderManager.Instance;
@@ -158,8 +156,6 @@ namespace Minigames.DivingForPictures
RegisterExemptFromPhotoSequencePausing(viewfinderPausable);
}
}
OnMonsterSpawned += DoMonsterSpawned;
}
protected override void OnDestroy()
@@ -168,7 +164,12 @@ namespace Minigames.DivingForPictures
// Unsubscribe from events when the manager is destroyed
PlayerCollisionBehavior.OnDamageTaken -= OnPlayerDamageTaken;
OnMonsterSpawned -= DoMonsterSpawned;
if (CinematicsManager.Instance != null)
{
CinematicsManager.Instance.OnCinematicStopped -= EndGame;
}
// Unregister all pausable components
_pausableComponents.Clear();