phaser3-rex-plugins
Version:
193 lines (159 loc) • 6.5 kB
JavaScript
import { Sequence, Selector, If, Succeeder, RepeatUntilFailure, Abort, Failer } from '../../../behaviortree';
import GetNodeType from './GetNodeType.js';
import GetConditionExpression from './GetConditionExpression';
import ParseProperty from './ParseProperty';
import TaskSequence from '../../eventsheetmanager/tree/TaskSequence.js';
import TaskAction from '../../eventsheetmanager/tree/TaskAction.js';
var TypeNames = ['if', 'else', 'while'];
var CreateTaskSequence = function (node, config) {
if (Array.isArray(node)) {
var nodes = node;
if (nodes.length === 1) {
return CreateTaskSequence(nodes[0], config);
} else {
var sequence = new Sequence({ title: '[root]' });
var lastIfSelector;
for (var i = 0, cnt = nodes.length; i < cnt; i++) {
var node = nodes[i];
var child = CreateTaskSequence(node, config);
// Construct if-branch selector
switch (child.title) {
case '[if]':
sequence.addChild(child);
lastIfSelector = child;
break;
case '[else]':
if (lastIfSelector) {
lastIfSelector.insertChild(child, null, -1);
} else {
// No [If] heading before this [else] heading
console.warn(`Can't find [If] heading before '${node.title}'`);
}
break;
default: // Normal tasks
sequence.addChild(child);
lastIfSelector = null;
break;
}
}
return sequence;
}
} else {
var nodeType = GetNodeType(node, TypeNames);
switch (nodeType) {
case 'if':
var selector = new Selector({
title: '[if]'
});
var ifDecorator = new If({
expression: GetConditionExpression(node)
});
ifDecorator.addChild(CreateTaskSequence(node.children, config));
selector.addChild(ifDecorator)
var succeeder = new Succeeder();
selector.addChild(succeeder);
return selector;
case 'else':
var ifDecorator = new If({
title: '[else]',
expression: GetConditionExpression(node)
});
ifDecorator.addChild(CreateTaskSequence(node.children, config));
return ifDecorator;
case 'while':
var whileDecorator = new RepeatUntilFailure({
title: '[while]',
returnSuccess: true,
})
var ifDecorator = new If({
title: '[while]',
expression: GetConditionExpression(node)
});
ifDecorator.addChild(CreateTaskSequence(node.children, config));
whileDecorator.addChild(ifDecorator);
return whileDecorator;
default:
var sequence = new TaskSequence({ title: node.title });
var paragraphs = node.paragraphs; // paragraphs -> TaskAction[]
for (var i = 0, cnt = paragraphs.length; i < cnt; i++) {
var commandData = GetCommandData(paragraphs[i], config);
if (!commandData) {
continue;
}
var commandType = commandData.type;
delete commandData.type;
var actionNode;
switch (commandType) {
case 'exit':
actionNode = new Abort({ title: '[exit]' });
break;
case 'break':
actionNode = new Failer({ title: '[break]' });
break;
default:
actionNode = new TaskAction(commandData);
break;
}
sequence.addChild(actionNode);
}
return sequence;
}
}
}
var GetCommandData = function (paragraph, config) {
var commandData;
if (paragraph.hasOwnProperty('block')) {
commandData = ParseCommandString(paragraph.block, ',', config);
commandData.parameters.text = paragraph.text;
} else {
commandData = ParseCommandString(paragraph.text, '\n', config);
}
return commandData;
}
var ParseCommandString = function (commandString, delimiter, {
lineBreak = '\\',
commentLineStart = '\/\/',
} = {}) {
var lines = commandString.split(delimiter);
if (delimiter === '\n') {
// Discard comment lines
lines = lines.filter(function (line) {
return !line.trimLeft().startsWith(commentLineStart);
})
if (lines.length === 0) {
return null;
} else if (lines.length === 1) {
var line = lines[0];
if (IsExitCommand(line)) {
return { type: 'exit' };
} else if (IsBreakLabelCommand(line)) {
return { type: 'break' };
} else if (line.indexOf(',') !== -1) {
lines = commandString.split(',');
}
}
}
var commandData = {
type: 'task',
name: TrimString(lines[0], lineBreak),
parameters: {}
};
var parameters = commandData.parameters;
for (var i = 1, cnt = lines.length; i < cnt; i++) {
ParseProperty(TrimString(lines[i], lineBreak), parameters);
}
return commandData;
}
var TrimString = function (s, lineBreak) {
if (lineBreak && (s.at(-1) === lineBreak)) {
s = s.substring(0, s.length - 1);
}
return s.trimLeft();
}
var IsExitCommand = function (s) {
return s.trim().toLowerCase() === '[exit]';
}
var IsBreakLabelCommand = function (s) {
return s.trim().toLowerCase() === '[break]';
}
export default CreateTaskSequence;