-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
using UnityEngine; | ||
|
||
namespace CleverCrow.FluidStateMachine.Examples { | ||
public class CustomStateBuilder : StateBuilderBase<CustomStateBuilder> { | ||
public CustomStateBuilder MyCustomStateBuilderMethod () { | ||
_actions.Add(new ActionEnter((action) => { | ||
Debug.Log("Registered"); | ||
})); | ||
return this; | ||
} | ||
} | ||
|
||
public class FsmBuilderExample : FsmBuilderBase<FsmBuilderExample, CustomStateBuilder> { | ||
public void MyCustomFsmMethod () { | ||
Debug.Log("Custom method"); | ||
} | ||
} | ||
|
||
public class FsmBuilderCustomUsage { | ||
private enum StateId { | ||
A, | ||
} | ||
|
||
public void Init () { | ||
var fsmBuilder = new FsmBuilderExample() | ||
.State(StateId.A, (state) => { | ||
state | ||
.MyCustomStateBuilderMethod() | ||
.Update((action) => { }); | ||
}); | ||
|
||
fsmBuilder.MyCustomFsmMethod(); | ||
|
||
var fsm = fsmBuilder.Build(); | ||
fsm.Tick(); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Dependencies | ||
|
||
You must install Probuilder in order for the example scenes to work. If you haven't done so here are the details on how | ||
to do so with Unity's new Package Manager for free. | ||
|
||
https://docs.unity3d.com/Packages/[email protected]/manual/installing.html |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace CleverCrow.FluidStateMachine { | ||
/// <summary> | ||
/// Triggers the Exit method on the current parent FSM | ||
/// </summary> | ||
public class ActionFsmExit : ActionBase { | ||
protected override void OnEnter () { | ||
ParentState.ParentFsm.Exit(); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
namespace CleverCrow.FluidStateMachine { | ||
/// <summary> | ||
/// Run a nested FSM. Triggers exit transition when nested FSM triggers an Exit event. | ||
/// </summary> | ||
public class ActionRunFsm : ActionBase { | ||
private IFsm _fsm; | ||
private string _exitTransition; | ||
private bool _triggerExit; | ||
|
||
public override string Name => "Run FSM"; | ||
|
||
public ActionRunFsm (string exitTransition, IFsm fsm) { | ||
_fsm = fsm; | ||
_exitTransition = exitTransition; | ||
} | ||
|
||
protected override void OnInit () { | ||
_fsm.EventExit.AddListener(() => _triggerExit = true); | ||
} | ||
|
||
protected override void OnEnter () { | ||
_fsm.Reset(); | ||
_triggerExit = false; | ||
} | ||
|
||
protected override void OnUpdate () { | ||
if (_triggerExit) { | ||
Transition(_exitTransition); | ||
return; | ||
} | ||
|
||
_fsm.Tick(); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
using NSubstitute; | ||
using NUnit.Framework; | ||
using UnityEngine.Events; | ||
|
||
namespace CleverCrow.FluidStateMachine.Editors { | ||
public class ActionRunFsmTest { | ||
private IFsm _fsm; | ||
|
||
[SetUp] | ||
public void BeforeEach () { | ||
var unityEvent = new UnityEvent(); | ||
_fsm = Substitute.For<IFsm>(); | ||
_fsm.EventExit.Returns(unityEvent); | ||
} | ||
|
||
public class EnterMethod : ActionRunFsmTest { | ||
[Test] | ||
public void It_should_trigger_Reset_on_the_fsm () { | ||
var runFsm = new ActionRunFsm("a", _fsm); | ||
|
||
runFsm.Enter(); | ||
|
||
_fsm.Received(1).Reset(); | ||
} | ||
} | ||
|
||
public class UpdateMethod : ActionRunFsmTest { | ||
[Test] | ||
public void It_should_tick_the_nested_fsm () { | ||
var runFsm = new ActionRunFsm("a", _fsm); | ||
|
||
runFsm.Update(); | ||
|
||
_fsm.Received(1).Tick(); | ||
} | ||
|
||
[Test] | ||
public void It_should_trigger_an_Exit_transition_if_FSM_triggers_an_EventExit () { | ||
var state = Substitute.For<IState>(); | ||
var runFsm = new ActionRunFsm("a", _fsm) {ParentState = state}; | ||
|
||
runFsm.Enter(); | ||
_fsm.EventExit.Invoke(); | ||
runFsm.Update(); | ||
|
||
state.Received(1).Transition("a"); | ||
} | ||
|
||
[Test] | ||
public void It_should_not_trigger_transition_again_after_enter_is_called () { | ||
var state = Substitute.For<IState>(); | ||
var runFsm = new ActionRunFsm("a", _fsm) {ParentState = state}; | ||
|
||
runFsm.Enter(); | ||
_fsm.EventExit.Invoke(); | ||
runFsm.Update(); | ||
runFsm.Exit(); | ||
runFsm.Enter(); | ||
runFsm.Update(); | ||
|
||
state.Received(1).Transition("a"); | ||
} | ||
} | ||
|
||
public class IntegrationTests { | ||
private enum StateId { | ||
A, | ||
B, | ||
} | ||
|
||
public class BuilderUsage { | ||
[Test] | ||
public void It_should_not_call_Enter_on_nested_FSM_when_created () { | ||
var stateEnter = false; | ||
var nestedFsm = new FsmBuilder() | ||
.Default(StateId.A) | ||
.State(StateId.A, (state) => { | ||
state.Enter((action) => stateEnter = true); | ||
}) | ||
.Build(); | ||
|
||
new FsmBuilder() | ||
.Default(StateId.A) | ||
.State(StateId.A, (state) => { | ||
state.RunFsm("a", nestedFsm); | ||
}) | ||
.Build(); | ||
|
||
Assert.IsFalse(stateEnter); | ||
} | ||
|
||
[Test] | ||
public void It_should_call_Enter_on_nested_FSM_when_ticked () { | ||
var stateEnter = false; | ||
var nestedFsm = new FsmBuilder() | ||
.Default(StateId.A) | ||
.State(StateId.A, (state) => { | ||
state.Enter((action) => stateEnter = true); | ||
}) | ||
.Build(); | ||
|
||
var fsm = new FsmBuilder() | ||
.Default(StateId.A) | ||
.State(StateId.A, (state) => { | ||
state.RunFsm("a", nestedFsm); | ||
}) | ||
.Build(); | ||
|
||
fsm.Tick(); | ||
|
||
Assert.IsTrue(stateEnter); | ||
} | ||
|
||
[Test] | ||
public void It_should_restart_nested_fsm_on_rerun () { | ||
var nestedFsm = new FsmBuilder() | ||
.Default(StateId.A) | ||
.State(StateId.A, (state) => { | ||
state.SetTransition("next", StateId.B); | ||
state.Update((action) => action.Transition("next")); | ||
}) | ||
.State(StateId.B, (state) => { | ||
state.FsmExit(); | ||
}) | ||
.Build(); | ||
|
||
var fsm = new FsmBuilder() | ||
.Default(StateId.A) | ||
.State(StateId.A, (state) => { | ||
state.SetTransition("next", StateId.B); | ||
state.RunFsm("next", nestedFsm); | ||
}) | ||
.State(StateId.B, (state) => { | ||
state.RunFsm("none", nestedFsm); | ||
}) | ||
.Build(); | ||
|
||
fsm.Tick(); | ||
fsm.Tick(); | ||
|
||
Assert.AreEqual(StateId.A, nestedFsm.CurrentState.Id); | ||
} | ||
} | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System.Linq; | ||
using UnityEditor; | ||
using System.Collections.Generic; | ||
using UnityEngine; | ||
|
||
namespace CleverCrow.FluidStateMachine.Editors { | ||
public class ExportProject { | ||
[MenuItem("Export/Build Fluid State Machine")] | ||
static void BuildProject () { | ||
var files = GetFiles(); | ||
var path = $"{Application.dataPath}/../FluidStateMachine.unitypackage"; | ||
|
||
Debug.Log($"Exporting to {path}"); | ||
AssetDatabase.ExportPackage(files.ToArray(), path); | ||
} | ||
|
||
private static List<string> GetFiles () { | ||
return AssetDatabase | ||
.FindAssets("", new[] { | ||
"Assets/FluidStateMachine", | ||
}).ToList() | ||
.Select(AssetDatabase.GUIDToAssetPath) | ||
.Where(file => !file.Contains("Test.cs")).ToList(); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.