Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Another approach for a generic event system #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Assets/Scenes/EventCallbackScene/DeathListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ public class DeathListener : MonoBehaviour
// Use this for initialization
void Start()
{
EventSystem.Current.RegisterListener<UnitDeathEventInfo>(OnUnitDied);
// subscribe fully generic to an event
EventSystem<UnitDeathEvent>.EventTriggered += OnUnitDied;
}

// Update is called once per frame
void Update()
{

}

void OnUnitDied(UnitDeathEventInfo unitDeathInfo)
void OnUnitDied(UnitDeathEvent unitDeathInfo)
{
Debug.Log("Alerted about unit death: " + unitDeathInfo.UnitGO.name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@

namespace EventCallbacks
{
public abstract class EventInfo
public abstract class Event
{
/*
* The base EventInfo,
* The base Event,
* might have some generic text
* for doing Debug.Log?
*/

public string EventDescription;
}

public class DebugEventInfo : EventInfo
public class DebugEvent : Event
{
public int VerbosityLevel;
}

public class UnitDeathEventInfo : EventInfo
public class UnitDeathEvent : Event
{
public GameObject UnitGO;
/*
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 1 addition & 41 deletions Assets/Scenes/EventCallbackScene/EventCallbackScene.unity
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
m_IndirectSpecularColor: {r: 0.44657826, g: 0.49641263, b: 0.57481676, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
Expand Down Expand Up @@ -332,43 +332,3 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
UnitPrefab: {fileID: 1366478792749392, guid: e7a5e0ba16dbdd34a9c802824f19afd8, type: 2}
--- !u!1 &1454433630
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1454433632}
- component: {fileID: 1454433631}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1454433631
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1454433630}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4cdea2b3fd5715644891661d21e98306, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1454433632
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1454433630}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
115 changes: 76 additions & 39 deletions Assets/Scenes/EventCallbackScene/EventSystem.cs
Original file line number Diff line number Diff line change
@@ -1,75 +1,112 @@
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace EventCallbacks
{
public class EventSystem : MonoBehaviour
public abstract class EventSystem
{
public abstract void CleanEventSystem();
}

// Use this for initialization
void OnEnable()
{
__Current = this;
}
/// <summary>
/// The actual generic eventsystem
/// </summary>
/// <typeparam name="T">The type of the event for this system</typeparam>
public class EventSystem<T> : EventSystem
{
static EventSystem<T> eventSystemInstance;
Action<T> eventDelegate;

static private EventSystem __Current;
static public EventSystem Current
public static event Action<T> EventTriggered
{
get
add
{
if(__Current == null)
if (EventSystemInstance.eventDelegate == null)
{
__Current = GameObject.FindObjectOfType<EventSystem>();
EventSystemManagement.RegisterNewEventSystem(EventSystemInstance);
}

return __Current;
EventSystemInstance.eventDelegate += value;
}
}

delegate void EventListener(EventInfo ei);
Dictionary<System.Type, List<EventListener>> eventListeners;
remove { EventSystemInstance.eventDelegate -= value; }
}

public void RegisterListener<T>(System.Action<T> listener) where T : EventInfo
public static void FireEvent(T eventData)
{
System.Type eventType = typeof(T);
if (eventListeners == null)
{
eventListeners = new Dictionary<System.Type, List<EventListener>>();
}
EventSystemInstance.FireEvent_(eventData);
}

if(eventListeners.ContainsKey(eventType) == false || eventListeners[eventType] == null)
static void CleanCurrentEventSystem()
{
if (eventSystemInstance != null)
{
eventListeners[eventType] = new List<EventListener>();
eventSystemInstance.CleanSubscribersList();
// we set our instance to null, so we can check whether we have to create a new instance next time
eventSystemInstance = null;
}
}

// Wrap a type converstion around the event listener
// I'm betting someone better at C# generic syntax
// can find a way around this.
EventListener wrapper = (ei) => { listener((T)ei); };
static EventSystem<T> EventSystemInstance
{
get { return eventSystemInstance ?? (eventSystemInstance = new EventSystem<T>()); }
}

eventListeners[eventType].Add(wrapper);
public override void CleanEventSystem()
{
// notice that we call a static method here
CleanCurrentEventSystem();
}

public void UnregisterListener<T>(System.Action<T> listener) where T : EventInfo
void CleanSubscribersList()
{
// TODO
eventDelegate = null;
}

public void FireEvent(EventInfo eventInfo)
void FireEvent_(T eventData)
{
System.Type trueEventInfoClass = eventInfo.GetType();
if (eventListeners == null || eventListeners[trueEventInfoClass] == null)
if (eventDelegate != null)
{
// No one is listening, we are done.
return;
eventDelegate(eventData);
}
}

EventSystem()
{
}
}

/// <summary>
/// a management class used to cleanup every used event system
/// </summary>
public static class EventSystemManagement
{
static readonly List<EventSystem> eventSystems = new List<EventSystem>();

foreach(EventListener el in eventListeners[trueEventInfoClass])
/// <summary>
/// Registers a new event system instance
/// </summary>
/// <param name="eventSystem">The event system instance to register</param>
public static void RegisterNewEventSystem(EventSystem eventSystem)
{
if (!eventSystems.Contains(eventSystem))
{
el( eventInfo );
eventSystems.Add(eventSystem);
}
}

/// <summary>
/// removes the listeners of all registered event system instances and
/// clears the list of registered event systems
/// </summary>
public static void CleanupEventSystem()
{
foreach (var eventSystem in eventSystems)
{
eventSystem.CleanEventSystem();
}

eventSystems.Clear();
}
}
}
11 changes: 5 additions & 6 deletions Assets/Scenes/EventCallbackScene/Health.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@ void Die()
{
// I am dying for some reason.

UnitDeathEventInfo udei = new UnitDeathEventInfo();
udei.EventDescription = "Unit "+ gameObject.name +" has died.";
udei.UnitGO = gameObject;
UnitDeathEvent ude = new UnitDeathEvent();
ude.EventDescription = "Unit "+ gameObject.name +" has died.";
ude.UnitGO = gameObject;

EventSystem.Current.FireEvent(
udei
);
// fire the event like so:
EventSystem<UnitDeathEvent>.FireEvent(ude);

Destroy(gameObject);
}
Expand Down
6 changes: 6 additions & 0 deletions Assets/Scenes/EventCallbackScene/Spawner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,11 @@ void SpawnUnit()
{
GameObject go = Instantiate(UnitPrefab);
}

void OnDestroy()
{
// TODO: cleanup the event systems
//EventSystemManagement.CleanupEventSystem();
}
}
}