public static BTProgram BuildProgram(BTLParser.Node[][] treeSets) { BTProgram program = new BTProgram(); int n = treeSets.Length; program._treeSets = new BTTree[n][]; program._codemaps = new CodeMap[n]; for (int i = 0; i < n; ++i) { program._treeSets[i] = Build(treeSets[i], out program._codemaps[i], true); } List <BTTree> trees = new List <BTTree>(); foreach (var set in program.treeSets) { trees.AddRange(set); } BTRuntimeBuilder.ResolveProxies(trees.ToArray()); return(program); }
private void DebugLogCompilationExceptions() { _exceptions = BTLAssetManager.GetCompilationExceptions(btSources); _pandaExceptions = null; _program = new BTProgram(pandaExceptions); if (Application.isPlaying) { DebugLogErrors(); } }
public static System.Exception[] CheckRootTree(BTProgram program) { var exceptions = new List <System.Exception>(); var treesSets = program.treeSets; int mainCount = 0; if (treesSets != null) { for (int i = 0; i < treesSets.Length; ++i) { var set = treesSets[i]; if (set != null) { for (int j = 0; j < set.Length; ++j) { var b = set[j]; if (b.name.ToLower() == "root") { ++mainCount; } } } } } if (mainCount == 0) { string msg = string.Format("No root tree found. tree \"Root\" is expected.\n"); exceptions.Add(new System.Exception(msg)); } if (mainCount > 1) { string msg = string.Format("Too many root trees found. Only one tree \"Root\" is expected.\n"); exceptions.Add(new System.Exception(msg)); } if (exceptions.Count > 0) { program._boundState = BoundState.Failed; program._codemaps = null; } return(exceptions.ToArray()); }
public void Tick() { BTProgram previous = BTProgram.current; BTProgram.current = this; if (main != null && boundState == BoundState.Bound) { ++_tickCount; main.Tick(); } else { if (!hasThrownExceptionOnTick) { BTProgram.current = previous; hasThrownExceptionOnTick = true; throw new System.Exception("Can not tick behaviour tree program. Program is invalid."); } } BTProgram.current = previous; }
public static BTProgram CreateBehaviourProgram(BTSource[] btlSources) { if (!isPandaInitialized) { InitializePanda(); isPandaInitialized = true; } BTProgram program = null; BTLParser.Node[][] nodeSets = null; var cache = Fetch(btlSources); var exceptions = cache.exceptions; // A program is correct when it does not contain any exceptions. bool isCorrect = true; foreach (var ex in exceptions) { if (ex != null) { isCorrect = false; break; } } if (isCorrect) { nodeSets = GetBTLRoots(btlSources); program = BTRuntimeBuilder.BuildProgram(nodeSets); } return(program); }
public void Reset() { BTProgram previous = BTProgram.current; BTProgram.current = this; if (treeSets != null) { foreach (var ts in treeSets) { if (ts == null) { continue; } foreach (var t in ts) { if (t != null) { t.Reset(); } } } } BTProgram.current = previous; }
public static SourceDisplay[] MapGUILines(BTSource[] btlSources, BTProgram program, PandaScriptException[] pandaExceptions) { if (btlSources == null || program == null) { return(null); } var sourceDisplays = new SourceDisplay[btlSources.Length]; for (int i = 0; i < btlSources.Length; i++) { if (btlSources[i] == null) { continue; } SourceDisplay sourceDisplay = null; var tokens = BTLAssetManager.GetBTLTokens(btlSources, btlSources[i]); sourceDisplay = BTLGUILine.Analyse(tokens, i); sourceDisplays[i] = sourceDisplay; CodeMap codemap = null; if (program.codemaps != null && i < program.codemaps.Length) { codemap = program.codemaps[i]; } if (codemap != null) { BTLGUILine.MapNodes(sourceDisplay.lines, codemap); var lines = sourceDisplay.flattenLines; foreach (var line in lines) { foreach (var n in line.btnodes) { var task = n as BTTask; if (task != null && task.boundState != BoundState.Bound) { line.hasErrors = true; } } } } if (sourceDisplay != null) { var lines = sourceDisplay.flattenLines; foreach (var line in lines) { foreach (var pandaException in pandaExceptions) { if (pandaException != null) { if (pandaException.filePath == btlSources[i].url && line.lineNumber == pandaException.lineNumber) { line.hasErrors = true; } } } } } } return(sourceDisplays); }
public static void Bind(BTProgram program, object[] implementers) { // Get all the [Task]s. var taskImplementations = TaskImplementation.Get(implementers); // Find for each task the corresponding implementations. var taskImplementationCandidates = new Dictionary <BTTask, List <TaskImplementation> >(); var tasks = program.tasks; foreach (var task in tasks) { taskImplementationCandidates[task] = new List <TaskImplementation>(); foreach (var ti in taskImplementations) { if (ti.IsMatch(task)) { taskImplementationCandidates[task].Add(ti); } } } // Check whether all the task are unambiguously defined. var unimplementedTasks = new List <BTTask>(); var over_implementedTasks = new List <BTTask>(); foreach (var kv in taskImplementationCandidates) { var task = kv.Key; var candidates = kv.Value; if (candidates.Count == 0) { unimplementedTasks.Add(task); } if (candidates.Count > 1) { over_implementedTasks.Add(task); } } // Generate eventual exceptions. var exceptions = new List <System.Exception>(); if (unimplementedTasks.Count > 0) { int line = 0; string path = null; foreach (var task in unimplementedTasks) { var m = GetMethodSignatureString(task); string msg = string.Format("The task `{0}' is not defined.\n", m); msg += string.Format("\nA method as follow is expected:\n"); string tpl = taskTpl; tpl = tpl.Replace("{!methodSignature}", m); tpl = tpl.Replace("{!statusType}", "Status"); msg += tpl; if (Locate(BehaviourTree._current, task, out path, out line)) { exceptions.Add(new PandaScriptException(msg, path, line)); } else { exceptions.Add(new System.NotImplementedException(msg)); } } } if (over_implementedTasks.Count > 0) { int line = 0; string path = null; foreach (var task in over_implementedTasks) { var m = GetMethodSignatureString(task); string msg = string.Format("The task `{0}' has too many definitions.\n", m); msg += string.Format("The task is implemented in:\n"); foreach (var o in taskImplementationCandidates[task]) { msg += string.Format(" - `{0}'\n", o.target.GetType().ToString()); } if (Locate(BehaviourTree._current, task, out path, out line)) { exceptions.Add(new PandaScriptException(msg, path, line)); } else { exceptions.Add(new System.Exception(msg)); } } } if (exceptions.Count == 0) { exceptions.AddRange(CheckRootTree(program)); } program._exceptions = exceptions.ToArray(); // Bind the tasks. foreach (var kv in taskImplementationCandidates) { var task = kv.Key; var candidates = kv.Value; if (candidates.Count == 1) { var ti = candidates[0]; Bind(task, ti); } else { task.Unbind(); } } }