Skip to content

Commit

Permalink
Merge pull request #8 from chickensoft-games/fix/binding-state
Browse files Browse the repository at this point in the history
fix: support patterns in generator, better support abstract and interface types in binding callbacks
  • Loading branch information
jolexxa authored Aug 2, 2023
2 parents e72ffac + 8c5c955 commit 67658e0
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 12 deletions.
30 changes: 30 additions & 0 deletions Chickensoft.LogicBlocks.Generator.Tests/test_cases/Patterns.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace Chickensoft.LogicBlocks.Generator.Tests;

[StateMachine]
public class Patterns : LogicBlock<Patterns.Input, Patterns.State, LightSwitch.Output> {
public enum Mode { One, Two, Three }

public override State GetInitialState(Context context) =>
new State.One(context);

public abstract record Input {
public record SetMode(Mode Mode) : Input;
}

public abstract record State(Context Context) : StateLogic(Context), IGet<Input.SetMode> {
public State On(Input.SetMode input) => input.Mode switch {
Mode.One => new One(Context),
Mode.Two => new Two(Context),
Mode.Three => true switch {
true => new Three(Context),
false => throw new NotImplementedException()
},
_ => throw new NotImplementedException()
};
public record One(Context Context) : State(Context);
public record Two(Context Context) : State(Context);
public record Three(Context Context) : State(Context);
}

public abstract record Output { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@startuml Patterns
state "Patterns State" as Chickensoft_LogicBlocks_Generator_Tests_Patterns_State {
state "One" as Chickensoft_LogicBlocks_Generator_Tests_Patterns_State_One
state "Two" as Chickensoft_LogicBlocks_Generator_Tests_Patterns_State_Two
state "Three" as Chickensoft_LogicBlocks_Generator_Tests_Patterns_State_Three
}
[*] --> Chickensoft_LogicBlocks_Generator_Tests_Patterns_State_One
@enduml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<NoWarn>NU5128</NoWarn>

<Title>LogicBlocks Generator</Title>
<Version>2.1.0</Version>
<Version>2.1.1</Version>
<Description></Description>
<Copyright>© 2023 Chickensoft Games</Copyright>
<Authors>Chickensoft</Authors>
Expand Down
8 changes: 8 additions & 0 deletions Chickensoft.LogicBlocks.Generator/src/ReturnTypeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ private void AddExpressionToReturnTypes(ExpressionSyntax? expression) {
return;
}

if (expression is SwitchExpressionSyntax @switch) {
foreach (var arm in @switch.Arms) {
AddExpressionToReturnTypes(arm.Expression);
}

return;
}

if (expression is BinaryExpressionSyntax binary) {
AddExpressionToReturnTypes(binary.Left);
AddExpressionToReturnTypes(binary.Right);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ state "TestMachine State" as Chickensoft_LogicBlocks_Tests_Fixtures_TestMachine_
}
}

Chickensoft_LogicBlocks_Tests_Fixtures_TestMachine_State --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachine_State_Activated_Blooped : Activate
Chickensoft_LogicBlocks_Tests_Fixtures_TestMachine_State --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachine_State_Activated_Bopped : Activate
Chickensoft_LogicBlocks_Tests_Fixtures_TestMachine_State_Activated --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachine_State_Deactivated : Deactivate

[*] --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachine_State_Deactivated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ state "TestMachineReusable State" as Chickensoft_LogicBlocks_Tests_Fixtures_Test
}
}

Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusable_State --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusable_State_Activated_Blooped : Activate
Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusable_State --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusable_State_Activated_Bopped : Activate
Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusable_State_Activated --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusable_State_Deactivated : Deactivate

[*] --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusable_State_Deactivated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ state "TestMachineReusableAsync State" as Chickensoft_LogicBlocks_Tests_Fixtures
}
}

Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusableAsync_State --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusableAsync_State_Activated_Blooped : Activate
Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusableAsync_State --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusableAsync_State_Activated_Bopped : Activate
Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusableAsync_State_Activated --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusableAsync_State_Deactivated : Deactivate

[*] --> Chickensoft_LogicBlocks_Tests_Fixtures_TestMachineReusableAsync_State_Deactivated
Expand Down
20 changes: 15 additions & 5 deletions Chickensoft.LogicBlocks.Tests/test/src/LogicBlock.BindingTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,17 @@ public class BlocGlueTests {
public static bool WasFinalized { get; set; }

[Fact]
public void DoesNotUpdateIfStateIsSameState() { }
public void UpdatesForEveryState() {
var block = new FakeLogicBlock();
using var binding = block.Bind();

var called = 0;
binding.When<FakeLogicBlock.State>().Call((state) => called++);

block.Input(new FakeLogicBlock.Input.InputTwo("d", "e"));

called.ShouldBe(1);
}

[Fact]
public void DoesNotUpdateIfSelectedDataIsSameObject() {
Expand All @@ -30,7 +40,7 @@ public void DoesNotUpdateIfSelectedDataIsSameObject() {
block.Input(new FakeLogicBlock.Input.InputTwo(a, b));
block.Input(new FakeLogicBlock.Input.InputTwo(a, "c"));

count.ShouldBe(1);
count.ShouldBe(2);
}

[Fact]
Expand Down Expand Up @@ -148,19 +158,19 @@ public void CallsSubstateTransitionsOnlyOnce() {
block.Input(new FakeLogicBlock.Input.InputTwo("c", "d"));

callStateA.ShouldBe(0);
callStateB.ShouldBe(1);
callStateB.ShouldBe(2);
block.Value.ShouldBeOfType<FakeLogicBlock.State.StateB>();

block.Input(new FakeLogicBlock.Input.InputOne(1, 2));

callStateA.ShouldBe(1);
callStateB.ShouldBe(1);
callStateB.ShouldBe(2);
block.Value.ShouldBeOfType<FakeLogicBlock.State.StateA>();

block.Input(new FakeLogicBlock.Input.InputTwo("a", "b"));

callStateA.ShouldBe(1);
callStateB.ShouldBe(2);
callStateB.ShouldBe(3);
block.Value.ShouldBeOfType<FakeLogicBlock.State.StateB>();
}

Expand Down
2 changes: 1 addition & 1 deletion Chickensoft.LogicBlocks/Chickensoft.LogicBlocks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<DebugType>portable</DebugType>

<Title>LogicBlocks</Title>
<Version>2.1.0</Version>
<Version>2.1.1</Version>
<Description>State management in a box.</Description>
<Copyright>© 2023 Chickensoft</Copyright>
<Authors>Chickensoft</Authors>
Expand Down
5 changes: 0 additions & 5 deletions Chickensoft.LogicBlocks/src/Logic.Binding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,6 @@ internal void Run(TState state, TState previous) {
}
}

if (previous is TStateType) {
// Overall state hasn't changed types. No need to run callbacks.
return;
}

foreach (var callback in _callbacks) {
callback(state, previous);
}
Expand Down

0 comments on commit 67658e0

Please sign in to comment.