Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#13 Transit chore to wait state upon enter events specified in ChoreList config. #324

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ StateTransitionConfig config
var smi = (StateMachine.Instance) chore.GetType().GetProperty("smi").GetValue(chore);
smi.stateMachine.GetState("root").enterActions?.Clear();
smi.stateMachine.GetState("root.delivering")?.enterActions?.Clear();
var state = smi.stateMachine.GetState("root." + config.StateToMonitorName);
var state = config.GetMonitoredState(smi.stateMachine);
state.enterActions?.Clear();
chore.Begin(
new Chore.Precondition.Context {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ public void SetUp() {
Singleton<StateMachineManager>.Instance.Clear();
}

[Test, TestCaseSource(nameof(EnterTestArgs))]
public void ClientStateEnter_DisablesTransition(
Type choreType,
Func<object[]> choreArgsFunc,
Func<Dictionary<int, object?>> stateTransitionArgsFunc,
StateTransitionConfig config
) {
var statesManager = Runtime.Instance.Dependencies.Get<FakeStatesManager>();
statesManager.CalledWithStates.Clear();

var chore = CreateChore(choreType, choreArgsFunc.Invoke());

var smi = statesManager.GetSmi(chore);
var expectedState = config.GetMonitoredState(smi.stateMachine);
Assert.Contains(expectedState, statesManager.CalledWithStates);
}

[Test, TestCaseSource(nameof(ExitTestArgs))]
public void ClientStateExit_DisablesTransition(
Type choreType,
Expand Down
44 changes: 39 additions & 5 deletions src/MultiplayerMod.Test/Multiplayer/States/StatesManagerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ public static void OneTimeSetUp() {
[SetUp]
public void SetUp() {
CreateTestData();
StateMachine.Instance.error = false;
}

[Test, TestCaseSource(nameof(ExitTestArgs))]
protected static IEnumerable<object[]> TestCases() {
return ExitTestArgs().Union(EnterTestArgs());
}

[Test, TestCaseSource(nameof(TestCases))]
public void AllowTransitionPreparesWaitHostState(
Type choreType,
Func<object[]> choreArgsFunc,
Expand All @@ -50,21 +55,50 @@ StateTransitionConfig config
Assert.AreEqual(expectedDictionary, waitHostState.ParametersArgs.Get(smi));
}

[Test, TestCaseSource(nameof(EnterTestArgs))]
public void EnterArgs_DisableChoreStateTransition(
Type choreType,
Func<object[]> choreArgsFunc,
Func<Dictionary<int, object?>> stateTransitionArgsFunc,
StateTransitionConfig config
) {
var sm = Singleton<StateMachineManager>.Instance.CreateStateMachine(GetStatesType(choreType));
sm.GetState("root").events?.Clear();
var statesManager = Runtime.Instance.Dependencies.Get<StatesManager>();
var stateToBeSynced = config.GetMonitoredState(sm);
statesManager.ReplaceWithWaitState(stateToBeSynced);
var chore = CreateChore(choreType, choreArgsFunc.Invoke());
var smi = statesManager.GetSmi(chore);

smi.GoTo(stateToBeSynced);

var waitHostState = (dynamic) statesManager.GetWaitHostState(chore);
Assert.AreEqual(waitHostState, smi.GetCurrentState());
}

[Test, TestCaseSource(nameof(ExitTestArgs))]
public void DisableChoreStateTransition(
public void ExitArgs_DisableChoreStateTransition(
Type choreType,
Func<object[]> choreArgsFunc,
Func<Dictionary<int, object?>> stateTransitionArgsFunc,
StateTransitionConfig config
) {
var sm = Singleton<StateMachineManager>.Instance.CreateStateMachine(GetStatesType(choreType));
sm.defaultState = sm.GetState("root");
sm.GetState("root.delivering")?.enterActions?.Clear();
var statesManager = Runtime.Instance.Dependencies.Get<StatesManager>();
statesManager
.ReplaceWithWaitState(sm.GetState("root"));
var stateToBeSynced = config.GetMonitoredState(sm);
statesManager.ReplaceWithWaitState(stateToBeSynced);
var chore = CreateChore(choreType, choreArgsFunc.Invoke());
var smi = statesManager.GetSmi(chore);
chore.Begin(
new Chore.Precondition.Context {
consumerState = new ChoreConsumerState(Minion.GetComponent<ChoreConsumer>()),
data = PickupableGameObject.GetComponent<Pickupable>()
}
);

smi.GoTo("root." + config.StateToMonitorName);
smi.GoTo(stateToBeSynced);

var waitHostState = (dynamic) statesManager.GetWaitHostState(chore);
Assert.AreEqual(waitHostState, smi.GetCurrentState());
Expand Down
2 changes: 0 additions & 2 deletions src/MultiplayerMod/Game/Chores/Types/StateTransitionConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ public record StateTransitionConfig(
string[] ParameterName
) {

/// TODO: Adjust client logic to wait until receives args from the host.
///
/// TODO: Execute command on the client
public static StateTransitionConfig OnEnter(string stateName, params string[] parameterName) =>
new(TransitionTypeEnum.Enter, stateName, null, parameterName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static void InitializeStatesPatch(StateMachine __instance) {
var config = ChoreList.Config[__instance.GetType().DeclaringType].StatesTransitionSync;

foreach (var stateTransitionConfig in config.StateTransitionConfigs.Where(
it => it.TransitionType == TransitionTypeEnum.Exit
it => it.TransitionType is TransitionTypeEnum.Exit or TransitionTypeEnum.Enter
)) {
var stateToBeSynced = stateTransitionConfig.GetMonitoredState(__instance);
Runtime.Instance.Dependencies.Get<StatesManager>().ReplaceWithWaitState(stateToBeSynced);
Expand Down
7 changes: 4 additions & 3 deletions src/MultiplayerMod/Multiplayer/States/StatesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void InjectWaitHostState(StateMachine sm) {
Activator.CreateInstance(genericType, sm);
}

public object GetWaitHostState(Chore chore) {
public StateMachine.BaseState GetWaitHostState(Chore chore) {
return GetWaitHostState(GetSmi(chore));
}

Expand All @@ -54,10 +54,11 @@ public StateMachine.Instance GetSmi(Chore chore) {
.GetValue(chore);
}

private object GetWaitHostState(StateMachine.Instance smi) => smi.stateMachine.GetState("root." + StateName);
private static StateMachine.BaseState GetWaitHostState(StateMachine.Instance smi) =>
smi.stateMachine.GetState("root." + StateName);

private static void TransitToWaitState(StateMachine.Instance smi) {
smi.GoTo("root." + StateName);
smi.GoTo(GetWaitHostState(smi));
}

}