Skip to content

Instantly share code, notes, and snippets.

@EuleMitKeule
Last active July 26, 2021 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EuleMitKeule/8c60d970423e1b596be2baad5d877ad9 to your computer and use it in GitHub Desktop.
Save EuleMitKeule/8c60d970423e1b596be2baad5d877ad9 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using UnityEngine;
namespace UnityExtensions.Runtime
{
public class MonoRoutine
{
IEnumerator Enumerator { get; }
MonoBehaviour Behaviour { get; }
Coroutine Coroutine { get; set; }
bool isRunning;
public bool IsRunning
{
get => isRunning;
private set
{
if (value) Started?.Invoke(Behaviour, EventArgs.Empty);
isRunning = value;
}
}
bool isPaused;
public bool IsPaused
{
get => isPaused;
set
{
if (value) Paused?.Invoke(Behaviour, EventArgs.Empty);
else Unpaused?.Invoke(Behaviour, EventArgs.Empty);
isPaused = value;
}
}
public event EventHandler<MonoRoutineEventArgs> Stopped;
public event EventHandler Paused;
public event EventHandler Unpaused;
public event EventHandler Started;
public MonoRoutine(IEnumerator enumerator, MonoBehaviour behaviour)
{
Enumerator = enumerator;
Behaviour = behaviour;
Coroutine = Behaviour.StartCoroutine(Wrapper());
}
public void Start()
{
if (IsRunning) return;
IsRunning = true;
Enumerator.Reset(); //FAILS
Coroutine ??= Behaviour.StartCoroutine(Wrapper());
}
public void Stop()
{
if (!IsRunning) return;
IsRunning = false;
if (Coroutine != null) Behaviour.StopCoroutine(Coroutine);
Stopped?.Invoke(Behaviour, new MonoRoutineEventArgs(true));
}
public void Pause()
{
if (!IsRunning) return;
IsPaused = true;
}
public void Unpause()
{
if (!IsRunning &! IsPaused) return;
IsPaused = false;
}
public void TogglePause()
{
if (!IsRunning) return;
IsPaused = !IsPaused;
}
IEnumerator Wrapper()
{
while (!IsRunning) yield return null;
while (IsRunning)
{
if (IsPaused) yield return null;
else
{
if (Enumerator != null && Enumerator.MoveNext())
{
yield return Enumerator.Current;
}
else
{
IsRunning = false;
Stopped?.Invoke(Behaviour, new MonoRoutineEventArgs(false));
yield break;
}
}
}
}
}
public class MonoRoutineEventArgs
{
public bool IsForced { get; }
public MonoRoutineEventArgs(bool isForced) => IsForced = isForced;
}
public class TestComponent : MonoBehaviour
{
MonoRoutine Routine { get; set; }
void Awake()
{
Routine = new MonoRoutine(Test, this);
Routine.Started += OnRoutineStarted;
Routine.Paused += OnRoutinePaused;
Routine.Unpaused += OnRoutineUnpaused;
Routine.Stopped += OnRoutineStopped;
Routine.Start();
}
void OnRoutineStarted(object sender, EventArgs e)
{
Debug.Log("Started");
}
void OnRoutinePaused(object sender, EventArgs e)
{
Debug.Log("Paused");
}
void OnRoutineUnpaused(object sender, EventArgs e)
{
Debug.Log("Unpaused");
}
void OnRoutineStopped(object sender, MonoRoutineEventArgs e)
{
Debug.Log("Stopped" + (e.IsForced ? " forcefully" : " not forcefully"));
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Routine.TogglePause();
}
if (Input.GetKeyDown(KeyCode.E))
{
Routine.Stop();
}
if (Input.GetKeyDown(KeyCode.S))
{
Routine.Start();
}
}
IEnumerator Test
{
get
{
yield return new WaitForSeconds(10f);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment