zoukankan      html  css  js  c++  java
  • [XState] Guarded Transitions

    Garuded Transitions, it prevents the state goes from current sate to its target state is condition is falsy.

    const machine = createMachine(
      {
        initial: "idle",
        context: {
          x: 0,
          y: 0,
          dx: 0,
          dy: 0,
          px: 0,
          py: 0,
          drags: 0,
        },
        states: {
          idle: {
            on: {
              mousedown:{
                cond: "noMoreThanFiveTimes",
                actions: assignPoint,
                target: "dragging",
              },
            },
          },
          dragging: {
            entry: countDrags,
            on: {
              mousemove: {
                actions: assignDelta,
              },
              mouseup: {
                actions: [assignPosition],
                target: "idle",
              },
              "keyup.escape": {
                target: "idle",
                actions: resetPosition,
              },
            },
          },
        },
      },
      {
        guards: {
          noMoreThanFiveTimes: (context) => {
            return context.drags >= 5 ? false : true;
          },
        },
      }
    );

    In the code, users cannot drag more than 5 times. So it preventing going to 'dragging' state by 'cond: "noMoreThanFiveTimes"'.

    So if we cannot go 'dragging' state after five times drags... what should we do then?

    We can introduce a final state "draggedOut":

    const machine = createMachine(
      {
        initial: "idle",
        context: {
          x: 0,
          y: 0,
          dx: 0,
          dy: 0,
          px: 0,
          py: 0,
          drags: 0,
        },
        states: {
          idle: {
            on: {
              // if use Array with cond,
              // for first cond which is false
              // then it continue to second state 'draggedOut'
              mousedown: [
                {
                  cond: "noMoreThanFiveTimes",
                  actions: assignPoint,
                  target: "dragging",
                },
                {
                  target: "draggedOut",
                },
              ],
            },
          },
          draggedOut: {
            type: "final",
          },
          dragging: {
            entry: countDrags,
            on: {
              mousemove: {
                actions: assignDelta,
              },
              mouseup: {
                actions: [assignPosition],
                target: "idle",
              },
              "keyup.escape": {
                target: "idle",
                actions: resetPosition,
              },
            },
          },
        },
      },
      {
        guards: {
          noMoreThanFiveTimes: (context) => {
            return context.drags >= 5 ? false : true;
          },
        },
      }
    );

    So in 'mousedown' event, we use 'Array' type, so it try first target 'dragging' with condition. If the condition is false, then it will try second target 'draggedOut' which is our final state.

  • 相关阅读:
    优化SQL查询:如何写出高性能SQL语句
    动态库与静态库
    多线程程序中fork导致的一些问题
    合理的使用size_t可以提高程序的可移植性和代码的可读性,让你的程序更高效。
    linux下C++ STL hash_map的使用以及使用char *型变量作为Key值的一大“坑”
    阅读腾讯编程规范的笔记
    2、vector的实现
    linux下C++对线程的封装
    1、空间配置器
    SQL Server三种表连接原理
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13363059.html
Copyright © 2011-2022 走看看