using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Diagnostics; namespace CarFire { public class Script { #region Public Properties public bool IsRunning { get { return mIsRunning; } } #endregion #region Public Methods public Script(string code, Game game) { mGame = 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 bool Run(Player player) { 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 Private Methods 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); } } #endregion #region Private Types class Impl { 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; } } class Function { 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 Game mGame; List mFunctions = new List(); bool mIsRunning; int mRunningIndex; Impl mImpl = new Impl(); #endregion } }