Code Monkey home page Code Monkey logo

state-machine's Introduction

state-machine

Turn any type into a state machine.

Example

A simple example of a state machine would be as follows.

import state_machine;

struct Order
{
    // Turn order into a state-machine with 3 states.
    mixin StateMachine!(status, "pending", "ordered", "paid");
    
    uint status;
}

Mixing in StateMachine gives our type functions to check its current state, as well as ones to control its transitions between states.

void main()
{
    Order o;
    
    assert(o.pending is true);
    assert(o.ordered is false);
    
    // Change status to ordered.
    assert(o.toOrdered() is true);

    assert(o.pending is false);
    assert(o.ordered is true);
}

Callbacks

You can also define callbacks to control transitions between states, as well as update fields in response to transitions.

import state_machine;

struct Order
{
    // Turn order into a state-machine with 3 states.
    mixin StateMachine!(status, "pending", "ordered", "paid");
    
    uint status;
    
    double total   = 0;
    double balance = 0;
    
    @BeforeTransition("ordered")
    bool isPendingAndTotalNonZero()
    {
        return this.pending && total > 0;
    }
    
    @AfterTransition("ordered")
    void setBalanceFromTotal()
    {
        balance = total;
    }
    
    @BeforeTransition("paid")
    bool isOrderedAndBalanceZero()
    {
        return this.ordered && balance == 0;
    }
}

Now Order requires a non-zero total to be transition to the ordered state, and a zero balance to become paid. In addition, the balance is automatically set when transitioning from pending to ordered.

void main()
{
    Order o;
    
    assert(o.pending is true);
    assert(o.toOrdered() is false);
    
    // Requires non-zero total.
    o.total = 50.00;
    assert(o.toOrdered() is true);

    // Balance is auto-set.
    assert(o.balance == 50.00);
    assert(o.toPaid() is false);

    // Balance must be zero.
    o.balance = 0;
    assert(o.toPaid() is true);
}

StateMachine operates on a given state field, which can be an int (or covariant type), a string, an enum type, or a @property of one of those 3 types. It also exposes some helpful meta-functions.

void main()
{
    Order o;

    assert(o.statusNames == ["pending", "ordered", "paid"]);
    assert(o.statusValues == [
        "pending": 0,
        "ordered": 1,
        "paid": 2
    ]);
}

License

MIT

state-machine's People

Contributors

mihail-k avatar rjmcguire avatar

Watchers

James Cloos avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.