/// <summary> /// Internal method to RunUntil( requirements ) are met /// The public version is the delegate method above, much simplier and more powerful for users. /// /// </summary> /// <param name="requirements"></param> /// <returns></returns> protected bool RunUntil(ModelRequirements requirements) { //Run until the following requirements are met (ie: variable = values) //Or until the time is elapsed. long startingticks = DateTime.Now.Ticks; long remainingticks = DetermineTicks(); if (this.Options.Tracing) { ModelTrace.WriteLine("Model Seed: " + this.Options.Seed); } bool meetsrequirements = Execute(requirements, startingticks, remainingticks); //CallLast //Because requirements not met and model needs to shutdown correctly. if (!meetsrequirements) { //CallLast, actions foreach (Model model in this.Models) { if (model.Actions.Accessed > 0) //Only if 'first' was called { foreach (ModelAction last in this.GetPossibleActions(model.Actions.FindFlag(ModelActionFlags.CallLast))) { this.ExecuteAction(last); } } } } return(meetsrequirements); }
private void ExecuteActionInfo(ModelActionInfo actioninfo) { ModelAction action = actioninfo.Action; ModelParameters parameters = actioninfo.Parameters; Model model = action.Model; //Pre-Execute, events //Note: If CallBefore returns false, we simply don't execute the method if (model.OnCallBefore(action, parameters)) { //Adding the selected action (and its param values) to the trace. if (this.Options.Tracing) { _actionstrace.Add(actioninfo); } //Execute the method (delegate) actioninfo.RetVal = action.Execute(parameters); _actionscalled++; //Add the returned model to the system Model output = actioninfo.RetVal as Model; if (output != null) { //If it doesn't already exist, and the model type is part of the set if (this.Models.FindInstance(output) == null) { actioninfo.Created = true; //Add returned models, if requested if (this.Options.AddReturnedModels) { //Note: We always obey the maxinstance count Models found = (Models)this.Models.FindType(output.GetType()).FindFlag((int)ModelItemFlags.Disabled, false); if (found.Count < output.MaxInstances) { output.Enabled = true; //Enabled by default if (output.ParentModel == null) //Hook up the creator, if not already specified { output.ParentModel = action.Model; } this.Models.Add(output); } } } } //Trace if (this.Options.Tracing) { ModelTrace.WriteLine(ModelTrace.FormatMethod(actioninfo)); } //Post-Execute, events model.OnCallAfter(action, parameters, actioninfo.RetVal); } //Reset cached variables foreach (ModelVariable variable in this.Models.Variables) { variable.CachedValue = null; } }
protected virtual bool Execute(ModelRequirements requirements, long startingticks, long remainingticks) { bool meetsrequirements = false; _actionscalled = 0; //Continue until no more actions to execute ModelAction action = this.DetermineNextAction(); while (action != null) { //Model Model model = action.Model; //Init if (model.Actions.Accessed == 0) { model.Init(); } //CallFirst, actions //TODO: What happens if this now meets the requirements? foreach (ModelAction first in this.GetPossibleActions(model.Actions.FindFlag(ModelActionFlags.CallFirst))) { if (first != action) { this.ExecuteAction(first); } } //Execute (choose the parameters as well) //Note: CallFirst might have disabled this model, so we check first if (model.Enabled) { this.ExecuteAction(action); } //Determine if all the requirements were met if (requirements != null && requirements.Count > 0 && MeetsRequirements(requirements)) { meetsrequirements = true; break; } //Check action count if (_actionscalled >= _options.MaxActions) { if (this.Options.Tracing) { ModelTrace.WriteLine("MaxActions: '" + _options.MaxActions + "' was reached."); } break; } //Check Timeout long currentticks = DateTime.Now.Ticks; if (currentticks - startingticks > remainingticks) { if (this.Options.Tracing) { ModelTrace.WriteLine("Timeout: '" + _options.Timeout + "' has elapsed."); } break; } //Determine the next action action = this.DetermineNextAction(); } return(meetsrequirements); }