程序包 cn.wjybxx.btree

类 Task<T>

java.lang.Object
cn.wjybxx.btree.Task<T>
类型参数:
T - 黑板的类型
所有已实现的接口:
ICancelTokenListener
直接已知子类:
BranchTask, Decorator, LeafTask, TaskEntry

public abstract class Task<T> extends Object implements ICancelTokenListener

取消

1.取消默认是协作式的,依赖于任务自身检查;如果期望更及时的响应取消信号,则需要注册注册监听器。 2.通常在执行外部代码后都应该检测. 3.一般而言,不管理上下文的节点在子节点取消时都应该取消自己(因为是同一个CancelToken) 4.Task类默认只在心跳方法中检测取消信号,任何的回调和事件方法中都由用户自身检测。

心跳+事件驱动

1.心跳为主,事件为辅。 2.心跳不是事件!心跳自顶向下驱动,事件则无规律。
作者:
wjybxx date - 2023/11/25
  • 字段概要

    字段
    修饰符和类型
    字段
    说明
    protected T
    任务运行时依赖的黑板(主要上下文) 1.每个任务可有独立的黑板(数据); 2.运行时不能为null; 3.如果是自动继承的,exit后自动删除;如果是Control赋值的,则由control删除。
    protected ICancelToken
    取消令牌(取消上下文) 1.每个任务可有独立的取消信号; 2.运行时不能为null; 3.如果是自动继承的,exit后自动删除;如果是Control赋值的,则由control删除。
    protected int
    任务的自定义标识 1.对任务进行标记是一个常见的需求,我们将其定义在顶层以简化使用 2.在运行期间不应该变动 3.高8位为流程控制特征值,会在任务运行前拷贝到ctl -- 以支持在编辑器导出文件中指定。
    static final org.slf4j.Logger
     
    static final int
     
    static final int
     
    static final int
     
    static final int
     
    static final int
     
    static final int
     
    protected Object
    共享属性(配置上下文) 1.用于解决【数据和行为分离】架构下的配置需求,主要解决策划的配置问题,减少维护工作量。
  • 构造器概要

    构造器
    构造器
    说明
     
  • 方法概要

    修饰符和类型
    方法
    说明
    final int
    addChild(Task<T> task)
    1.尽量不要在运行时增删子节点(危险操作) 2.不建议将Task从一棵树转移到另一棵树,可能产生内存泄漏(引用未删除干净) 3.如果需要知道task的索引,可提前调用getChildCount()
    protected abstract int
     
    protected void
    该方法用于初始化对象。
    boolean
    该方法用于测试自己的状态和事件数据 如果通过条件Task来实现事件过滤,那么通常的写法如下:
    final boolean
    checkCancel(int rid)
    检查取消
    abstract Stream<Task<T>>
    该接口主要用于测试,该接口有一定的开销
    protected void
    enter(int reentryId)
    该方法在Task进入运行状态时执行 1.数据初始化需要放在beforeEnter()中,避免执行逻辑时对象未初始化完成。
    protected abstract void
    Task的心跳方法,在Task进入完成状态之前会反复执行。
    protected void
    该方法在Task进入完成状态时执行 1.该方法与enter(int)对应,通常用于停止enter(int)中启动的逻辑。
    final T
     
     
    abstract Task<T>
    getChild(int index)
    获取指定索引的child
    abstract int
    子节点的数量(仅包括普通意义上的child,不包括钩子任务)
    final Task<T>
     
    final Object
     
    int
    获取当前的帧号
    final int
     
    获取行为树绑定的实体 -- 最好让Entity也在黑板中
    final T
    获取行为树入口绑定的黑板
    final int
     
    final int
     
    final Task<T>
     
    final int
    获取归一化后的状态码,所有的失败码都转换为TaskStatus.ERROR
    final int
    获取任务前一次的执行结果 1.取值范围[0,63] -- 其实只要能区分成功失败就够; 2.这并不是一个运行时必须的属性,而是为Debug和UI视图服务的;
    final int
    获取重入id 1.重入id用于解决事件(或外部逻辑)可能使当前Task进入完成状态的问题。
    final int
    运行的帧数 1.任务如果在首次execute()的时候就进入完成状态,那么运行帧数0 2.运行帧数是非常重要的统计属性,值得我们定义在顶层.
    final Object
     
    final int
    获取原始的状态码
    final TaskEntry<T>
     
    int
    indexChild(Task<?> task)
     
    final boolean
     
    final boolean
     
    final boolean
     
    final boolean
    任务是否已被取消
    final boolean
    任务是否已完成(成功、失败、取消)
    final boolean
     
    final boolean
    execute方法是否是enter触发的 1.用于execute()方法判断当前是否和enter(int)在同一帧,以决定是否执行某些逻辑。
    protected final boolean
    是否正在执行execute()方法 该方法非常重要,主要处理心跳和事件方法之间的冲突。
    final boolean
    isExited(int rid)
    重入id对应的任务是否已退出,即:是否已执行exit()方法。
    final boolean
    exit方法是否是由stop()方法触发的
    final boolean
    任务是否已失败
    final boolean
    任务是否已失败或被取消
    final boolean
    isLocked(int lockId)
     
    final boolean
    是否已通知父节点完成。
    final boolean
    isReentered(int rid)
    查询任务是否已被重入 1.若任务已经重入,则表示产生了递归执行 2.若任务未被重入,则可能正在运行或已结束
    final boolean
    任务是否正在运行
    final boolean
     
    final boolean
    任务是否未启动就失败了。
    final boolean
    任务是否已成功
    final void
    lock(int lockId)
    进行互斥 1.该锁是简单的互斥锁,不支持重入。
    void
    取消令牌的回调方法 注意:如果未启动自动监听,手动监听时也建议绑定到该方法
    protected abstract void
    子节点进入完成状态 1.避免方法数太多,实现类测试task的status即可 2.getNormalizedStatus()有助于switch测试 3.task可能是取消状态,甚至可能没运行过直接失败(前置条件失败) 4.钩子任务和guard不会调用该方法 5.isExecuting()有助于检测冲突,减少调用栈深度 6.同一子节点连续通知的情况下,completed的逻辑应当覆盖onChildRunning(Task)的影响。
    protected abstract void
    子节点还需要继续运行 1.child在运行期间只会通知一次 2.该方法不应该触发状态迁移,即不应该使自己进入完成状态
    final void
    onEvent(Object event)
    Task收到外部事件
    protected abstract void
    对于控制节点,通常将事件派发给约定的子节点或钩子节点。
    void
    删除所有的child -- 不是个常用方法
    final Task<T>
    removeChild(int index)
    删除指定索引的child
    final boolean
    removeChild(Task<?> task)
     
    protected abstract Task<T>
    removeChildImpl(int index)
     
    protected void
    重置所有的子节点 1.如果有需要重置的特殊子节点,可以重写该方法以确保无遗漏
    void
    重置任务以便重新启动(清理运行产生的所有临时数据)
    static void
     
    final void
    setAutoCheckCancel(boolean enable)
    告知模板方法是否自动检测取消 1.默认值由flags中的信息指定,默认自动检测 2.自动检测取消信号是一个动态的属性,可随时更改 -- 因此不要轻易缓存。
    final void
    setAutoListenCancel(boolean enable)
    告知模板方法是否自动监听取消事件 1.默认值由flags中的信息指定,默认不自动监听!
    final void
    setAutoResetChildren(boolean enable)
    告知模板方法是否在beforeEnter()前自动调用resetChildrenForRestart() 1.默认值由flags中的信息指定,默认不启用 2.要覆盖默认值应当在beforeEnter()方法中调用 3.部分任务可能在调用resetForRestart()之前不会再次运行,因此需要该特性
    final void
    setBlackboard(T blackboard)
     
    final void
    设置为取消
    final void
     
    final Task<T>
    setChild(int index, Task<T> newTask)
    替换指定索引位置的child (该方法可避免Task的结构发生变化,也可以减少事件数)
    protected abstract Task<T>
    setChildImpl(int index, Task<T> task)
     
    final void
    setCompleted(int status, boolean fromChild)
    设置为完成 -- 通常用于通过子节点的结果设置自己
    final void
    setControl(Task<T> control)
    设置任务的控制节点
    final void
    setControlData(Object controlData)
     
    final void
    setDisableDelayNotify(boolean disable)
    是否禁用延迟通知 1.默认值由flags中的信息指定,默认不禁用(即默认延迟通知) 2.要覆盖默认值应当在beforeEnter()方法中调用 3.用于解决事件驱动模式下调用栈深度问题 -- 类似尾递归优化,可减少一半栈深度 4.先更新自己为完成状态,再通知父节点,这有时候非常有用 -- 在状态机中,你的State可以感知自己是成功或是失败。
    void
    setEnterFrame(int enterFrame)
    慎重调用
    void
    setExitFrame(int exitFrame)
    慎重调用
    final void
    setFailed(int status)
    设置为执行失败 -- 兼容setGuardFailed(Task)
    final Task<T>
    setFlags(int flags)
     
    final Task<T>
    setGuard(Task<T> guard)
     
    final void
    setGuardFailed(Task<T> control)
    设置为前置条件测试失败 1.该方法仅适用于control测试child的guard失败,令child在未运行的情况下直接失败的情况。
    final void
    setPrevStatus(int prevStatus)
     
    final void
    setSharedProps(Object sharedProps)
     
    final void
    setSlowStart(boolean disable)
    告知模板方法否将enter(int)execute()方法分开执行。
    final void
    设置为运行成功
    final void
    强制停止任务 1.只应该由Control调用,因此不会通知Control 2.未完成的任务默认会进入Cancelled状态 3.不命名为cancel,否则容易误用;我们设计的cancel是协作式的,可通过cancelToken发出请求请求。
    static void
    stop(Task<?> task)
     
    protected void
    停止所有运行中的子节点 1.该方法在自身的exit之前调用 2.如果有特殊的子节点(钩子任务),也需要在这里停止
    final boolean
    检查前置条件 1.如果未显式设置guard的上下文,会默认捕获当前Task的上下文 2.guard的上下文在运行结束后会被清理 3.guard只应该依赖共享上下文(黑板和props),不应当对父节点做任何的假设。
    final void
    execute模板方法 注: 1.如果想减少方法调用,对于运行中的子节点,可直接调用子节点的模板方法。
    final void
    运行子节点,会检查子节点的前置条件
    final void
    运行子节点,不检查子节点的前置条件
    final void
    执行钩子任务,会检查前置条件 1.钩子任务不会触发onChildRunning(Task)onChildCompleted(Task) 2.前置条件其实是特殊的钩子任务
    final void
    执行钩子任务,不检查前置条件
    final boolean
    tryLock(int lockId)
     
    final void
    unlock(int lockId)
     
    final void
    删除任务的控制节点(用于清理) 该方法在任务结束时并不会自动调用,因为Task上的数据可能是有用的,不能立即删除,只有用户知道是否可以清理。

    从类继承的方法 java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • 字段详细资料

    • logger

      public static final org.slf4j.Logger logger
    • MASK_SLOW_START

      public static final int MASK_SLOW_START
      另请参阅:
    • MASK_DISABLE_DELAY_NOTIFY

      public static final int MASK_DISABLE_DELAY_NOTIFY
      另请参阅:
    • MASK_DISABLE_AUTO_CHECK_CANCEL

      public static final int MASK_DISABLE_AUTO_CHECK_CANCEL
      另请参阅:
    • MASK_AUTO_LISTEN_CANCEL

      public static final int MASK_AUTO_LISTEN_CANCEL
      另请参阅:
    • MASK_AUTO_RESET_CHILDREN

      public static final int MASK_AUTO_RESET_CHILDREN
      另请参阅:
    • MASK_CONTROL_FLOW_FLAGS

      public static final int MASK_CONTROL_FLOW_FLAGS
      另请参阅:
    • blackboard

      protected transient T blackboard
      任务运行时依赖的黑板(主要上下文) 1.每个任务可有独立的黑板(数据); 2.运行时不能为null; 3.如果是自动继承的,exit后自动删除;如果是Control赋值的,则由control删除。
    • cancelToken

      protected transient ICancelToken cancelToken
      取消令牌(取消上下文) 1.每个任务可有独立的取消信号; 2.运行时不能为null; 3.如果是自动继承的,exit后自动删除;如果是Control赋值的,则由control删除。
    • sharedProps

      protected transient Object sharedProps
      共享属性(配置上下文) 1.用于解决【数据和行为分离】架构下的配置需求,主要解决策划的配置问题,减少维护工作量。 2.共享属性应该在运行前赋值,不应该也不能被序列化。 3.共享属性应该是只读的、可共享的,因为它是配置。 4.如果是自动继承的,exit后自动删除;如果是Control赋值的,则由control删除。

      举个例子:部分项目的角色技能是有等级的,且数值不是根据等级计算的,而是一级一级配置的, 那么每一级的数值就是props,技能流程就是task。

    • flags

      protected int flags
      任务的自定义标识 1.对任务进行标记是一个常见的需求,我们将其定义在顶层以简化使用 2.在运行期间不应该变动 3.高8位为流程控制特征值,会在任务运行前拷贝到ctl -- 以支持在编辑器导出文件中指定。
  • 构造器详细资料

    • Task

      public Task()
  • 方法详细资料

    • getTaskEntry

      public final TaskEntry<T> getTaskEntry()
    • getControl

      public final Task<T> getControl()
    • getBlackboard

      public final T getBlackboard()
    • setBlackboard

      public final void setBlackboard(T blackboard)
    • getCancelToken

      public final ICancelToken getCancelToken()
    • setCancelToken

      public final void setCancelToken(ICancelToken cancelToken)
    • getControlData

      public final Object getControlData()
    • setControlData

      public final void setControlData(Object controlData)
    • getSharedProps

      public final Object getSharedProps()
    • setSharedProps

      public final void setSharedProps(Object sharedProps)
    • getEnterFrame

      public final int getEnterFrame()
    • getExitFrame

      public final int getExitFrame()
    • setEnterFrame

      public void setEnterFrame(int enterFrame)
      慎重调用
    • setExitFrame

      public void setExitFrame(int exitFrame)
      慎重调用
    • getStatus

      public final int getStatus()
      获取原始的状态码
    • getNormalizedStatus

      public final int getNormalizedStatus()
      获取归一化后的状态码,所有的失败码都转换为TaskStatus.ERROR
    • isRunning

      public final boolean isRunning()
      任务是否正在运行
    • isCompleted

      public final boolean isCompleted()
      任务是否已完成(成功、失败、取消)
    • isSucceeded

      public final boolean isSucceeded()
      任务是否已成功
    • isCancelled

      public final boolean isCancelled()
      任务是否已被取消
    • isFailed

      public final boolean isFailed()
      任务是否已失败
    • isFailedOrCancelled

      public final boolean isFailedOrCancelled()
      任务是否已失败或被取消
    • getEntity

      public Object getEntity()
      获取行为树绑定的实体 -- 最好让Entity也在黑板中
    • getEntryBlackboard

      public final T getEntryBlackboard()
      获取行为树入口绑定的黑板
    • getCurFrame

      public int getCurFrame()
      获取当前的帧号
    • getRunFrames

      public final int getRunFrames()
      运行的帧数 1.任务如果在首次execute()的时候就进入完成状态,那么运行帧数0 2.运行帧数是非常重要的统计属性,值得我们定义在顶层.
    • getPrevStatus

      public final int getPrevStatus()
      获取任务前一次的执行结果 1.取值范围[0,63] -- 其实只要能区分成功失败就够; 2.这并不是一个运行时必须的属性,而是为Debug和UI视图服务的;
    • setPrevStatus

      public final void setPrevStatus(int prevStatus)
    • beforeEnter

      protected void beforeEnter()
      该方法用于初始化对象。 1.不命名为init,是因为init通常让人觉得只调用一次。 2.该方法不可以使自身进入完成状态。
    • enter

      protected void enter(int reentryId)
      该方法在Task进入运行状态时执行 1.数据初始化需要放在beforeEnter()中,避免执行逻辑时对象未初始化完成。 2.如果要初始化子节点,也放到beforeEnter()方法; 3.允许更新自己为完成状态
      参数:
      reentryId - 用于判断父类是否使任务进入了完成状态;虽然也可先捕获再调用超类方法,但传入会方便许多。
    • execute

      protected abstract void execute()
      Task的心跳方法,在Task进入完成状态之前会反复执行。 1.可以根据isExecuteTriggeredByEnter()判断是否是与enter(int)连续执行的。 2.运行中可通过setSuccess()setFailed(int) ()}、setCancelled()将自己更新为完成状态。 3.不建议直接调用该方法,而是通过模板方法运行。
    • exit

      protected void exit()
      该方法在Task进入完成状态时执行 1.该方法与enter(int)对应,通常用于停止enter(int)中启动的逻辑。 2.该方法也用于清理部分运行时产生的临时数据。 3.一定记得取消注册的各种监听器。
    • setSuccess

      public final void setSuccess()
      设置为运行成功
    • setCancelled

      public final void setCancelled()
      设置为取消
    • setFailed

      public final void setFailed(int status)
      设置为执行失败 -- 兼容setGuardFailed(Task)
    • setGuardFailed

      public final void setGuardFailed(Task<T> control)
      设置为前置条件测试失败 1.该方法仅适用于control测试child的guard失败,令child在未运行的情况下直接失败的情况。 2.对于运行中的child,如果发现child的guard失败,不能继续运行,应当取消子节点的执行(stop)。
      参数:
      control - 由于task未运行,其control可能尚未赋值,因此要传入;传null可不接收通知
    • setCompleted

      public final void setCompleted(int status, boolean fromChild)
      设置为完成 -- 通常用于通过子节点的结果设置自己
    • onChildRunning

      protected abstract void onChildRunning(Task<T> child)
      子节点还需要继续运行 1.child在运行期间只会通知一次 2.该方法不应该触发状态迁移,即不应该使自己进入完成状态
    • onChildCompleted

      protected abstract void onChildCompleted(Task<T> child)
      子节点进入完成状态 1.避免方法数太多,实现类测试task的status即可 2.getNormalizedStatus()有助于switch测试 3.task可能是取消状态,甚至可能没运行过直接失败(前置条件失败) 4.钩子任务和guard不会调用该方法 5.isExecuting()有助于检测冲突,减少调用栈深度 6.同一子节点连续通知的情况下,completed的逻辑应当覆盖onChildRunning(Task)的影响。 7.任何的回调和事件方法中都由用户自身检测取消信号
    • onEvent

      public final void onEvent(@Nonnull Object event)
      Task收到外部事件
      另请参阅:
    • canHandleEvent

      public boolean canHandleEvent(@Nonnull Object event)
      该方法用于测试自己的状态和事件数据 如果通过条件Task来实现事件过滤,那么通常的写法如下:
           blackboard.set("event", event); // task通过黑板获取事件对象
           try {
               return template_checkGuard(eventFilter);
           } finally {
               blackboard.remove("event");
           }
       
      ps: 如果想支持编辑器中测试事件属性,event通常需要实现为KV结构。
    • onEventImpl

      protected abstract void onEventImpl(@Nonnull Object event)
      对于控制节点,通常将事件派发给约定的子节点或钩子节点。 对于叶子节点,通常自身处理事件。 注意: 1.转发事件时应该调用子节点的onEvent(Object)方法 2.在AI这样的领域中,建议将事件转化为信息存储在Task或黑板中,而不是尝试立即做出反应。 3.isExecuting()方法很重要
    • onCancelRequested

      public void onCancelRequested(ICancelToken cancelToken)
      取消令牌的回调方法 注意:如果未启动自动监听,手动监听时也建议绑定到该方法
      指定者:
      onCancelRequested 在接口中 ICancelTokenListener
      参数:
      cancelToken - 收到取消信号的令牌
    • stop

      public final void stop()
      强制停止任务 1.只应该由Control调用,因此不会通知Control 2.未完成的任务默认会进入Cancelled状态 3.不命名为cancel,否则容易误用;我们设计的cancel是协作式的,可通过cancelToken发出请求请求。
    • stopRunningChildren

      protected void stopRunningChildren()
      停止所有运行中的子节点 1.该方法在自身的exit之前调用 2.如果有特殊的子节点(钩子任务),也需要在这里停止
    • resetForRestart

      public void resetForRestart()
      重置任务以便重新启动(清理运行产生的所有临时数据)

      1. 和exit一样,清理的是运行时产生的临时数据,而不是所有数据;不过该方法是比exit更彻底的清理。 2. 钩子任务也应当被重置。 3. 与beforeEnter()相同,重写方法时,应先执行父类逻辑,再重置自身属性。 4. 有临时数据的Task都应该重写该方法,行为树通常是需要反复执行的。

    • resetChildrenForRestart

      protected void resetChildrenForRestart()
      重置所有的子节点 1.如果有需要重置的特殊子节点,可以重写该方法以确保无遗漏
    • checkCancel

      public final boolean checkCancel(int rid)
      检查取消
      参数:
      rid - 重入id;方法保存的局部变量
      返回:
      任务是否已进入完成状态;如果返回true,调用者应立即退出
      另请参阅:
    • isExecuting

      protected final boolean isExecuting()
      是否正在执行execute()方法 该方法非常重要,主要处理心跳和事件方法之间的冲突。 利用得当可大幅降低代码复杂度,减少调用栈深度,提高性能。
    • isExited

      public final boolean isExited(int rid)
      重入id对应的任务是否已退出,即:是否已执行exit()方法。 1.如果已退出,当前逻辑应该立即退出。 2.通常在执行外部代码后都应该检测,eg:运行子节点,派发事件,执行用户钩子... 3.通常循环体中的代码应该调用checkCancel(int) 4.也可以用于检测是否已重新启动
      参数:
      rid - 重入id;方法保存的局部变量
      返回:
      重入id对应的任务是否已退出
    • isStillborn

      public final boolean isStillborn()
      任务是否未启动就失败了。常见原因: 1. 前置条件失败 2. 任务开始前检测到取消
    • getReentryId

      public final int getReentryId()
      获取重入id 1.重入id用于解决事件(或外部逻辑)可能使当前Task进入完成状态的问题。 2.如果执行的外部逻辑可能触发状态切换,在执行外部逻辑前最好捕获重入id,再执行外部逻辑后以检查是否可进行运行。
    • isReentered

      public final boolean isReentered(int rid)
      查询任务是否已被重入 1.若任务已经重入,则表示产生了递归执行 2.若任务未被重入,则可能正在运行或已结束
    • isExecuteTriggeredByEnter

      public final boolean isExecuteTriggeredByEnter()
      execute方法是否是enter触发的 1.用于execute()方法判断当前是否和enter(int)在同一帧,以决定是否执行某些逻辑。 2.如果仅仅是想在下一帧运行execute()的逻辑,可通过setSlowStart(boolean) 实现。 3.部分Task的execute()可能在一帧内执行多次,因此不能通过运行帧数为0代替。
    • isExitTriggeredByStop

      public final boolean isExitTriggeredByStop()
      exit方法是否是由stop()方法触发的
    • isNotified

      public final boolean isNotified()
      是否已通知父节点完成。 注意:该接口主要是为Debug和UI展示设计的,业务通常不需要使用它。
    • setAutoCheckCancel

      public final void setAutoCheckCancel(boolean enable)
      告知模板方法是否自动检测取消 1.默认值由flags中的信息指定,默认自动检测 2.自动检测取消信号是一个动态的属性,可随时更改 -- 因此不要轻易缓存。
    • isAutoCheckCancel

      public final boolean isAutoCheckCancel()
    • setAutoListenCancel

      public final void setAutoListenCancel(boolean enable)
      告知模板方法是否自动监听取消事件 1.默认值由flags中的信息指定,默认不自动监听!自动监听有较大的开销,绝大多数业务只需要在Entry监听。 2.要覆盖默认值应当在beforeEnter()方法中调用
    • isAutoListenCancel

      public final boolean isAutoListenCancel()
    • setSlowStart

      public final void setSlowStart(boolean disable)
      告知模板方法否将enter(int)execute()方法分开执行。 1.默认值由flags中的信息指定,默认不分开执行 2.要覆盖默认值应当在beforeEnter()方法中调用 3.该属性运行期间不应该调整,调整也无效
    • isSlowStart

      public final boolean isSlowStart()
    • setAutoResetChildren

      public final void setAutoResetChildren(boolean enable)
      告知模板方法是否在beforeEnter()前自动调用resetChildrenForRestart() 1.默认值由flags中的信息指定,默认不启用 2.要覆盖默认值应当在beforeEnter()方法中调用 3.部分任务可能在调用resetForRestart()之前不会再次运行,因此需要该特性
    • isAutoResetChildren

      public final boolean isAutoResetChildren()
    • setDisableDelayNotify

      public final void setDisableDelayNotify(boolean disable)
      是否禁用延迟通知 1.默认值由flags中的信息指定,默认不禁用(即默认延迟通知) 2.要覆盖默认值应当在beforeEnter()方法中调用 3.用于解决事件驱动模式下调用栈深度问题 -- 类似尾递归优化,可减少一半栈深度 4.先更新自己为完成状态,再通知父节点,这有时候非常有用 -- 在状态机中,你的State可以感知自己是成功或是失败。 5.该属性运行期间不应该调整

      理论基础:99.99% 的情况下,Task在调用 setRunning 等方法后会立即return,那么在当前方法退出后再通知父节点就不会破坏时序。

    • isDisableDelayNotify

      public final boolean isDisableDelayNotify()
    • template_execute

      public final void template_execute()
      execute模板方法 注: 1.如果想减少方法调用,对于运行中的子节点,可直接调用子节点的模板方法。 2.该方法在Task完成前不可以递归执行,如果在正在执行的情况下想执行execute()方法,就直接调用。
    • template_runChild

      public final void template_runChild(Task<T> child)
      运行子节点,会检查子节点的前置条件
      参数:
      child - 普通子节点,或需要接收通知的钩子任务
    • template_runChildDirectly

      public final void template_runChildDirectly(Task<T> child)
      运行子节点,不检查子节点的前置条件
    • template_runHook

      public final void template_runHook(Task<T> hook)
      执行钩子任务,会检查前置条件 1.钩子任务不会触发onChildRunning(Task)onChildCompleted(Task) 2.前置条件其实是特殊的钩子任务
      参数:
      hook - 钩子任务,或不需要接收事件通知的子节点
    • template_runHookDirectly

      public final void template_runHookDirectly(Task<T> hook)
      执行钩子任务,不检查前置条件
    • template_checkGuard

      public final boolean template_checkGuard(@Nullable Task<T> guard)
      检查前置条件 1.如果未显式设置guard的上下文,会默认捕获当前Task的上下文 2.guard的上下文在运行结束后会被清理 3.guard只应该依赖共享上下文(黑板和props),不应当对父节点做任何的假设。 4.guard永远是检查当前Task的上下文,子节点的guard也不例外。 5.guard通常不应该修改数据
      参数:
      guard - 前置条件;可以是子节点的guard属性,也可以是条件子节点,也可以是外部的条件节点
    • setControl

      public final void setControl(Task<T> control)
      设置任务的控制节点
    • unsetControl

      public final void unsetControl()
      删除任务的控制节点(用于清理) 该方法在任务结束时并不会自动调用,因为Task上的数据可能是有用的,不能立即删除,只有用户知道是否可以清理。
    • addChild

      public final int addChild(Task<T> task)
      1.尽量不要在运行时增删子节点(危险操作) 2.不建议将Task从一棵树转移到另一棵树,可能产生内存泄漏(引用未删除干净) 3.如果需要知道task的索引,可提前调用getChildCount()
      参数:
      task - 要添加的子节点
      返回:
      child index
    • setChild

      public final Task<T> setChild(int index, Task<T> newTask)
      替换指定索引位置的child (该方法可避免Task的结构发生变化,也可以减少事件数)
      返回:
      index对应的旧节点
    • removeChild

      public final boolean removeChild(Task<?> task)
    • removeChild

      public final Task<T> removeChild(int index)
      删除指定索引的child
    • removeAllChild

      public void removeAllChild()
      删除所有的child -- 不是个常用方法
    • indexChild

      public int indexChild(Task<?> task)
      返回:
      index or -1
    • childStream

      public abstract Stream<Task<T>> childStream()
      该接口主要用于测试,该接口有一定的开销
    • getChildCount

      public abstract int getChildCount()
      子节点的数量(仅包括普通意义上的child,不包括钩子任务)
    • getChild

      public abstract Task<T> getChild(int index)
      获取指定索引的child
    • addChildImpl

      protected abstract int addChildImpl(Task<T> task)
      返回:
      为child分配的index
    • setChildImpl

      protected abstract Task<T> setChildImpl(int index, Task<T> task)
      返回:
      索引位置旧的child
    • removeChildImpl

      protected abstract Task<T> removeChildImpl(int index)
      返回:
      index对应的child
    • lock

      public final void lock(int lockId)
      进行互斥 1.该锁是简单的互斥锁,不支持重入。 2.底层会在exit的时候清理数据,不会影响下次运行。
      参数:
      lockId - 锁id,范围 [1 ~ 4]
    • tryLock

      public final boolean tryLock(int lockId)
    • unlock

      public final void unlock(int lockId)
    • isLocked

      public final boolean isLocked(int lockId)
    • stop

      public static void stop(@Nullable Task<?> task)
    • resetForRestart

      public static void resetForRestart(@Nullable Task<?> task)
    • getGuard

      public final Task<T> getGuard()
    • setGuard

      public final Task<T> setGuard(Task<T> guard)
    • getFlags

      public final int getFlags()
    • setFlags

      public final Task<T> setFlags(int flags)