# How TEngine Automatically Cleans Up Events When UI Is Destroyed

> Learn how TEngine automatically cleans up UI events when destroyed. TEngine's GameEventMgr efficiently removes delegates via OnDestroy for seamless memory management.

- Repository: [ALEX/tengine](https://github.com/alex-rachel/tengine)
- Tags: how-to-guide
- Published: 2026-02-24

---

**TEngine automatically removes UI event listeners by storing them in a `GameEventMgr` instance that clears all registered delegates when the `UIBase` class receives Unity's `OnDestroy` callback.**

The alex-rachel/tengine framework eliminates manual event unsubscription in Unity UI development through an automated lifecycle management system. By coupling each UI component with a dedicated `GameEventMgr` instance, TEngine ensures that **automatically clean up events when UI is destroyed** happens without developer intervention, preventing memory leaks and null reference exceptions.

## The Architecture Behind Automatic Event Cleanup

### GameEventMgr: The Central Registry

Located at [`UnityProject/Assets/TEngine/Runtime/Core/GameEvent/GameEventMgr.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/TEngine/Runtime/Core/GameEvent/GameEventMgr.cs), the `GameEventMgr` class implements `IMemory` and maintains two parallel collections to track registrations:

- `_listEventTypes`: A `List<int>` storing integer event identifiers
- `_listHandles`: A `List<Delegate>` storing the corresponding handler references

When `AddEvent()` is called, the method registers the listener with the global `GameEvent` dispatcher and records the pairing internally via `AddEventImp()`. This dual-tracking enables bulk cleanup later.

### UIBase: The Lifecycle Bridge

The `UIBase` class at [`UnityProject/Assets/TEngine/Runtime/Module/UILifecycle/UIBase.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/TEngine/Runtime/Module/UILifecycle/UIBase.cs) provides the critical link between Unity's destruction phase and TEngine's cleanup logic. Every UI component inherits a protected `_eventMgr` field initialized to `new GameEventMgr()`.

The base class overrides `OnDestroy()` to invoke `_eventMgr.Clear()`, ensuring that **automatically clean up events when UI is destroyed** occurs precisely when the GameObject is destroyed.

## Step-by-Step Cleanup Process

1. **Event Registration**: When a UI script calls `AddUIEvent(eventType, handler)`, the base class forwards this to `_eventMgr.AddEvent()`. This registers with `GameEvent.AddEventListener()` and stores the mapping in `_listEventTypes` and `_listHandles`.

2. **Destruction Trigger**: Unity calls `MonoBehaviour.OnDestroy()` when the UI GameObject is destroyed.

3. **Cleanup Invocation**: The `UIBase.OnDestroy()` override executes `_eventMgr.Clear()`.

4. **Listener Removal**: The `Clear()` method iterates through all stored pairs and unregisters them:
   ```csharp
   for (int i = 0; i < _listEventTypes.Count; ++i)
   {
       var eventType = _listEventTypes[i];
       var handle    = _listHandles[i];
       GameEvent.RemoveEventListener(eventType, handle);
   }
   ```

5. **Reference Release**: After unregistering from the global dispatcher, `_listEventTypes.Clear()` and `_listHandles.Clear()` remove all references, allowing the garbage collector to reclaim the UI object's memory.

## Practical Implementation Example

```csharp
using UnityEngine;
using System;

public class InventoryPanel : UIBase
{
    private const int UpdateInventoryEvent = 2001;

    private void Start()
    {
        // Register event - no manual cleanup needed
        AddUIEvent(UpdateInventoryEvent, RefreshInventory);
    }

    private void RefreshInventory()
    {
        Debug.Log("Refreshing inventory display");
    }

    // Cleanup happens automatically in UIBase.OnDestroy()
}

```

This pattern applies to any class inheriting from `UIBase`. The framework handles the entire lifecycle, allowing developers to focus on business logic rather than subscription management.

## Memory Safety Benefits

The **automatically clean up events when UI is destroyed** mechanism prevents two common Unity pitfalls:

- **Memory leaks**: Stale delegate references keep destroyed UI objects alive in the global `GameEvent` dispatcher
- **Null reference exceptions**: Callbacks firing on destroyed MonoBehaviours after scene transitions

By encapsulating the cleanup in `GameEventMgr.Clear()` and triggering it through `UIBase.OnDestroy()`, TEngine guarantees that no dangling callbacks remain when UI objects are destroyed.

## Summary

- TEngine stores UI event registrations in the `GameEventMgr` class located at [`UnityProject/Assets/TEngine/Runtime/Core/GameEvent/GameEventMgr.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/TEngine/Runtime/Core/GameEvent/GameEventMgr.cs)
- The `UIBase` class at [`UnityProject/Assets/TEngine/Runtime/Module/UILifecycle/UIBase.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/TEngine/Runtime/Module/UILifecycle/UIBase.cs) provides automatic cleanup by calling `_eventMgr.Clear()` in its `OnDestroy()` override
- `Clear()` iterates through `_listEventTypes` and `_listHandles` to call `GameEvent.RemoveEventListener()` for every registered delegate
- Developers using `UIBase` never need to manually unregister events; the framework handles cleanup when Unity destroys the GameObject
- This design prevents memory leaks and null reference exceptions by ensuring zero orphaned callbacks after UI destruction

## Frequently Asked Questions

### What triggers the automatic cleanup in TEngine?

Unity's `OnDestroy` lifecycle method triggers the cleanup. When a UI GameObject is destroyed, the `UIBase` class receives the `OnDestroy` callback and immediately invokes `_eventMgr.Clear()`, which removes all registered listeners from the global `GameEvent` dispatcher.

### Do I need to manually unregister events in TEngine UI classes?

No. When you inherit from `UIBase` and use `AddUIEvent()` or `_eventMgr.AddEvent()`, the framework automatically tracks all registrations. The `Clear()` method in [`GameEventMgr.cs`](https://github.com/alex-rachel/tengine/blob/main/GameEventMgr.cs) handles unregistration when the UI is destroyed, eliminating the need for manual cleanup code in your UI scripts.

### What happens if I don't use UIBase for my UI components?

Without inheriting from `UIBase`, you lose the automatic cleanup mechanism. You would need to manually manage a `GameEventMgr` instance and ensure you call `Clear()` during your component's destruction phase. The base class exists specifically to provide this lifecycle management automatically.

### Where is the cleanup logic located in the source code?

The cleanup implementation spans two critical files: [`UnityProject/Assets/TEngine/Runtime/Core/GameEvent/GameEventMgr.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/TEngine/Runtime/Core/GameEvent/GameEventMgr.cs) contains the `Clear()` method that iterates through `_listEventTypes` and `_listHandles` to call `GameEvent.RemoveEventListener()`, while [`UnityProject/Assets/TEngine/Runtime/Module/UILifecycle/UIBase.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/TEngine/Runtime/Module/UILifecycle/UIBase.cs) provides the `OnDestroy()` override that triggers this cleanup process.