Skip to content

Instantly share code, notes, and snippets.

@mrkybe
Created May 20, 2025 02:42
Show Gist options
  • Select an option

  • Save mrkybe/dcba4c15f4a18be5d39896f4b2198f2b to your computer and use it in GitHub Desktop.

Select an option

Save mrkybe/dcba4c15f4a18be5d39896f4b2198f2b to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class ShipCoordinator : MonoBehaviour
{
private Dictionary<System, NowOrEvent> State = new Dictionary<System, NowOrEvent>();
[Flags]
public enum System { None = 0, Pathfinding = 1, WorkStations = 2, DoorManager = 4, GasSystem = 8, Crew = 16 }
private NowOrEvent AddSystem(System system)
{
var now = new NowOrEvent { System = system };
State.Add(system, now);
return now;
}
private void Start()
{
Invoke(nameof(WarnForMissing), 5f);
}
private void WarnForMissing()
{
foreach(var s in State)
{
if(s.Value.Ready == false)
{
Debug.Log($"{s.Value.System} was not ready after 5 seconds");
}
}
}
public void WaitFor(UnityAction action, params System[] systems)
{
if (systems == null || systems.Length == 0)
throw new ArgumentException("No systems supplied", nameof(systems));
int remaining = 0;
UnityAction onReady = null;
// local helper to detach all listeners
void Unsubscribe()
{
foreach (var s in systems)
State[s].ReadyEvent.RemoveListener(onReady);
}
onReady = () =>
{
if (--remaining == 0)
{
Unsubscribe();
action();
}
};
foreach (var s in systems)
{
if (!State.TryGetValue(s, out var entry))
{
Debug.Log($"System {s} not registered, adding");
entry = AddSystem(s);
}
if (entry.Ready) continue;
remaining++;
entry.ReadyEvent.AddListener(onReady);
}
// all were already ready
if (remaining == 0) action();
}
public void SystemReady(System sys)
{
if (State.TryGetValue(sys, out var now))
{
if(!now.Ready)
{
now.Ready = true;
now.ReadyEvent.Invoke();
}
else
{
if(sys != System.Crew)
Debug.LogError($"System {sys} Ready was already called once!", this);
}
}
else
{
var newnow = AddSystem(sys);
newnow.Ready = true;
}
}
public class NowOrEvent
{
public System System;
public bool Ready;
public UnityEvent ReadyEvent = new UnityEvent();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment