5个不稳定版本

0.5.0 2022年5月26日
0.2.0 2022年5月25日
0.1.2 2022年5月24日
0.1.1 2022年5月24日
0.1.0 2022年5月24日

#1422 in 算法

MIT许可证

11KB
113

MIT licensed Version

Rust etsm

为Rust的小型状态机,详见etsm

描述

在许多语言中实现一个裸机状态机。这个库旨在尽可能简单,并仅支持基本功能

  • 对象(所有者)上的状态
  • 可选的进入/退出方法
  • 虚拟状态用户方法
  • is in
  • 无限制的转换
  • 无运行时分配

安装

将以下行添加到您的Cargo.toml文件中

[dependencies]
etsm = "x.y.z"

最新版本:版本

或者

将此文件直接添加到您的项目中:etsm

示例

简单

声明状态机

use etsm::*;
state_machine!(
    Foo,
    State {
        {A, Some(Foo::enter_a), Some(Foo::exit_a)},
        {B, Some(Foo::enter_b), None}
    }
);

在您的结构体中实例化状态机

struct Foo {
    state_machine: StateMachine<State>,
}

impl Foo {
    fn new() -> Foo {
        Foo {
            state_machine: StateMachine::new(),
        }
    }
}

添加进入/退出回调

impl Foo {
    //...
    fn enter_a(&mut self) {
        print!(" ->A ");
    }

    fn exit_a(&mut self) {
        print!(" A-> ");
    }

    fn enter_b(&mut self) {
        print!(" ->B ");
    }
}

执行转换

    fn run(&mut self) {
        transition!(self, state_machine, Some(State::A));
        transition!(self, state_machine, Some(State::B));
        transition!(self, state_machine, None);
    }

输出: " ->A A-> ->B "
示例: ab

虚拟状态方法

声明带有数据的状态机,您可以使用任何类型的数据,将此数据视为每个状态静态数据。

state_machine!(
    Foo,
    Data,
    State {
        // state, enter, exit, data
        {  A,     None,  None, Some(Data { run : Foo::run_a })},
        {  B,     None,  None, Some(Data { run : Foo::run_b })}
    }
);

声明statedata结构体

struct Data {
    run: fn(&mut Foo),
}

实现Foo

struct Foo {
    state_machine: StateMachine<State>,
}

impl Foo {
    fn new() -> Foo {
        Foo {
            state_machine: StateMachine::new(),
        }
    }

    fn run_a(&mut self) {
        print!(" A ");
    }

    fn run_b(&mut self) {
        print!(" B ");
    }

    fn run(&mut self) {
        // call run on the current state
        if let Some(statedata) = get_statedata(&self.state_machine) {
            (statedata.run)(self);
        }
    }
}

在Foo上调用方法run,将其转发到当前状态

#[test]
fn virtual_call() {
    let mut foo = Foo::new();

    transition!(&mut foo, state_machine, Some(State::A));
    foo.run();

    transition!(&mut foo, state_machine, Some(State::B));
    foo.run();
}

输出: " A B "
示例: virtual_call

无运行时依赖