Skip to content

Instantly share code, notes, and snippets.

@n0f3
Created September 20, 2013 00:28
Show Gist options
  • Save n0f3/6631787 to your computer and use it in GitHub Desktop.
Save n0f3/6631787 to your computer and use it in GitHub Desktop.
Simple event system to queue and process prioritized events.
using System;
using System.Collections;
using System.Collections.Generic;
public class SidebarController : MonoBehaviour {
private SidebarEventController.GenericSidebarEventArgs currEventProcessed;
private SidebarEventController.SidebarEventID currEventID;
//Determines whether or not a specific sidebar is in view and available to
//process events.
private bool bIsSidebarViewReady;
public bool SidebarViewReady {
get { return bIsSidebarViewReady; }
set {
bIsSidebarViewReady = value;
if(bIsSidebarViewReady) {
if(CurrSidebarState != SidebarControllerStates.PROCESSING_EVENT) {
CurrSidebarState = SidebarControllerStates.WAITING_EVENT;
}
}
}
}
//Whether or not there is currently a transition in the siebar.
public bool IsAnimating { get; set; }
//Prioritized list of event queues. Sorted by ascending order based on the Event ID.
SortedList<SidebarEventController.SidebarEventID, Queue<SidebarEventController.GenericSidebarEventArgs>> sidebarEvents;
public enum SidebarControllerStates {
WAITING_EVENT,
PROCESSING_EVENT,
BLOCKED_EVENT,
MAX_CONTROLLER_STATE
}
private SidebarControllerStates mCurrSidebarState;
public SidebarControllerStates CurrSidebarState {
set { mCurrSidebarState = value; EnterState(mCurrSidebarState); }
get { return mCurrSidebarState; }
}
public override void Awake() {
sidebarEvents = new SortedList<SidebarEventController.SidebarEventID, Queue<SidebarEventController.GenericSidebarEventArgs>>();
SidebarViewReady = false;
IsReady = true;
currEventProcessed = null;
//Sets up event listeners related to sidebar
SidebarEventController.MissionEvent += GenericEventHandler;
SidebarEventController.SidebarAnimEvent += GenericEventHandler;
SidebarEventController.SidebarGenericEvent += GenericEventHandler;
}
/// <summary>
/// Takes care of going through the sorted list of events. If there's any event to be processed,
/// it gets retrieved from the Queue and calls ProcessEvent() on it. Checks against current state of the sidebar
/// to avoid processing additional events until the current one has finished. If the sidebar is not available to
/// process a specific event, it gets queued back in the list.
/// </summary>
private void ProcessEvent() {
if(CurrSidebarState == SidebarControllerStates.BLOCKED_EVENT) {
return;
}
if(sidebarEvents.Count > 0) {
if(SidebarViewReady && !MiniGameBase.IsActive) {
foreach(KeyValuePair<SidebarEventController.SidebarEventID, Queue<SidebarEventController.GenericSidebarEventArgs>> pair in
sidebarEvents) {
if(pair.Value != null && pair.Value.Count > 0) {
currEventProcessed = pair.Value.Dequeue();
if(currEventProcessed != null) {
currEventID = currEventProcessed.GetEventID();
if(currEventID == SidebarEventController.SidebarEventID.NEW_MISSION && AquaUIManager.Instance.IsSidebarInteractionTimerActive()) {
QueueEvent(currEventProcessed);
break;
}
if(CurrSidebarState != SidebarControllerStates.PROCESSING_EVENT) {
CurrSidebarState = SidebarControllerStates.PROCESSING_EVENT;
if(currEventProcessed.ProcessEvent()) {
CurrSidebarState = SidebarControllerStates.WAITING_EVENT;
}
}
} else {
QueueEvent(currEventProcessed);
}
break;
}
}
}
}
}
/// <summary>
/// Takes care of inserting the desired Event inside the sorted List.
/// The event ID is used as key for list insertion. If we already have a Queue
/// of events that uses that same ID, we don't need to create a new one and just Enqueue
/// that event, otherwise a new queue is created and added to the sorted list.
/// </summary>
/// <param name='_toQueue'>
/// The event we want to queue.
/// </param>
private void QueueEvent(SidebarEventController.GenericSidebarEventArgs _toQueue) {
if(_toQueue != null) {
SidebarEventController.SidebarEventID eventID = _toQueue.GetEventID();
if(!sidebarEvents.ContainsKey(eventID)) {
sidebarEvents.Add(eventID, new Queue<SidebarEventController.GenericSidebarEventArgs>());
}
sidebarEvents[eventID].Enqueue(_toQueue);
}
}
/// <summary>
/// Callback for when a new event is received. Takes care of inserting the event in the Event list
/// and tries to process the highest priority one right away if Sidebar is available.
/// </summary>
/// <param name='sender'>
/// The object that has sent the event
/// </param>
/// <param name='genericEvent'>
/// The event being sent.
/// </param>
private void GenericEventHandler(object sender, SidebarEventController.GenericSidebarEventArgs genericEvent) {
if(genericEvent != null) {
QueueEvent(genericEvent);
if(SidebarViewReady && !GameManager.Instance.Paused && !AquaDialogs.Instance.IsDialogCurrentlyShowing) {
ProcessEvent();
}
}
}
void Update() {
if(CurrSidebarState == SidebarControllerStates.WAITING_EVENT) {
ProcessEvent();
}
}
}
using Social;
/// <summary>
/// This class handles dispatching of events related to sidebar.
/// </summary>
public class SidebarEventController {
public delegate void MissionEventHandler(object sender, MissionEventArgs missionEvent);
public static event MissionEventHandler MissionEvent;
public delegate void SidebarGenericEventHandler(object sender, GenericSidebarEventArgs sidebarAnimEvent);
public static event SidebarGenericEventHandler SidebarAnimEvent;
public static event SidebarGenericEventHandler SidebarGenericEvent;
public static void SendMissionEvent(object sender, MissionEventArgs toSend) {
if(MissionEvent != null) {
MissionEvent(sender, toSend);
}
}
public static void SendSidebarAnimEvent(object sender, GenericSidebarEventArgs toSend) {
if(SidebarAnimEvent != null) {
SidebarAnimEvent(sender, toSend);
}
}
public static void SendSidebarGenericEvent(object sender, GenericSidebarEventArgs toSend) {
if(SidebarGenericEvent != null) {
SidebarGenericEvent(sender, toSend);
}
}
//Priorities of IDs. Lower is higher.
public enum SidebarEventID {
PLACEMENT_TUTORIAL,
TRICK_PURCHASED,
PLACEMENT_MOVE_RECORDED,
SIDEBAR_BTN_ANIM,
MISSION_COMPLETE,
MISSION_ACTIVE,
MISSION_OBJ_COMPLETE,
NEW_MISSION,
MISSION_TEASER,
SIDEBAR_BTN_MOVE,
SOCIAL_REQUEST,
MAX_EVENT_ID
}
public class GenericSidebarEventArgs : System.EventArgs {
//Delegate that gets called when the event is processed.
protected System.Action performAction;
protected SidebarEventID eventID;
public SidebarEventID GetEventID() { return eventID; }
public GenericSidebarEventArgs() {
eventID = SidebarEventController.SidebarEventID.MAX_EVENT_ID;
performAction = null;
}
public GenericSidebarEventArgs(System.Action _toPerform, SidebarEventID _eventID) {
eventID = _eventID;
performAction = _toPerform;
}
/// <summary>
/// Base method that takes care of definining behaviour when an event is processed.
/// Overriden in child classes.
/// </summary>
/// <returns>
/// False if it should delay and stop processing of events, true otherwise.
public virtual bool ProcessEvent() {
if(performAction != null) {
performAction();
}
if(eventID == SidebarEventController.SidebarEventID.TRICK_PURCHASED) {
return false;
}
return true;
}
public override string ToString () {
return "GenericSidebarEventArgs. EventID: " + GetEventID().ToString() + " Action to perform: " + performAction.ToString();
}
}
//Overrides generic sidebar event for missions.
public class MissionEventArgs : GenericSidebarEventArgs {
private int nMissionID;
private bool bIsNew;
private bool bObjComplete;
private bool bIsHidden;
private MissionObjectives.Mission mMissionObj;
public MissionEventArgs(int _missionID, bool _isNew, bool _objComplete, bool _isHidden, System.Action _toPerform = null) {
nMissionID = _missionID;
bIsNew = _isNew;
bObjComplete = _objComplete;
bIsHidden = _isHidden;
performAction = _toPerform;
mMissionObj = (MissionManager.Instance != null) ? MissionManager.Instance.GetMission(GetMissionID()) : null;
if(GetIsMissionNew()) {
this.eventID = SidebarEventController.SidebarEventID.NEW_MISSION;
} else if(GetIsObjComplete()) {
this.eventID = SidebarEventController.SidebarEventID.MISSION_OBJ_COMPLETE;
}
}
public int GetMissionID() { return nMissionID; }
public bool GetIsMissionNew() { return bIsNew; }
public bool GetIsObjComplete() { return bObjComplete; }
public bool GetIsHidden() { return bIsHidden; }
public override bool ProcessEvent() {
if(GetIsHidden()) {
return true;
}
base.ProcessEvent();
if(GetIsMissionNew()) {
if(!InTankMissionsBar.LastInstance.CheckForNewMissionReady(MissionsButton.MissionsButtonState.NewMission, GetMissionID())) {
InTankMissionsBar.LastInstance.MoveDownMissions(MissionsButton.MissionsButtonState.NewMission, GetMissionID());
}
} else if(GetIsObjComplete()) {
if(mMissionObj != null) {
InTankMissionsBar.LastInstance.LookForMissionInSidebar(GetMissionID());
}
}
return true;
}
public override string ToString () {
return string.Format ("[MissionEventArgs] EventID:{0} MissionID:{1} MissionNew:{2} MissionObjComplete:{3} MissionHidden:{4}",
GetEventID(), GetMissionID(), GetIsMissionNew(), GetIsObjComplete(), GetIsHidden());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment