@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
104 lines (78 loc) • 3.02 kB
JavaScript
import { assert } from "../../../../core/assert.js";
import { Behavior } from "../Behavior.js";
import { BehaviorStatus } from "../BehaviorStatus.js";
import { SucceedingBehavior } from "../primitive/SucceedingBehavior.js";
/**
* Utility behavior that works just like an IF/ELSE statement
* If you are not sure if this is the right behavior for your use-case, consider using a selector behavior instead,
* as selector is a more commonly applicable behavior type
* @author Alex Goldring
* @copyright Company Named Limited (c) 2025
*/
export class BranchBehavior extends Behavior {
#branch_success = SucceedingBehavior.INSTANCE
#branch_failure = SucceedingBehavior.INSTANCE
#condition = SucceedingBehavior.INSTANCE
/**
*
* @type {Behavior|null}
*/
#current = null;
/**
*
* @param {Behavior} condition
* @param {Behavior} [branch_success]
* @param {Behavior} [branch_failure]
*/
static from(
condition,
branch_success = SucceedingBehavior.INSTANCE,
branch_failure = SucceedingBehavior.INSTANCE
) {
assert.defined(condition, 'condition');
assert.notNull(condition, 'condition');
assert.equal(condition.isBehavior, true, 'condition.isBehavior !== true');
assert.defined(branch_success, 'branch_success');
assert.notNull(branch_success, 'branch_success');
assert.equal(branch_success.isBehavior, true, 'branch_success.isBehavior !== true');
assert.defined(branch_failure, 'branch_failure');
assert.notNull(branch_failure, 'branch_failure');
assert.equal(branch_failure.isBehavior, true, 'branch_failure.isBehavior !== true');
const r = new BranchBehavior();
r.#condition = condition;
r.#branch_success = branch_success;
r.#branch_failure = branch_failure;
return r;
}
initialize(context) {
super.initialize(context);
this.#current = this.#condition;
this.#current.initialize(context);
}
tick(timeDelta) {
const s = this.#current.tick(timeDelta);
if (s !== BehaviorStatus.Succeeded && s !== BehaviorStatus.Failed) {
// current behavior was not resolved, continue
return s;
}
if (this.#current !== this.#condition) {
// underlying branch was resolved
return s;
}
// condition was resolved, move onto a branch
this.#current.finalize();
if (s === BehaviorStatus.Succeeded) {
this.#current = this.#branch_success;
} else {
this.#current = this.#branch_failure;
}
this.#current.initialize(this.context);
return this.#current.tick(timeDelta);
}
finalize() {
super.finalize();
if (this.#current !== null) {
this.#current.finalize()
}
}
}