~stacyharper/bonsai

A Finite State Machine structured as a tree that trigger commands
Improve readme
contrib: fix args again
contrib: parameterize instance name and use a well know database location

clone

read-only
https://git.sr.ht/~stacyharper/bonsai
read/write
git@git.sr.ht:~stacyharper/bonsai

You can also use your local clone with git send-email.

#Bonsai

#Definitions

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:

  • event transition: The received event name match the transition one
  • context transition: The state context match the transition one
  • exec transition: The transition command is run and succeed
  • delay transition: The state wait for the delay transition duration. No other accepted event is received while waiting

The state will transition following every accepted transition. If there is no more available transition, the state goes back to the initial position.

#Reference

[
  {
    "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's arent recursives

Event input can triggers one or zero event transition. The state will then follows every accepted execs, contexts or delays transitions.

#Soft locks

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 transitions

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", …].

#Hole transitions

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"
      }
    ]
  }
]
#How delay are cancelled

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.

#Usage

$ bonsaid -t my/bonsaid/tree.json -D # as daemon
$ bonsaictl -e my_event_name # trigger event
$ bonsaictl -c foo=bar toto=titi # change context

#Build

$ make check
$ make
$ doas make install

#Contribute

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.