X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fcarfire;a=blobdiff_plain;f=CarFire%2FCarFire%2FCarFire%2FScript.cs;h=0cf9dbdbd56c5e22e4145ed37a05506ac1cbaef6;hp=5ae6908b11475262ffdeaaa97fce6a29886d6051;hb=e8ee0aa62a7e8b5dffa9e02c00c3e353a9e93b4c;hpb=8bd8893e7f7516c76558ad7262e9f9350f5192b9 diff --git a/CarFire/CarFire/CarFire/Script.cs b/CarFire/CarFire/CarFire/Script.cs index 5ae6908..0cf9dbd 100644 --- a/CarFire/CarFire/CarFire/Script.cs +++ b/CarFire/CarFire/CarFire/Script.cs @@ -2,49 +2,156 @@ 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, object bindings) { - Waiting, - Done, + mBindings = bindings; + + 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; - #endregion + if (!mIsRunning) + { + mIsRunning = true; + mRunningIndex = 0; + } + for (; mRunningIndex < mFunctions.Count; mRunningIndex++) + { + result = Call(mRunningIndex, player); + if (!result) break; + } - #region Public Methods + if (mRunningIndex >= mFunctions.Count - 1) mIsRunning = false; + return result; + } - public Script(string code) + public void Reset() { + mIsRunning = false; + } - public Status Run() + #endregion + + + #region Private Methods + + /// + /// 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) { - return Status.Done; + Debug.Assert(0 <= index && index < mFunctions.Count); + try + { + object[] args = new object[2]; + args[0] = player; + args[1] = mFunctions[index].Arguments; + return (bool)mBindings.GetType().InvokeMember(mFunctions[index].Name, BindingFlags.InvokeMethod, null, mBindings, 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 Evaluate(out bool value) + #endregion + + + #region Private Types + + 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 + + object mBindings; + List mFunctions = new List(); + bool mIsRunning; + int mRunningIndex; + + #endregion } }