X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=CarFire%2FCarFire%2FCarFire%2FScript.cs;h=9676bbb83e62d07b36067d59d9f6dbdd4a137b16;hb=fc34f843ea42a3496a7ff5dd04853695ba628e8b;hp=5ae6908b11475262ffdeaaa97fce6a29886d6051;hpb=8bd8893e7f7516c76558ad7262e9f9350f5192b9;p=chaz%2Fcarfire
diff --git a/CarFire/CarFire/CarFire/Script.cs b/CarFire/CarFire/CarFire/Script.cs
index 5ae6908..9676bbb 100644
--- a/CarFire/CarFire/CarFire/Script.cs
+++ b/CarFire/CarFire/CarFire/Script.cs
@@ -2,49 +2,186 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Reflection;
+using System.Diagnostics;
namespace CarFire
{
+ ///
+ /// The Script class handles the parsing and execution of lists
+ /// of functions. Scripts are closely related to triggers.
+ ///
public class Script
{
- #region Public Types
+ #region Public Properties
- public enum Status
+ ///
+ /// Determine if the script is in the process of being run.
+ ///
+ public bool IsRunning { get { return mIsRunning; } }
+
+ #endregion
+
+
+ #region Public Methods
+
+ ///
+ /// Construct a script object with code and a game reference.
+ ///
+ /// The script code.
+ /// A game reference.
+ public Script(string code, Game game)
{
- Waiting,
- Done,
+ mImpl = new Impl(game);
+
+ string[] functions = Parse.List(code);
+ if (functions != null)
+ {
+ foreach (string function in functions)
+ {
+ string[] parts = Parse.Function(function);
+ if (parts != null)
+ {
+ string[] args = Parse.List(parts[1]);
+ if (args != null)
+ {
+ Function func = new Function(parts[0], args);
+ mFunctions.Add(func);
+ }
+ else throw new Exception("Arguments could not be parsed: " + parts[1]);
+ }
+ else throw new Exception("Function could not be parsed: " + function);
+ }
+ }
+ else throw new Exception("Script could not be parsed: " + code);
}
- public enum Function
+ ///
+ /// Start execution of the script. If there is no need to break
+ /// execution before the script ends, it will finish before this method
+ /// call ends. Otherwise, execution will be delayed and will finish sometime
+ /// in the future. This will execute each function in sequence as long
+ /// as each function evaluates to true. If a function does not evaluate to true,
+ /// this method will return and execution will be delayed. In either case,
+ /// the evaluation of the last function is returned by this method.
+ ///
+ /// The player associated with this script.
+ /// Evaluation of the last function call.
+ public bool Run(Player player)
{
- Create,
- Has,
- Play,
- Remove,
- UseUp,
- Wait,
+ bool result = false;
+
+ if (!mIsRunning)
+ {
+ mIsRunning = true;
+ mRunningIndex = 0;
+ }
+
+ for (; mRunningIndex < mFunctions.Count; mRunningIndex++)
+ {
+ result = Call(mRunningIndex, player);
+ if (!result) break;
+ }
+
+ if (mRunningIndex >= mFunctions.Count - 1) mIsRunning = false;
+ return result;
}
#endregion
- #region Public Methods
+ #region Private Methods
- public Script(string code)
+ ///
+ /// Call a function in the last at a certain index.
+ ///
+ /// The function index.
+ /// The associated player object.
+ /// The evaluation of the function.
+ bool Call(int index, Player player)
{
+ Debug.Assert(0 <= index && index < mFunctions.Count);
+ try
+ {
+ object[] args = new object[2];
+ args[0] = player;
+ args[1] = mFunctions[index].Arguments;
+ return (bool)typeof(Impl).InvokeMember(mFunctions[index].Name, BindingFlags.InvokeMethod, null, null, args);
+ }
+#pragma warning disable 0168
+ catch (System.MissingMethodException ex)
+#pragma warning restore 0168
+ {
+ throw new Exception("Function could not be found: " + mFunctions[index].Name);
+ }
}
- public Status Run()
+ #endregion
+
+
+ #region Private Types
+
+ class Impl
{
- return Status.Done;
+ public static bool True(Player player, string[] args)
+ {
+ return true;
+ }
+
+ public static bool False(Player player, string[] args)
+ {
+ return false;
+ }
+
+ public static bool Has(Player player, string[] args)
+ {
+ return false;
+ }
+
+ public static bool Print(Player player, string[] args)
+ {
+ foreach (string arg in args)
+ {
+ string line = Parse.String(arg);
+ if (line != null) Console.WriteLine(line);
+ }
+ return true;
+ }
+
+
+ public Impl(Game game)
+ {
+ mGame = game;
+ }
+
+ Game mGame;
}
- public Status Evaluate(out bool value)
+ class Function
{
- value = true;
- return Status.Done;
+ public string Name { get { return mName; } }
+ public string[] Arguments { get { return mArgs; } }
+
+ public Function(string name, string[] args)
+ {
+ mName = name;
+ mArgs = args;
+ }
+
+ string mName;
+ string[] mArgs;
}
#endregion
+
+
+ #region Private Variables
+
+ Impl mImpl;
+ List mFunctions = new List();
+ bool mIsRunning;
+ int mRunningIndex;
+
+ #endregion
}
}