/// <summary> /// Parses raw lines in to the system. /// </summary> private void parseScriptGroup(List<string> rawLines, string filePath, string fileKey, Logger fileLog) { // split-up the lines in to indatation based blocks. var group = new GroupInfo(filePath, fileKey, fileLog); scriptsLock.EnterWriteLock(); scriptGroups.Add(group); scriptsLock.ExitWriteLock(); var blocks = group.Blocks; int currentLine = 0; string blockKey = null; string[] blockTags = null; string[] blockResponses = null; int blockLine = 0; while (currentLine < rawLines.Count) { string str = rawLines[currentLine]; int indent = 0; fileLog.SetId(currentLine); if (parseCutLine(ref str, ref indent)) // line empty? { if (indent == 0) // indent 0 defines what the key of the upcoming object is. { List<string[]> args; parseBlockStart(str, out blockKey, out args, fileLog); blockTags = null; blockResponses = null; if (args.Count > 0) blockTags = KeyClean(args[0], fileLog); if (args.Count > 1) blockResponses = SanitizeInputReplace(args[1]); blockLine = currentLine; // make sure key is a valid type. var rootKey = KeySplit(blockKey)[0]; if (rootKey != "script" && rootKey != "list" && rootKey != "setup" && rootKey != "personality") { fileLog.Error(string.Format(StringsScripting.Formatted_Error_Invalid_root_type, rootKey), currentLine); break; } ++currentLine; } else if (indent > 0) { if (blockKey == null) { fileLog.Error(StringsScripting.Invalid_Indentation, currentLine); break; } var log = new Logger(fileKey + "." + blockKey); var lines = parseBlock(rawLines, ref currentLine, indent, log); if (lines == null) blocks.Add(new BlockBase(blockKey, null, blockTags, group, log)); else { // Figureout type of script, then add it. var keySplit = KeySplit(blockKey); if (keySplit.Length == 2) { if (keySplit[1] == null || keySplit[1].Length == 0) { fileLog.Warning(StringsScripting.Warning_Empty_sub_key); continue; } var key = fileKey + '.' + keySplit[1]; switch (keySplit[0]) { case "setup": scriptsLock.EnterWriteLock(); try { if (keySplit[1] == "controller") setupController.Add(new Script(this, false, blockKey, lines, blockTags, group, log)); else if (keySplit[1] == "personality") setupPersonality.Add(new Script(this, false, blockKey, lines, blockTags, group, log)); //else //ToDo : Error unknown setup type. } finally { scriptsLock.ExitWriteLock(); } // ToDo : Remove error from strings. //if (blockTags != null && blockTags.Length > 0) // fileLog.Warning(StringsScripting.Setup_has_tags, blockLine); // warn if has responses if (blockResponses != null && blockResponses.Length >= 0) fileLog.Warning(StringsScripting.Setup_has_responses, blockLine); break; case "script": case "list": { var script = new Script(this, keySplit[0] == "list", blockKey, lines, blockTags, group, log); blocks.Add(script); addScript(keySplit[0], fileKey, keySplit[1], script, blockTags, blockResponses); } break; case "personality": { key = keySplit[1]; // does personality already exist? Personality p = null; Variable<Personality> vP = null; if (personalities.TryGetValue(key, out vP)) p = vP.Value; // if not create new. else p = CreatePersonality(key); // run through the script to fill the personalities variables. var script = new Script(this, false, blockKey, lines, null, group, log); var c = new Controller(this, "DUMMY"); c.AddPersonality(p); var sb = new StringBuilder(); validateScript(c, script, null, sb); runThroughScript(c, script, sb); } break; default: fileLog.Error(string.Format(StringsScripting.Formatted_Error_Invalid_root_type, keySplit[0]), blockLine); return; } } else { fileLog.Error(string.Format(StringsScripting.Formatted_Error_Invalid_root_type, keySplit[0]), blockLine); break; } } } } else ++currentLine; } return; }
public void Validate() { var log = new Logger("Validator"); using (new LogTimed(log, "Starting", "Finished")) { // dummy variables used to run scripts without effecting user data. var p = new Personality(this, "tmpValidator", "tmpValidator"); var c = new Controller(this, "DUMMY"); c.AddPersonality(p); var output = new StringBuilder(); var vars = new Dictionary<string, Variable>(); personControlLock.EnterReadLock(); try { if (personalities.Count == 0) log.Error(StringsScripting.No_personalities); if (inputReplace == null || inputReplace.Count == 0) log.Warning(StringsScripting.No_input_replace); } finally { personControlLock.ExitReadLock(); } if (allscripts.IsEmpty) log.Error(StringsScripting.No_scripts); // validate startup scripts. scriptsLock.EnterReadLock(); try { foreach (var s in setupPersonality) validateScript(c, s, vars, output); foreach (var s in setupController) validateScript(c, s, vars, output); } finally { scriptsLock.ExitReadLock(); } // validate all other scripts. foreach (var s in allscripts.GetAll()) if (s.IsSet) validateScript(c, s, vars, output); } // ToDo 2: Scripts can change inbetwen here and validation, so we could be dirty but dirty being false. Dirty = false; }
/// <summary> Runs all setup scripts on the personality. </summary> private void runAllSetupOn(Personality p, StringBuilder sb) { var c = new Controller(this, "DUMMY"); c.AddPersonality(p); scriptsLock.EnterReadLock(); try { foreach (var s in setupPersonality) runThroughScript(c, s, sb); } finally { scriptsLock.ExitReadLock(); } }