simprokmachine

Creator: coderz1093

Last updated:

0 purchases

TODO
Add to Cart

Description:

simprokmachine

simprokmachine #
Introduction #
Every application consists of the classes that refer to the other classes, which refer to the other classes etc. It is a tree of classes where each one knows about its children and doesn't know about its parent.
In general, classes communicate with each other by calling methods and properties of their children to pass data "down" or by triggering a callback passing data "up" to the parent.
Moreover, we have many patterns to make this communication easier such as delegate, facade, observable, command, etc. And we haven't even started discussing how to pass data from the logic's layer to the UI.
Problem #
Every time the communication must be organized it is up to us to decide which pattern to use, and how to handle it. This requires attention and can easily result in unexpected bugs.
Solution #
simprokmachine is a framework that automates the communication between the application's components called "machines".
How to use #
Machine - is an instance in your application that receives and processes input data and may emit output.

To create it use ChildMachine class.
class PrinterMachine extends ChildMachine<String, bool> {

@override
void process(String? input, Handler<bool> callback) {
log(input);
}
}
copied to clipboard
If your machine must update flutter widgets with its input - use ChildWidgetMachine instead. Combine it with MachineConsumer to update UI where needed.
class PrinterWidgetMachine extends ChildWidgetMachine<String, bool> {

@override
Widget child() {
return MaterialApp(
home: Scaffold(
body: Center(
child: MachineConsumer<String, bool>(
initial: (BuildContext context) => Text("UI before first input was received"),
builder: (BuildContext context, String? input, Handler<bool> callback) => Text("UI when input received: $input")
),
),
),
),
}
}
copied to clipboard
To start the flow use runRootMachine() method in your main() function.
void main() {
runRootMachine<String, bool>(
root: PrinterWidgetMachine(),
);
}
copied to clipboard
This does not print anything but null because after startRootMachine() is called the root is subscribed to the child machine triggering process() method with null value.
Use Handler<Output> callback to emit output.
class EmittingMachine extends ChildMachine<String, bool> {

void process(String? input, Handler<bool> callback) {
if (input != null) {
log("input: \(input)");
} else {
callback(false); // Emits output
}
}
}
copied to clipboard
To unite two or more machines where one machine is WidgetMachine and another one is plain Machine use mergeWidgetMachine().
void main() {
runRootMachine<String, bool>(
root: mergeWidgetMachine(
main: PrinterWidgetMachine(),
secondary: { PrinterMachine(), },
),
);
}
copied to clipboard
To merge more than one machine together - use merge().
final Machine<Input, Output> machine1 = ...
final Machine<Input, Output> machine2 = ...

... = merge({
machine1,
machine2,
});
copied to clipboard
To separate machines into classes instead of cluttering them up in the runRootMachine(), use ParentMachine or ParentWidgetMachine classes.
class IntermediateLayer extends ParentMachine<String, bool> {

@override
Machine<String, bool> child() {
return PrinterMachine(); // or PrinterWidgetMachine() if extends ParentWidgetMachine
}
}
copied to clipboard
To map or ignore input - use inward().
... = machine.inward((ParentInput parentInput) {
return Ward.values([ChildInput(), ChildInput(), ChildInput()]); // pass zero, one or more outputs.
})
copied to clipboard
To map or ignore output - use outward().
... = machine.outward((ChildOutput childOutput) {
return Ward.values([ParentOutput(), ParentOutput(), ParentOutput()]); // pass zero, one or more outputs.
});
copied to clipboard
To send input back to the child when output received - use redirect().
... = machine.redirect((ChildOutput childOutput) {
// Return
// Direction.prop() - for pushing ChildOutput further to the root.
// Direction.back(Ward.values([ChildInput()])) - for sending child inputs back to the child.
...
});
copied to clipboard
Check out the sample and the wiki for more information about API and how to use it.
Killer-features #

Declarative way of describing your application's behavior.
Automated concurrency management saves from race conditions, deadlocks, and headache.
Flexible. Every existing component can become a machine.
Modular. Every machine can be described once and reused easily.
Cross-platform. Kotlin and Native iOS supported.

Installation #
Add the line into pubspec.yaml:
dependencies:
simprokmachine: ^1.1.3
copied to clipboard
Now in your Dart code, you can use:
import 'package:simprokmachine/simprokmachine.dart';
copied to clipboard
What to check next #
Check out these tools to see an existing library of useful machines and the architectural approach we suggest using.

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files In This Product:

Customer Reviews

There are no reviews.