UNPKG

blueshell

Version:

A Behavior Tree implementation in modern Javascript

70 lines (63 loc) 1.98 kB
/** * Created by masdoorian on 06/23/21 */ import { IfElse } from './IfElse'; import { BlueshellState, ResultCode, rc, BaseNode, Conditional } from '../models'; const LATCHED_RUNNING_CONSEQUENT = 0; const LATCHED_RUNNING_ALTERNATIVE = 1; /** * Latched If-Else Latched Composite Node. * * The conditional function is not called if the previous result was RUNNING - instead * the saved result of calling the conditional is used until the consequent/alternative * returns not RUNNING again and the state is reset * * If `conditional(state: S, event: E)` returns true, * control is passed to the consequent node. * * If `conditional(state: S, event: E)` returns false, * control is passed to the alternative node, or * if alternative is a result code, that is returned, or * if one is not provided, 'FAILURE' is returned. * * 06/23/21 * @author Mark Asdoorian */ export class LatchedIfElse<S extends BlueshellState, E> extends IfElse<S, E> { constructor( name: string, private conditionalToLatch: Conditional<S, E>, consequent: BaseNode<S, E>, alternative?: BaseNode<S, E> | ResultCode, ) { super( name, (state: S, event: E) => { const storage = this.getNodeStorage(state); let res: boolean; if (storage.running === undefined) { // we're not latched, so run the conditional and save the result res = this.conditionalToLatch(state, event); storage.running = res ? LATCHED_RUNNING_CONSEQUENT : LATCHED_RUNNING_ALTERNATIVE; } else { // we're latched, so return the saved result of the conditional res = storage.running === LATCHED_RUNNING_CONSEQUENT; } return res; }, consequent, alternative, ); } get latched() { return true; } protected _afterEvent(res: ResultCode, state: S, event: E): ResultCode { res = super._afterEvent(res, state, event); if (res !== rc.RUNNING) { const storage = this.getNodeStorage(state); storage.running = undefined; } return res; } }