Skip to content

Instantly share code, notes, and snippets.

@adammyhre
Created March 31, 2024 02:50
Show Gist options
  • Save adammyhre/927556d14a957ed1422f4aa9cf9bd683 to your computer and use it in GitHub Desktop.
Save adammyhre/927556d14a957ed1422f4aa9cf9bd683 to your computer and use it in GitHub Desktop.
Unity Mediator
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public abstract class Mediator<T> : MonoBehaviour where T : Component, IVisitable {
readonly List<T> entities = new List<T>();
public void Register(T entity) {
if (!entities.Contains(entity)) {
entities.Add(entity);
OnRegistered(entity);
}
}
protected virtual void OnRegistered(T entity) {
// noop
}
public void Deregister(T entity) {
if (entities.Contains(entity)) {
entities.Remove(entity);
OnDeregistered(entity);
}
}
protected virtual void OnDeregistered(T entity) {
// noop
}
public void Message(T source, T target, IVisitor message) {
entities.FirstOrDefault(entity => entity.Equals(target))?.Accept(message);
}
public void Broadcast(T source, IVisitor message, Func<T, bool> predicate = null) {
entities.Where(target => source != target && SenderConditionMet(target, predicate) && MediatorConditionMet(target))
.ForEach(target => target.Accept(message));
}
bool SenderConditionMet(T target, Func<T, bool> predicate) => predicate == null || predicate(target);
protected abstract bool MediatorConditionMet(T target);
}
public static class EnumerableExtensions {
/// <summary>
/// Performs an action on each element in the sequence.
/// </summary>
/// <typeparam name="T">The type of elements in the sequence.</typeparam>
/// <param name="sequence">The sequence to iterate over.</param>
/// <param name="action">The action to perform on each element.</param>
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action) {
foreach (var item in sequence) {
action(item);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment