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

How do we send data to another State when activating it? #13

Open
svk014 opened this issue Jan 18, 2022 · 7 comments
Open

How do we send data to another State when activating it? #13

svk014 opened this issue Jan 18, 2022 · 7 comments
Labels

Comments

@svk014
Copy link

svk014 commented Jan 18, 2022

Consider two states StateA and StateB. StateA has a transition inside which a method mA1 is executed and it produces some object o1. After, mA1 is executed, we set the current state to StateB. On entering StateB, we need to call another method mA2 with the previously produced object o1.

How do I achieve this? I think this can be achieved using Streams, but is that the best solution?

@renggli
Copy link
Owner

renggli commented Jan 18, 2022

This library doesn't enforce a specific way to model or pass data.

The most strait-forward way would be if you stored the object in a variable that both handlers have access to.

A more generic way would be to use custom state objects, and use a transition handler to propagate the value from the previous state to the next one.

@svk014
Copy link
Author

svk014 commented Jan 18, 2022

Can you please give me an example of the transition handler approach?

@renggli
Copy link
Owner

renggli commented Jan 18, 2022

class Data {
  String? input;
  String? output;
}

void main() {
  final machine = Machine<Data>();
  machine.onBeforeTransition.forEach((event) =>
      event.target?.identifier.input = event.source?.identifier.output);

  final stateA = machine.newState(Data());
  final stateB = machine.newState(Data());

  stateA.enter();
  stateA.identifier.output = 'Hello';

  stateB.enter();
  print(stateB.identifier.input); // Prints 'Hello'
}

@svk014
Copy link
Author

svk014 commented Jan 18, 2022

What do you think about state.enter() accepting an argument? Something along these lines,

State<Data, Custom?> stateA = machine.newState<Custom?>(Data()); 
Custom? customObject;
stateA.enter(customObject);

Internally, the state can hold the data as T? input, and it can clear it by setting input = null in an exitTransition.

@renggli
Copy link
Owner

renggli commented Jan 19, 2022

That sounds like a useful idea, if the typing doesn't get too messy. I have to think about this a bit more.

@renggli
Copy link
Owner

renggli commented Jan 19, 2022

State<I, C> where I is the type for the identifier (present today), and C is the type of the context (or mutable data).

  • Adding C per State would make the API really ugly. At many places where the type would not be know the return type would need to be State<I, dynamic>.

  • Adding C per Machine would make the API slightly less ugly, but much more restrictive. Probably not useful to force all states have the same generic context type?

In either case the API would not be backward compatible (adding a generic type is breaking this). Any other ideas?

@svk014
Copy link
Author

svk014 commented Jan 19, 2022

I agree that this would be not backwards compatible. Adding C per State would make the API more useful, but like you said, things like machine.current would have to return State<I, dynamic> which kind of defeats the purpose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants