Controllers are the part that figures out what the personality is going to say next.
Inheritance: IKeyed
Example #1
0
		public Context(Controller controller, BlockBase root, Line block, int line, Dictionary<string, Variable> variables)
		{
			Controller = controller;
			Root = root;
			Block = block;
			Line = line;
			Variables = variables;
		}
Example #2
0
		private void validateScript(Controller c, Script s, Dictionary<string, Variable> vars, StringBuilder output)
		{
			// if script has never been validated, but has errors, then do not validate, they are parse errors.
			if (s.Valid == BlockBase.Validation.NeverRan && s.Log.ErrorCount > 0)
			{
				s.SetValid(false); // will set valid to failed.
				return;
			}

			s.SetValid(true);
			if (s.List)
			{
				vars.Clear();
				s.ExecuteAsList(new Context(c, s, s, 0, vars), output);
			}
			else
			{
				c.Add(s);
				while (c.next(output))
				{

				}
			}
			s.SetValid(false);
		}
Example #3
0
		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;
		}
Example #4
0
		/// <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;
		}
Example #5
0
		/// <summary> Add script to controller, call next until false. </summary>
		/// <returns> false if valid is not passed </returns>
		private bool runThroughScript(Controller c, BlockBase s, StringBuilder sb)
		{
			if (s.Valid != BlockBase.Validation.Passed)
				return false;
			c.Add(s);
			bool AutoFill = c.AutoFill;
			c.AutoFill = false;
			while (c.next(sb))
			{
			}
			c.AutoFill = AutoFill;
			return true;
		}
Example #6
0
		/// <summary> Runs all setup scripts on the controller. </summary>
		private void runAllSetupOn(Controller c, StringBuilder sb)
		{
			scriptsLock.EnterReadLock();
			try
			{
				foreach (var s in setupController)
					runThroughScript(c, s, sb);
			}
			finally
			{ scriptsLock.ExitReadLock(); }
		}
Example #7
0
		/// <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(); }
		}
Example #8
0
		public void RemoveController(Controller c)
		{
			if (c == null)
				return;
			c.stop();
			personControlLock.EnterWriteLock();
			try
			{
				controllers.Remove(c);
			}
			finally
			{ personControlLock.ExitWriteLock(); }
		}
Example #9
0
		/// <summary>
		/// Creates a new controller for the given personality.
		/// </summary>
		/// <param name="p"></param>
		/// <returns></returns>
		public Controller CreateController(string id, Logger log = null)
		{
			if (log == null)
				log = new Logger("CreateController[" + id + "]");
			personControlLock.EnterWriteLock();
			try
			{
				var c = new Controller(this, id);
				controllers.Add(c);

				// run setups
				if (Dirty)
					Logger.Log(log, Logger.Level.Error, StringsScripting.Log_VM_Dirty);
				else
				{
					personControlLock.EnterReadLock();
					scriptsLock.EnterReadLock();
					try
					{ runAllSetupOn(c, new StringBuilder()); }
					finally
					{
						scriptsLock.ExitReadLock();
						personControlLock.ExitReadLock();
					}
				}
				c.AddFromStartQuery(log);
				return c;
			}
			finally
			{ personControlLock.ExitWriteLock(); }
		}