protected ModelActions GetPossibleActions(ModelActions totalactions) { //Loop through all actions, specified ModelActions possibleactions = new ModelActions(); foreach (ModelAction action in totalactions) { //Ignore Disabled actions if (action.Weight == 0 || action.Disabled) { continue; } //Ignore CallLimit/CallOnce actions that have already been called (max times) if (action.Accessed >= action.CallLimit) { continue; } //Note: CallFirst and CallLast imply CallOnce if (action.Accessed > 0 && (action.CallFirst || action.CallLast)) { continue; } //Ignore Actions, that return Models when were over the limit of those models Type returntype = action.Method.ReturnType; if (!returntype.IsPrimitive && typeof(Model).IsAssignableFrom(returntype) && returntype != typeof(Model)) { Models found = (Models)this.Models.FindType(returntype).FindFlag((int)ModelItemFlags.Disabled, false); if (found.Count >= found.MaxInstances) { continue; } } //Determine if Requirements meet ModelRequirement failedrequirement = null; bool matched = MeetsRequirements(action.Requirements, out failedrequirement); if (matched) { //Requirements met, action can be called possibleactions.Add(action); } else { //Requirements not met, action can't be called //Unless the user wants this to be called, when the requirements aren't met if (this.InvalidActions && failedrequirement != null && failedrequirement.Throws) { //Note: We clone the action, and set the expected exception, just as if //it were an invalid action from the start. We also set the weight of the //invalid action, to the weight of the requirement, so it's not weighted //the same as the (positive) version that's specified at the action level ModelAction invalidaction = (ModelAction)action.Clone(); invalidaction.Exception = failedrequirement.Exception; invalidaction.ExceptionId = failedrequirement.ExceptionId; invalidaction.Weight = failedrequirement.Weight; possibleactions.Add(invalidaction); } } } possibleactions.SortByWeightDesc(); //Sort all actions, across models return(possibleactions); }
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; } }
/// <summary> /// This method forces the engine to reload the models. /// Useful to reload the weights and other properties. /// </summary> public override void Reload() { //Clear, so they will be dynamically setup by reflection again _models = null; }