状态机生锈了?

Mak*_*gan 1 syntax state-machine rust

在 C 系列语言中,我通常将状态机实现为一系列 if else 语句和枚举,其中 if 语句检查机器处于哪个状态,并且主体执行状态转换,例如:

if(current_left_state == GLFW_PRESS && !left_pressed)
{
    left_pressed = true;
    return MouseInputState::LEFT_DOWN;
}
if(current_left_state == GLFW_PRESS && left_pressed)
{
    left_pressed = true;
    return MouseInputState::LEFT_DRAG;
}
if(current_left_state == GLFW_RELEASE && left_pressed)
{
    left_pressed = false;
    return MouseInputState::LEFT_UP;
}
if(current_right_state == GLFW_PRESS && !right_pressed)
{
    right_pressed = true;
    return MouseInputState::RIGHT_DOWN;
}
Run Code Online (Sandbox Code Playgroud)

Rust 有很多惯用的糖,这很好,我想知道是否有一种方法可以使用 Rust 的语法糖来制作更干净的状态机。

就像,一定有比这更好的方法:

MouseState::NoAction =>
{
    if *button == glfw::MouseButtonLeft && *action == glfw::Action::Press
    {
        return MouseState::LeftDown;
    }
    if *button == glfw::MouseButtonRight && *action == glfw::Action::Press
    {
        return MouseState::RightDown;
    }
    return MouseState::NoAction;
}
MouseState::LeftDown =>
{
    if *button == glfw::MouseButtonLeft && *action == glfw::Action::Release
    {
        return MouseState::LeftUp;
    }
    return MouseState::LeftDrag;
}
MouseState::LeftDrag =>
{
    if *button == glfw::MouseButtonLeft && *action == glfw::Action::Release
    {
        return MouseState::LeftUp;
    }
    return MouseState::LeftDrag;
}
MouseState::LeftUp =>
{
    if *button == glfw::MouseButtonLeft && *action == glfw::Action::Press
    {
        return MouseState::LeftUp;
    }
    return MouseState::NoAction;
}
Run Code Online (Sandbox Code Playgroud)

isa*_*tfa 6

对于真正干净的状态机,您可以匹配元组:

let next_state = match (current_state, button, action) => {
    (MouseState::NoAction, glfw::MouseButtonLeft, glfw::Action::Press) => MouseState::LeftDown,
    (MouseState::NoAction, glfw::MouseButtonRight, glfw::Action::Press) => MouseState::RightDown,
    (MouseState::NoAction, _, _) => MouseState::RightDown,
    (MouseState::LeftDown, glfw::MouseButtonLeft, glfw::Action::Release) => MouseState::LeftUp,
    (MouseState::LeftDown, _, _) => MouseState::LeftDrag,
    (MouseState::LeftDrag, glfw::MouseButtonLeft, glfw::Action::Release) => MouseState::LeftUp,
    (MouseState::LeftDrag, _, _) => MouseState::LeftDrag,
    (MouseState::LeftUp, glfw::MouseButtonLeft, glfw::Action::Press) => MouseState::LeftUp,
    (MouseState::LeftUp, _, _) => MouseState::NoAction,
    _ => MouseState::NoAction,
}
Run Code Online (Sandbox Code Playgroud)

根据您的喜好,您可以使用该模式合并具有相同结果的分支|