diff --git a/Runtime/Event/BehaviourEnabledObserver2.cs b/Runtime/Event/BehaviourEnabledObserver2.cs new file mode 100644 index 00000000..fc8d7b53 --- /dev/null +++ b/Runtime/Event/BehaviourEnabledObserver2.cs @@ -0,0 +1,62 @@ +namespace Zinnia.Event +{ + using UnityEngine; + using UnityEngine.Events; + using Malimbe.BehaviourStateRequirementMethod; + using Malimbe.MemberClearanceMethod; + using Malimbe.PropertySerializationAttribute; + using Malimbe.XmlDocumentationAttribute; + using Zinnia.Data.Collection.List; + using Zinnia.Extension; + using Zinnia.Process; + using Zinnia.Rule; + + /// + /// Emits an event once a list of s all are . + /// + public class BehaviourEnabledObserver2 : MonoBehaviour, IProcessable + { + /// + /// The s to observe. + /// + [Serialized] + [field: DocumentedByXml] + public BehaviourObservableList Behaviours { get; set; } + + /// + /// The rule to match against the Behaviours. + /// + [Serialized, Cleared] + [field: DocumentedByXml] + public RuleContainer Rule { get; set; } + + /// + /// Emitted when all are . + /// + [DocumentedByXml] + public UnityEvent ActiveAndEnabled = new UnityEvent(); + + /// + /// Checks whether all are and emits if they are. + /// + /// Whether all are active and enabled. + [RequiresBehaviourState] + public virtual void Process() + { + if (Behaviours == null || Behaviours.NonSubscribableElements.Count == 0) + { + return; + } + + foreach (Behaviour behaviour in Behaviours.NonSubscribableElements) + { + if (!Rule.Accepts(behaviour)) + { + return; + } + } + + ActiveAndEnabled?.Invoke(); + } + } +} diff --git a/Runtime/Event/BehaviourEnabledObserver2.cs.meta b/Runtime/Event/BehaviourEnabledObserver2.cs.meta new file mode 100644 index 00000000..b6461b58 --- /dev/null +++ b/Runtime/Event/BehaviourEnabledObserver2.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fdc10351feed3fe46958637c21b253b2 +timeCreated: 1541932041 \ No newline at end of file diff --git a/Runtime/Process/Moment/CoroutineMomentProcessor.cs b/Runtime/Process/Moment/CoroutineMomentProcessor.cs new file mode 100644 index 00000000..edd92e93 --- /dev/null +++ b/Runtime/Process/Moment/CoroutineMomentProcessor.cs @@ -0,0 +1,136 @@ +namespace Zinnia.Process.Moment +{ + using UnityEngine; + using System.Collections; + using Malimbe.MemberChangeMethod; + using Malimbe.PropertySerializationAttribute; + using Malimbe.XmlDocumentationAttribute; + using Zinnia.Process.Moment.Collection; + + /// + /// Iterates through a given collection and executes the method using Unity coroutine. + /// + public class CoroutineMomentProcessor : MonoBehaviour + { + /// + /// The amount of time to pause after each process iteration. + /// + [Serialized] + [field: DocumentedByXml] + public float Interval { get; set; } = 0.000011f; + /// + /// The maximum amount of time to perform the process before ending. + /// + [Serialized] + [field: DocumentedByXml] + public float MaximumRunTime { get; set; } = float.PositiveInfinity; + + /// + /// A collection of to process. + /// + [Serialized] + [field: DocumentedByXml] + public MomentProcessObservableList Processes { get; set; } + + /// + /// A reference to the started routine. + /// + protected Coroutine processRoutine; + /// + /// Delays the by seconds. + /// + protected WaitForSeconds delayYieldInstruction; + /// + /// The amount of time until the is cancelled. + /// + protected float timeUntilProcessIsCancelled; + + /// + /// Initiates the process if no existing process is already running. + /// + public virtual void BeginProcess() + { + if (processRoutine == null) + { + processRoutine = StartCoroutine(ProcessRoutine()); + } + } + + /// + /// Cancels any running process. + /// + public virtual void EndProcess() + { + if (processRoutine == null) + { + return; + } + + StopCoroutine(processRoutine); + processRoutine = null; + } + + protected virtual void OnEnable() + { + OnAfterCheckDelayChange(); + OnAfterMaximumRunTimeChange(); + BeginProcess(); + } + + protected virtual void OnDisable() + { + EndProcess(); + } + + /// + /// Calls on every frame. + /// + /// An Enumerator to manage the running of the Coroutine. + protected virtual IEnumerator ProcessRoutine() + { + timeUntilProcessIsCancelled = Time.time + MaximumRunTime; + while (Time.time < timeUntilProcessIsCancelled) + { + Process(); + yield return delayYieldInstruction; + } + processRoutine = null; + } + + /// + /// Iterates through the given and calls on each one. + /// + protected virtual void Process() + { + if (Processes == null) + { + return; + } + + foreach (MomentProcess currentProcess in Processes.NonSubscribableElements) + { + currentProcess.Process(); + } + } + + + /// + /// Called after has been changed. + /// + [CalledAfterChangeOf(nameof(Interval))] + protected virtual void OnAfterCheckDelayChange() + { + delayYieldInstruction = new WaitForSeconds(Interval); + } + + /// + /// Called after has been changed. + /// + [CalledAfterChangeOf(nameof(MaximumRunTime))] + protected virtual void OnAfterMaximumRunTimeChange() + { + float remainingRunTime = timeUntilProcessIsCancelled - Time.time; + timeUntilProcessIsCancelled = MaximumRunTime - remainingRunTime; + } + } +} \ No newline at end of file diff --git a/Runtime/Process/Moment/CoroutineMomentProcessor.cs.meta b/Runtime/Process/Moment/CoroutineMomentProcessor.cs.meta new file mode 100644 index 00000000..80f42e3f --- /dev/null +++ b/Runtime/Process/Moment/CoroutineMomentProcessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f209ac37ba2d16b4ea6027fffe5726f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Rule/IsActiveAndEnabledRule.cs b/Runtime/Rule/IsActiveAndEnabledRule.cs new file mode 100644 index 00000000..d46378b3 --- /dev/null +++ b/Runtime/Rule/IsActiveAndEnabledRule.cs @@ -0,0 +1,19 @@ +namespace Zinnia.Rule +{ + using UnityEngine; + using Malimbe.BehaviourStateRequirementMethod; + + /// + /// Determines whether a is active in the scene hierarchy. + /// + public class IsActiveAndEnabledRule : MonoBehaviour, IRule + { + /// + [RequiresBehaviourState] + public bool Accepts(object target) + { + Behaviour behaviour = target as Behaviour; + return behaviour != null && behaviour.isActiveAndEnabled; + } + } +} \ No newline at end of file diff --git a/Runtime/Rule/IsActiveAndEnabledRule.cs.meta b/Runtime/Rule/IsActiveAndEnabledRule.cs.meta new file mode 100644 index 00000000..e51af6f2 --- /dev/null +++ b/Runtime/Rule/IsActiveAndEnabledRule.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59a718228167ba54288f4fc37e9d1e98 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: