Skip to content

Commit

Permalink
Added Race node
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikolas Howard committed Mar 11, 2024
1 parent 3b21c3b commit 1bcf90f
Show file tree
Hide file tree
Showing 13 changed files with 513 additions and 12 deletions.
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ root {
```

### Parallel
This composite node will update each child node concurrently. It will move to the `SUCCEEDED` state if all of its children have moved to the `SUCCEEDED` state and will move to the `FAILED` state if any of its children move to the `FAILED` state. This node will remain in the `RUNNING` state if any of its children are in the `RUNNING` state.
This composite node will update each child node concurrently. It will move to the `SUCCEEDED` state if all of its children have moved to the `SUCCEEDED` state and will move to the `FAILED` state if any of its children move to the `FAILED` state, otherwise it will remain in the `RUNNING` state.
[Example](https://nikkorn.github.io/mistreevous-visualiser/index.html?example=parallel)

*MDSL*
Expand Down Expand Up @@ -205,6 +205,40 @@ root {
}
```

### Race
This composite node will update each child node concurrently. It will move to the `SUCCEEDED` state if any of its children have moved to the `SUCCEEDED` state and will move to the `FAILED` state if all of its children move to the `FAILED` state, otherwise it will remain in the `RUNNING` state.
[Example](https://nikkorn.github.io/mistreevous-visualiser/index.html?example=race)

*MDSL*
```
root {
race {
action [UnlockDoor]
action [FindAlternativePath]
}
}
```

*JSON*
```json
{
"type": "root",
"child": {
"type": "race",
"children": [
{
"type": "action",
"call": "UnlockDoor"
},
{
"type": "action",
"call": "FindAlternativePath"
}
]
}
}
```

### Lotto
This composite node will select a single child at random to run as the active running node. The state of this node will reflect the state of the active child.
[Example](https://nikkorn.github.io/mistreevous-visualiser/index.html?example=lotto)
Expand Down
11 changes: 10 additions & 1 deletion dist/BehaviourTreeDefinition.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ export interface ParallelNodeDefinition extends CompositeNodeDefinition {
*/
type: "parallel";
}
/**
* A race node.
*/
export interface RaceNodeDefinition extends CompositeNodeDefinition {
/**
* The node type.
*/
type: "race";
}
/**
* A root node.
*/
Expand Down Expand Up @@ -227,7 +236,7 @@ export interface FailNodeDefinition extends DecoratorNodeDefinition {
/**
* A type defining any node definition.
*/
export type AnyNodeDefinition = BranchNodeDefinition | ActionNodeDefinition | ConditionNodeDefinition | WaitNodeDefinition | SequenceNodeDefinition | SelectorNodeDefinition | LottoNodeDefinition | ParallelNodeDefinition | RootNodeDefinition | RepeatNodeDefinition | RetryNodeDefinition | FlipNodeDefinition | SucceedNodeDefinition | FailNodeDefinition;
export type AnyNodeDefinition = BranchNodeDefinition | ActionNodeDefinition | ConditionNodeDefinition | WaitNodeDefinition | SequenceNodeDefinition | SelectorNodeDefinition | LottoNodeDefinition | ParallelNodeDefinition | RaceNodeDefinition | RootNodeDefinition | RepeatNodeDefinition | RetryNodeDefinition | FlipNodeDefinition | SucceedNodeDefinition | FailNodeDefinition;
/**
* A type defining any node type that can be a child of composite parent node.
*/
Expand Down
61 changes: 60 additions & 1 deletion dist/bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions dist/bundle.js.map

Large diffs are not rendered by default.

61 changes: 60 additions & 1 deletion dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions dist/index.js.map

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions src/BehaviourTreeBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Node from "./nodes/Node";
import Composite from "./nodes/composite/Composite";
import Decorator from "./nodes/decorator/Decorator";
import Parallel from "./nodes/composite/Parallel";
import Race from "./nodes/composite/Race";
import Selector from "./nodes/composite/Selector";
import Sequence from "./nodes/composite/Sequence";
import Lotto from "./nodes/composite/Lotto";
Expand Down Expand Up @@ -38,6 +39,7 @@ type AnyNode =
| Selector
| Lotto
| Parallel
| Race
| Repeat
| Retry
| Flip
Expand Down Expand Up @@ -163,6 +165,12 @@ function nodeFactory(definition: AnyNodeDefinition, rootNodeDefinitionMap: RootN
definition.children.map((child) => nodeFactory(child, rootNodeDefinitionMap))
);

case "race":
return new Race(
attributes,
definition.children.map((child) => nodeFactory(child, rootNodeDefinitionMap))
);

case "lotto":
return new Lotto(
attributes,
Expand Down
11 changes: 11 additions & 0 deletions src/BehaviourTreeDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,16 @@ export interface ParallelNodeDefinition extends CompositeNodeDefinition {
type: "parallel";
}

/**
* A race node.
*/
export interface RaceNodeDefinition extends CompositeNodeDefinition {
/**
* The node type.
*/
type: "race";
}

/**
* A root node.
*/
Expand Down Expand Up @@ -254,6 +264,7 @@ export type AnyNodeDefinition =
| SelectorNodeDefinition
| LottoNodeDefinition
| ParallelNodeDefinition
| RaceNodeDefinition
| RootNodeDefinition
| RepeatNodeDefinition
| RetryNodeDefinition
Expand Down
2 changes: 1 addition & 1 deletion src/BehaviourTreeDefinitionUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function isDecoratorNode(node: NodeDefinition): node is DecoratorNodeDefi
* @returns A value of true if the specified node satisfies the CompositeNodeDefinition type.
*/
export function isCompositeNode(node: NodeDefinition): node is CompositeNodeDefinition {
return ["sequence", "selector", "lotto", "parallel"].includes(node.type);
return ["sequence", "selector", "lotto", "parallel", "race"].includes(node.type);
}

/**
Expand Down
27 changes: 27 additions & 0 deletions src/BehaviourTreeDefinitionValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,10 @@ function validateNode(definition: any, depth: number): void {
validateParallelNode(definition, depth);
break;

case "race":
validateRaceNode(definition, depth);
break;

case "lotto":
validateLottoNode(definition, depth);
break;
Expand Down Expand Up @@ -774,6 +778,29 @@ function validateParallelNode(definition: any, depth: number): void {
definition.children.forEach((child: any) => validateNode(child, depth + 1));
}

/**
* Validate an object that we expect to be a race node definition.
* @param definition An object that we expect to be a race node definition.
* @param depth The depth of the node in the definition tree.
*/
function validateRaceNode(definition: any, depth: number): void {
// Check that the node type is correct.
if (definition.type !== "race") {
throw new Error(`expected node type of 'race' for race node at depth '${depth}'`);
}

// A race node is a composite node, so must have a children nodes array defined.
if (!Array.isArray(definition.children) || definition.children.length === 0) {
throw new Error(`expected non-empty 'children' array to be defined for race node at depth '${depth}'`);
}

// Validate the node attributes.
validateNodeAttributes(definition, depth);

// Validate the child nodes of this composite node.
definition.children.forEach((child: any) => validateNode(child, depth + 1));
}

/**
* Validate an object that we expect to be a lotto node definition.
* @param definition An object that we expect to be a lotto node definition.
Expand Down
Loading

0 comments on commit 1bcf90f

Please sign in to comment.