using System; using System.Collections; using System.Collections.Generic; using SUISS.Core; using SUISS.Scheduling; using UnityEngine; namespace SUISSEngine { public abstract class InterestingEventFlagging where T : struct, IConvertible { public InterestingEventFlagging(Messenger messenger, Scheduler scheduler, IRatingRequestManager ratingRequestManager) { messenger.Subscribe>(new Action>(this.HandleInterestingRatingTriggerEvent)); this._scheduler = scheduler; this._timeOutInfo = new Dictionary.TimeOutInfo>(); this._flags = new Dictionary(); } public InterestingEventFlagging() { } private void HandleInterestingRatingTriggerEvent(InterestingRatingTriggerEvent e) { T eventType = e.EventType; this.AddFlag(eventType); this.HandleFlagAdd(eventType); if (this._timeOutInfo.ContainsKey(eventType)) { this.StartTimer(eventType); } } private void AddFlag(T et) { if (this._flags.ContainsKey(et)) { (this._flags)[et] = this._flags[et] + 1; } else { this._flags.Add(et, 1); } } private void StartTimer(T et) { if (!this._timeOutInfo.ContainsKey(et)) { UnityEngine.Debug.LogWarning("Can not start time since there is no timeoutinfo for the " + et + "event."); return; } InterestingEventFlagging.TimeOutInfo toi = this._timeOutInfo[et]; this._scheduler.StartRoutine(this.TimerCoroutine(et, toi)); } private IEnumerator TimerCoroutine(T et, InterestingEventFlagging.TimeOutInfo toi) { yield return Timing.time + (double)toi.TimeOutDuration; if (toi.TimeOutStyle == InterestingEventFlagging.TimeOutStyle.Decrement && this.FlagsRaised(et) > 0) { (this._flags)[et] = this._flags[et] - 1; } else { this._flags[et] = 0; } yield break; } protected abstract void HandleFlagAdd(T eventType); protected bool FlagRaised(T flag) { return this.FlagsRaised(flag) > 0; } protected int FlagsRaised(T flag) { return (!this._flags.ContainsKey(flag)) ? 0 : this._flags[flag]; } protected void DelayedNotice(double delay) { if (this._delayedNoticeCoroutine != null) { this._scheduler.StopRoutine(this._delayedNoticeCoroutine); } this._delayedNoticeCoroutine = this.DelayedNoticeCoroutine(delay); this._scheduler.StartRoutine(this._delayedNoticeCoroutine); } private IEnumerator DelayedNoticeCoroutine(double delay) { yield return Timing.time + delay; this._delayedNoticeCoroutine = null; yield break; } private Scheduler _scheduler; protected Dictionary.TimeOutInfo> _timeOutInfo; private Dictionary _flags; private IEnumerator _delayedNoticeCoroutine; protected enum TimeOutStyle { FullReset, Decrement } protected class TimeOutInfo { public TimeOutInfo(int timeOutDuration, InterestingEventFlagging.TimeOutStyle timeOutStyle) { this.TimeOutDuration = timeOutDuration; this.TimeOutStyle = timeOutStyle; } public int TimeOutDuration { get; private set; } public InterestingEventFlagging.TimeOutStyle TimeOutStyle { get; private set; } } } }