I’ve made an abstract class, which adds an Update method to an UpdateManager as an Action.
The UpdateManager then adds the Action to a Queue, and on every update, an event is invoked for every Action in the Queue.
This means that in every class where I wish to add an Update method, which is called every update cycle. I can just inherit the UpdateObject class, and override the Update(GameTime gameTime) method.
Personally I love this, it’s easy to add an Update method to every class now. But now please tell me if you think this is a viable pattern, or if there’s something fundamentally wrong with this.
public abstract class UpdateObject : IUpdateObject
{
public UpdateObject(int priority = 100)
{
UpdateManager.AddUpdateEvent(Update, priority);
}
public abstract void Update(GameTime gameTime);
}
public static class UpdateManager
{
private static Queue<Action<GameTime>> EventQueue = new Queue<Action<GameTime>>();
private static List<(Action<GameTime> action, int priority)> UpdateEventsWithPriority = new List<(Action<GameTime>, int)>();
private static IEnumerable<Action<GameTime>> OrderedUpdateEvents = new List<Action<GameTime>>();
public static void AddUpdateEvent(Action<GameTime> action, int priority)
{
var newEvent = (action, priority);
// Find the index to insert the new event based on priority
int index = UpdateEventsWithPriority.FindIndex(eventItem => eventItem.priority >= priority);
if (index == -1)
{
// If no event with higher or equal priority is found, insert at the end
UpdateEventsWithPriority.Add(newEvent);
}
else
{
// Otherwise, insert at the appropriate index
UpdateEventsWithPriority.Insert(index, newEvent);
}
OrderedUpdateEvents = UpdateEventsWithPriority.Select(e => e.action);
}
//This is called in every Update from Game1.cs
public static void ProcessEvents(GameTime gameTime)
{
foreach (Action<GameTime> action in OrderedUpdateEvents)
{
EventQueue.Enqueue(action);
}
while (EventQueue.Any())
{
var eventAction = EventQueue.Dequeue();
eventAction?.Invoke(gameTime);
}
}
}