mercredi 29 avril 2020

StateMachine (One Trigger with Two States)

I am using Statless.StateMachine and I am facing a situation where I have one trigger with two states! Let me explain, I have an application where I need to activate some buttons when a user fills out a textbox but at the same time, those buttons will be deactivated when the user clears the textbox.

What I have done is that I have created two states Waiting and Editing. On waiting, the buttons are deactivated while on editing the buttons are activated as long as the textbox is not empty. To solve this, I wrote the following code:

_machine.Configure(State.ChoiceWaiting)
    .OnEntry(() => Setup())
    .PermitIf(Trigger.Edit, State.Editing, () => CheckEditing())
    .PermitReentryIf(Trigger.Wait, () => !CheckEditing());

_machine.Configure(State.Editing)
    .OnEntry(() => Setup2())
    .PermitIf(Trigger.Wait, State.ChoiceWaiting, () => !CheckEditing())
    .PermitIf(Trigger.Edit, State.ChoiceWaiting, () => !CheckEditing())
    .PermitReentryIf(Trigger.Edit, () => CheckEditing());

Now KeyUp event of the textbox is:

private void TextBlock_KeyUp(object sender, KeyEventArgs e)
{
    _machine.Fire(Trigger.Edit);
}

the previous code is working fine, the problem appears when pressing Backspace while the textbox is empty

System.InvalidOperationException: 'Trigger 'Edit' is valid for transition from state 'ChoiceWaiting' but a guard conditions are not met. Guard descriptions: 'Function

I know that I can solve the issue by having a condition to determine which trigger to fire on KeyUp event, but I feel that defeats the purpose of State Design Pattern as I need to control the states without the mess of if-else inside the code like KeyUp (outside StateMachine as PermitIf will do the decision on its own).

Is a correct application of the state design pattern? Or is there something I have missed?

Aucun commentaire:

Enregistrer un commentaire