Skip to content

Instantly share code, notes, and snippets.

@CoffeeVampir3
Created June 12, 2021 02:47
Show Gist options
  • Save CoffeeVampir3/c81ab2d2999318041c300f667397953d to your computer and use it in GitHub Desktop.
Save CoffeeVampir3/c81ab2d2999318041c300f667397953d to your computer and use it in GitHub Desktop.
Non-Academic Rule Engine
public interface IRule<in Ruleable> : IRule
where Ruleable : IRuleable
{
/// <summary>
/// Tries to run this specific rule.
/// </summary>
/// <returns>Returns true if the rule ran on this command.</returns>
bool RunIfValid(Ruleable ruleable);
}
public interface IRule
{
}
public interface IRuleable
{
bool TryRule(IRule rule);
}
public class RuleHandler : MonoBehaviour
{
private static RuleHandler inst = null;
private readonly Dictionary<Type, List<IRule>> allRules = new();
public static RuleHandler Instance
{
get
{
if (inst == null)
{
Debug.LogError(
"Attempted to access rule singleton before it was initialized or there's none in the scene!");
}
return inst;
}
}
public void Awake()
{
if (inst != null)
{
Destroy(this);
return;
}
inst = this;
DontDestroyOnLoad(this);
}
public void OnEnable() => allRules.Clear();
public void RegisterRule<T>(IRule<T> rule, Type ruleType)
where T : IRuleable
{
if(!allRules.TryGetValue(ruleType, out var specificRules))
{
specificRules = new List<IRule>();
allRules.Add(ruleType, specificRules);
}
specificRules.Add(rule);
Debug.Log("Command: " + ruleType + " was registered by " + rule);
}
public void UnregisterRule<T>(IRule<T> rule, Type ruleType)
where T : IRuleable
{
Debug.Log("Trying to unregister command: ");
if(!allRules.TryGetValue(ruleType, out var rules))
return;
if(rules.Contains(rule))
rules.Remove(rule);
Debug.Log("Command: " + ruleType + " was unregistered by " + rule);
}
public void RunRulesOn(IRuleable ruleable, bool shouldConsumeAUse)
{
if (!allRules.TryGetValue(ruleable.GetType(), out var rules))
return;
for (var i = rules.Count - 1; i >= 0; i--)
{
var rule = rules[i];
var wasRuleApplied = ruleable.TryRule(rule);
if (shouldConsumeAUse
&& wasRuleApplied
&& rule is IOnRuleUsedReceiver limitedRule)
limitedRule.OnRuleUsed();
}
}
}
public static class RuleHandlerHelper
{
public static void RegisterRule<T>(this IRule<T> rule, Type ruleType)
where T : IRuleable
=> RuleHandler.Instance.RegisterRule(rule, ruleType);
public static void UnregisterRule<T>(this IRule<T> rule, Type ruleType)
where T : IRuleable
=> RuleHandler.Instance.UnregisterRule(rule, ruleType);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment