Improve readme
contrib: fix args again
contrib: parameterize instance name and use a well know database location
Bonsai is a Finite State Machine structured as a tree. It has been designed to trigger commands when successive events and/or a precise context is accepted.
There is 4 kind of transition with specific acceptance rules:
The state will transition following every accepted transition. If there is no more available transition, the state goes back to the initial position.
[
{
"type": "event",
"event_name": "event_foo"
},
{
"type": "context",
"contexts": {
"toto": "titi",
"tata": "tutu"
}
},
{
"type": "delay",
"delay_duration": 500,
"delay_unit": "millisecond",
},
{
"type": "exec",
"command": [
"echo",
"boooh"
]
},
{
"type": "…",
…,
"transitions": [
{
…
},
…
]
}
]
Event input can triggers one or zero event transition. The state will then follows every accepted execs, contexts or delays transitions.
It is easy to soft lock the state machine if you don't plan every situation. The following example show two trees. The first one can reach a soft lock:
[
{
"type": "event",
"event_name": "foo",
"transitions": [
{
"type": "event",
"event_name": "bar",
"transitions": [
{
"type": "exec",
"command": [
"yataaa"
]
}
]
}
]
}
]
If the state machine receives "foo" but no "bar" it stays locked at this position. Maybe this is intended, maybe not. Here how to handle this:
[
{
"type": "event",
"event_name": "foo",
"transitions": [
{
"type": "event",
"event_name": "bar",
"transitions": [
{
"type": "exec",
"command": [
"yataaa"
]
}
]
},
{
"type": "delay",
"delay_duration": 500,
"delay_unit": "millisecond",
}
]
}
]
Now if the state machine receives "foo" but no "bar" in less than 0.5 seconds, it returns to initial position. This is how sxmo use bonsai to support complex keybind sentences.
Exec transition commands are run synchronously. If you don't care about the
command status, or if you use the command as final trigger, and don't want
to hold the bonsai daemon, you should use ["setsid", "-f", …].
Context transitions can be used as "holes" if you don't specify context values, because it will always match. This is particularly useful just after exec transition that may fail. In that example, if the command fails, the state machine goes back to initial position. You can also add child to the context transition, to exec another command:
[
{
"type": "event",
"event_name": "foo",
"transitions": [
{
"type": "exec",
"command": [
"this",
"command",
"can",
"fail"
]
},
{
"type": "context"
}
]
}
]
If the state machine is waiting while receiving an event, or a context update, it checks if there is a accepting event or context transition available. Otherwise it continues to wait.
$ bonsaid -t my/bonsaid/tree.json -D # as daemon
$ bonsaictl -e my_event_name # trigger event
$ bonsaictl -c foo=bar toto=titi # change context
$ make check
$ make
$ doas make install
Send patches to the Sxmo mailing list: Development mailing list for the Sxmo project.
To learn how to use git send-email, please see git-send-email.io.