Skip to content

Commit

Permalink
Add multi-single modules
Browse files Browse the repository at this point in the history
  • Loading branch information
Anatoly Brizhan committed Apr 16, 2024
1 parent a024a3f commit 3e2b558
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 102 deletions.
16 changes: 6 additions & 10 deletions Assets/BetterStateMachine/Runtime/IStateMachine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,16 @@ public interface IStateMachine<TState> where TState : BaseState
TState CurrentState { get; }
bool InTransition { get; }
Task TransitionTask { get; }

void Run();
Task ChangeStateAsync(TState newState, CancellationToken cancellationToken = default);
bool InState<T>() where T : TState;
Task ChangeStateAsync(TState newState, CancellationToken cancellationToken = default);
void Stop();

public void AddModule(Module<TState> module);

public bool AddModule(Module<TState> module);
public bool HasModule(Module<TState> module);
public bool HasModule(Type type);
public bool HasModule<TModule>() where TModule : Module<TState>;
public bool TryGetModule(Type type, out Module<TState> module);
public bool TryGetModule<TModule>(out TModule module) where TModule : Module<TState>;
public Module<TState> GetModule(Type type);
public TModule GetModule<TModule>() where TModule : Module<TState>;
public bool RemoveModule(Type type);
public bool RemoveModule<TModule>() where TModule : Module<TState>;
public bool RemoveModule(Module<TState> module);
}
}
65 changes: 34 additions & 31 deletions Assets/BetterStateMachine/Runtime/Modules/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,77 +6,76 @@ namespace Better.StateMachine.Runtime.Modules
{
public abstract class Module<TState> where TState : BaseState
{
protected IStateMachine<TState> StateMachine { get; private set; }
public int LinksCount { get; private set; }
public bool IsLinked => LinksCount > 0;

internal void Link(IStateMachine<TState> stateMachine)
public virtual bool AllowLinkTo(IStateMachine<TState> stateMachine)
{
if (StateMachine != null)
{
var message = $"Already linked to {nameof(StateMachine)}";
DebugUtility.LogException<InvalidOperationException>(message);
return;
}
return true;
}

StateMachine = stateMachine;
internal void Link(IStateMachine<TState> stateMachine)
{
LinksCount++;
OnLinked(stateMachine);
}

protected abstract void OnLinked(IStateMachine<TState> stateMachine);

internal void Unlink()
internal void Unlink(IStateMachine<TState> stateMachine)
{
if (StateMachine == null)
{
var message = "Already unlinked";
DebugUtility.LogException<InvalidOperationException>(message);
return;
}

StateMachine = null;
OnUnlinked();
LinksCount--;
OnUnlinked(stateMachine);
}

protected abstract void OnUnlinked();
public virtual bool AllowRunMachine()
protected abstract void OnUnlinked(IStateMachine<TState> stateMachine);

public virtual bool AllowRunMachine(IStateMachine<TState> stateMachine)
{
return true;
}

public virtual void OnMachineRunned()
public virtual void OnMachineRunned(IStateMachine<TState> stateMachine)
{
}

public virtual bool AllowChangeState(TState state)
public virtual bool AllowChangeState(IStateMachine<TState> stateMachine, TState state)
{
return true;
}

public virtual void OnStatePreChanged(TState state)
public virtual void OnStatePreChanged(IStateMachine<TState> stateMachine, TState state)
{
}

public virtual void OnStateChanged(TState state)
public virtual void OnStateChanged(IStateMachine<TState> stateMachine, TState state)
{
}

public virtual bool AllowStopMachine()
public virtual bool AllowStopMachine(IStateMachine<TState> stateMachine)
{
return true;
}

public virtual void OnMachineStopped()
public virtual void OnMachineStopped(IStateMachine<TState> stateMachine)
{
}

protected bool ValidateMachineRunning(bool targetState, bool logException = true)
protected bool ValidateMachineRunning(IStateMachine<TState> stateMachine, bool targetState, bool logException = true)
{
var isRunning = StateMachine?.IsRunning ?? false;
if (stateMachine == null)
{
var message = $"Is not valid, {nameof(stateMachine)} is null";
DebugUtility.LogException<InvalidOperationException>(message);
return false;
}

var isRunning = stateMachine.IsRunning;
var isValid = isRunning == targetState;
if (!isValid && logException)
{
var reason = targetState ? "not running" : "is running";
var message = $"Is not valid, {nameof(StateMachine)} {reason}";
var message = $"Is not valid, {nameof(stateMachine)} {reason}";
DebugUtility.LogException<InvalidOperationException>(message);
}

Expand All @@ -88,4 +87,8 @@ public override string ToString()
return GetType().Name;
}
}

public abstract class Module : Module<BaseState>
{
}
}
53 changes: 53 additions & 0 deletions Assets/BetterStateMachine/Runtime/Modules/SingleModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using Better.Commons.Runtime.Utility;
using Better.StateMachine.Runtime.States;

