private TaskNode MakeNode(StreamReader sr, bool concurrent) { TaskNode p; if (DebugPrinting) { form1.WriteAI("DEBUG: New TaskNode is " + ((concurrent) ? "concurrent" : "not concurrent")); } //read in the information for the encountered node (storing in temp vars) //currently sr is right after the "[" #region read_postfix //scan up to a ] meaning we copied in the postfix expression char[] buffer = new char[MAX_STRING_BUFFER_SIZE]; char[] delims = { ']' }; if (!ReadUpTo(sr, buffer, delims)) { form1.WriteAI("ERROR: Overran buffer in search for ']'"); return(null); } String postfix = new String(buffer); postfix = postfix.Trim(); if (DebugPrinting) { form1.WriteAI("DEBUG: Created priority expression string \"" + postfix + "\""); } #endregion //move over the ] sr.Read(); #region read_name //scan up to a ! or a { (so that we'll skip over and record a name) char[] delims2 = { '!', '{' }; if (!ReadUpTo(sr, buffer, delims2)) { form1.WriteAI("ERROR: Overran buffer in search for '!' or '{'"); return(null); } String name = new String(buffer); name = name.Trim(); if (DebugPrinting) { form1.WriteAI("DEBUG: Created name \"" + name + "\""); } #endregion char next = (char)sr.Read(); //if encountered a block start "{" if (next == '{') { #region make_subtask if (DebugPrinting) { form1.WriteAI("DEBUG: Found a '{', calling ParseLevel for new parent \"" + name + "\""); } //make p a new subtask (handle exception) try { p = new Subtask(name, this, postfix); } catch (InvalidOperationException) { form1.WriteAI("ERROR: Failed to construct FunctionNode \"" + name + "\" with given postfix expression"); return(null); } //call ParseLevel with parent node p if (!ParseLevel((Subtask)p, sr)) { return(null); } //make sure "}" termination if (DebugPrinting) { form1.WriteAI("DEBUG: Serching for '}' termination for \"" + name + "\""); } while ((char)sr.Read() != '}') { ; } if (DebugPrinting) { form1.WriteAI("DEBUG: Found '}' termination for Subtask, returning"); } #endregion } else if (next == '!') { #region make_function_node if (DebugPrinting) { form1.WriteAI("DEBUG: Found a '!', creating FunctionNode \"" + name + "\""); } // *[<postfix priority expression>] !<action>(<param>); #region read_FID char[] delims3 = { '(', ')' }; if (!ReadUpTo(sr, buffer, delims3)) { form1.WriteAI("ERROR: Overran buffer in search for '(' for \"" + name + "\""); return(null); } if (DebugPrinting) { form1.WriteAI("DEBUG: Read up to a '(' to get FID"); } String temp = new String(buffer); int functionId; if (!Int32.TryParse(temp, out functionId)) { form1.WriteAI("ERROR: Invalid FID \"" + temp + "\" in \"" + name + "\""); return(null); } if (DebugPrinting) { form1.WriteAI("DEBUG: Parsed FID into int \"" + functionId.ToString() + "\""); } #endregion //skip over '(' sr.Read(); #region read_param //get the param if (!ReadUpTo(sr, buffer, delims3)) { form1.WriteAI("ERROR: Overran buffer in search for ')' for \"" + name + "\""); return(null); } if (DebugPrinting) { form1.WriteAI("DEBUG: Read up to a ')' to get param"); } String param = new String(buffer); param = param.Trim(); if (DebugPrinting) { form1.WriteAI("DEBUG: Created parameter expression string \"" + param + "\""); } #endregion //make p a new function node (handle exception) try { p = new FunctionNode(this, name, functionId, param, this, postfix); } catch (InvalidOperationException) { form1.WriteAI("ERROR: Failed to construct FunctionNode \"" + name + "\" with given postfix expression"); return(null); } if (DebugPrinting) { form1.WriteAI("DEBUG: FunctionNode \"" + name + "\" created"); } //skip ')' sr.Read(); //make sure ";" termination if ((char)sr.Read() != ';') { form1.WriteAI("ERROR: Expected a ';' closing for \"" + name + "\""); return(null); } if (DebugPrinting) { form1.WriteAI("DEBUG: Found ';' termination for FunctionNode, returning"); } #endregion } else { form1.WriteAI("ERROR: Expected a block start '{' or FID '!' for \"" + name + "\""); return(null); } p.Concurrent = concurrent; return(p); }
//parses a Subtask's block of children and adds the children under Subtask private bool ParseLevel(Subtask parent, StreamReader sr) { if (DebugPrinting) { form1.WriteAI("DEBUG: Searching for child tasks in \"" + parent.ToString() + "\""); } char[] buffer = new char[1]; String temp; bool concurrent = false; //pass through every char until we reach something of interest (namely a child or >) while (sr.Peek() != -1 && (char)sr.Peek() != '}') { sr.Read(buffer, 0, 1); temp = new String(buffer); //decide what to do about the char read in switch (buffer[0]) { case '#': String comment = sr.ReadLine(); if (DebugPrinting) { form1.WriteAI("DEBUG: Skipping comment \"#" + comment + "\""); } if (comment.StartsWith("!")) { int t; if (Int32.TryParse(comment.Substring(1), out t)) { form1.setAIInterval(t); } form1.WriteAI("DEBUG: Setting AI Interval to " + t); } break; case '[': //makenode will move sr ahead to the next header in this block if (DebugPrinting) { form1.WriteAI("DEBUG: Encountered a child task in \"" + parent.ToString() + "\""); } TaskNode child = MakeNode(sr, concurrent); if (child == null) { form1.WriteAI("ERROR: Failed to create child task in \"" + parent.ToString() + "\""); return(false); } parent.children.Add(child); concurrent = false; break; case '*': concurrent = true; break; case '>': String path = form1.launchPath + "\\ai\\" + sr.ReadLine(); if (DebugPrinting) { form1.WriteAI("DEBUG: Including external file \"" + path + "\""); } FileStream fs; try { fs = File.Open(path, FileMode.Open); } catch (IOException) { form1.WriteAI("ERROR: Could not find included file \"" + path + "\""); return(false); } StreamReader tempStream = new StreamReader(fs); if (!ParseLevel(parent, tempStream)) { return(false); } break; default: if (DebugPrinting) { form1.WriteAI("DEBUG: Skipping character \"" + temp + "\""); form1.WriteAI("(" + ((int)(temp.ToCharArray()[0])).ToString() + ")"); } break; } } //for each char between things of interest //at the block ending char '}' return(true); }