diff --git a/.circleci/config.yml b/.circleci/config.yml index df4b963..b38c134 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -73,5 +73,6 @@ workflows: requires: - setup - publish: + context: 6rs-public-npm requires: - test diff --git a/lib/index.ts b/lib/index.ts index 51b3d18..3ae0b70 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -10,6 +10,7 @@ export {LatchedSelector} from './nodes/LatchedSelector'; export {LatchedSequence} from './nodes/LatchedSequence'; export {IfElse} from './nodes/IfElse'; export {resultCodes, ResultCode} from './utils/resultCodes'; +export {TreePublisher} from './utils/TreePublisher'; import * as decorators from './nodes/decorators'; diff --git a/lib/nodes/Base.ts b/lib/nodes/Base.ts index 99bcd2a..a1c7679 100644 --- a/lib/nodes/Base.ts +++ b/lib/nodes/Base.ts @@ -3,6 +3,8 @@ */ import {BlueshellState} from './BlueshellState'; import {resultCodes as rc, ResultCode} from '../utils/resultCodes'; +import {TreePublisher, TreeNonPublisher} from '../utils/TreePublisher'; + /** * Base class of all Nodes. @@ -11,6 +13,17 @@ import {resultCodes as rc, ResultCode} from '../utils/resultCodes'; export class Base { private _parent: string; + // Hard to properly type this since the static can't + // inherit the types from this generic class. This static is + // here because it's difficult to inject this functionality + // into blueshell in the current form, but this is maybe + // marginally better than a global + static treePublisher: TreePublisher = new TreeNonPublisher(); + + public static registerTreePublisher(publisher: TreePublisher): void { + Base.treePublisher = publisher; + } + /** * @constructor * @param name The name of the Node. If no name is given, the name of the Class will be used. @@ -38,8 +51,8 @@ export class Base { } try { + Base.treePublisher.publishResult(state, event, false); const result = this.onEvent(state, event); - return this._afterEvent(result, state, event); } catch (err) { state.errorReason = err; diff --git a/lib/utils/TreePublisher.ts b/lib/utils/TreePublisher.ts new file mode 100644 index 0000000..c1f24ad --- /dev/null +++ b/lib/utils/TreePublisher.ts @@ -0,0 +1,13 @@ +import {BlueshellState} from '../nodes/BlueshellState'; + +export interface TreePublisher { + publishResult(state: B, event: V, topLevel: boolean): void; + configure(options: object): void; +} + +export class TreeNonPublisher implements TreePublisher { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + publishResult(_state: BlueshellState, _event: any, _topLevel: boolean) {} + // eslint-disable-next-line @typescript-eslint/no-unused-vars + configure(_options: object) {} +} diff --git a/test/nodes/Base.test.ts b/test/nodes/Base.test.ts index 038cabd..67eb380 100644 --- a/test/nodes/Base.test.ts +++ b/test/nodes/Base.test.ts @@ -5,6 +5,7 @@ import {assert} from 'chai'; import * as Behavior from '../../lib'; import {BlueshellState} from '../../lib/nodes/BlueshellState'; import {resultCodes as rc} from '../../lib/utils/resultCodes'; +import {TreeNonPublisher} from '../../lib/utils/TreePublisher'; const Base = Behavior.Action; const Decorator = Behavior.Decorator; @@ -118,4 +119,29 @@ describe('Base', function() { assert.equal(child.getLastEventSeen(state), 2, 'last event seen should be updated'); }); }); + + describe('publisher', function() { + it('Has a non publisher by default', function() { + assert.isTrue(Base.treePublisher instanceof TreeNonPublisher); + }); + + it('We can make a publisher', function() { + const action = new TestAction(); + let published = false; + const publisher = { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + publishResult(_state: any, _event: any, _topLevel: boolean) { + published = true; + }, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + configure(_options: object) {}, + } as Behavior.TreePublisher; + + Base.registerTreePublisher(publisher); + const res = action.handleEvent(new TestState(), 'testEvent'); + + assert.equal(res, rc.SUCCESS); + assert.isTrue(published); + }); + }); });