namespace Better.StateMachine.Runtime.Modules
{
public abstract class SingleModule<TState> : Module<TState>
where TState : BaseState
{
protected IStateMachine<TState> StateMachine { get; private set; }

public override bool AllowLinkTo(IStateMachine<TState> stateMachine)
{
return base.AllowLinkTo(stateMachine) && !IsLinked;
}

protected override void OnLinked(IStateMachine<TState> stateMachine)
{
if (IsLinked)
{
var message = "Already linked";
DebugUtility.LogException<InvalidOperationException>(message);

stateMachine.RemoveModule(this);
return;
}

StateMachine = stateMachine;
}

protected override void OnUnlinked(IStateMachine<TState> stateMachine)
{
if (!IsLinked)
{
var message = "Already unlinked";
DebugUtility.LogException<InvalidOperationException>(message);

return;
}

StateMachine = null;
}

protected bool ValidateMachineRunning(bool targetState, bool logException = true)
{
return ValidateMachineRunning(StateMachine, targetState, logException);
}
}

public abstract class SingleModule : SingleModule<BaseState>
{
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

89 changes: 77 additions & 12 deletions Assets/BetterStateMachine/Runtime/Modules/StatesCacheModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,31 @@ public class StatesCacheModule<TState> : Module<TState>
{
public event Action<TState> Cached;

private readonly bool _autoCache;
private readonly bool _autoClear;
private readonly Dictionary<Type, TState> _typeInstanceMap;

public StatesCacheModule()
public StatesCacheModule(bool autoCache, bool autoClear)
{
_typeInstanceMap = new();
autoCache = autoCache;
_autoClear = autoClear;
}

public StatesCacheModule() : this(true, true)
{
}

protected override void OnLinked(IStateMachine<TState> stateMachine)
{
}

protected override void OnUnlinked()
protected override void OnUnlinked(IStateMachine<TState> stateMachine)
{
ClearCache();
if (_autoClear && !IsLinked)
{
ClearCache();
}
}

public void Cache(TState state)
Expand All @@ -39,11 +50,6 @@ public void Cache(TState state)
OnCached(state);
}

protected virtual void OnCached(TState state)
{
Cached?.Invoke(state);
}

public T Cache<T>() where T : TState, new()
{
var state = new T();
Expand All @@ -52,11 +58,34 @@ protected virtual void OnCached(TState state)
return state;
}

protected virtual void OnCached(TState state)
{
Cached?.Invoke(state);
}

public bool Contains(Type type)
{
if (type == null)
{
DebugUtility.LogException<ArgumentNullException>(nameof(type));
return false;
}

return _typeInstanceMap.ContainsKey(type);
}

public bool Contains(TState state)
{
if (state == null)
{
DebugUtility.LogException<ArgumentNullException>(nameof(state));
return false;
}

var type = state.GetType();
return Remove(type);
}

public bool Contains<T>()
where T : TState
{
Expand All @@ -66,6 +95,14 @@ public bool Contains<T>()

public bool TryGet(Type type, out TState module)
{
if (type == null)
{
DebugUtility.LogException<ArgumentNullException>(nameof(module));

module = default;
return false;
}

return _typeInstanceMap.TryGetValue(type, out module);
}

Expand All @@ -85,6 +122,12 @@ public bool TryGet<T>(out T state) where T : TState

public TState Get(Type type)
{
if (type == null)
{
DebugUtility.LogException<ArgumentNullException>(nameof(type));
return default;
}

if (TryGet(type, out var module))
{
return module;
Expand Down Expand Up @@ -120,21 +163,43 @@ public T Get<T>() where T : TState

public bool Remove(Type type)
{
if (type == null)
{
DebugUtility.LogException<ArgumentNullException>(nameof(type));
return false;
}

return _typeInstanceMap.Remove(type);
}

public bool Remove(TState state)
{
if (state == null)
{
DebugUtility.LogException<ArgumentNullException>(nameof(state));
return false;
}

var type = state.GetType();
return Remove(type);
}

public bool Remove<T>() where T : TState
{
var type = typeof(T);
return Remove(type);
}

public override void OnStatePreChanged(TState state)
public override void OnStatePreChanged(IStateMachine<TState> stateMachine, TState state)
{
base.OnStatePreChanged(state);
Cache(state);
base.OnStatePreChanged(stateMachine, state);

if (_autoCache)
{
Cache(state);
}
}

public void ClearCache()
{
_typeInstanceMap.Clear();
Expand Down
Loading

0 comments on commit 3e2b558

Please sign in to comment.