protected bool MeetsRequirements(ModelRequirements requirements) { //Delegate ModelRequirement failedrequirement = null; return(this.MeetsRequirements(requirements, out failedrequirement)); }
protected bool MeetsRequirements(ModelRequirements requirements, out ModelRequirement failedrequirement) { if (requirements != null) { //Loop over all requirements foreach (ModelRequirement requirement in requirements) { //Ignore disabled requirements if (requirement.Weight == 0 || requirement.Disabled) { continue; } //By default were just looking at this specific variable instance //However if 'Global' is enabled, consider this variable on any models of this type List <Object> currentValues = new List <Object>(); if (requirement.Global) { //Note: We do this check everytime, since models could have been added dynamically if (requirement.Variable != null) { foreach (Model model in this.Models.FindType(requirement.Variable.Model.GetType())) { ModelVariables variables = model.Variables.Find(requirement.Variable.Name); foreach (ModelVariable variable in variables) { currentValues.Add(variable.CachedValue); } } } else { currentValues.Add(true); } } else { if (requirement.Variable == null) { throw new ModelException(this, "Variable is null?"); } currentValues.Add(requirement.Variable.CachedValue); } //See if this requirement is met bool matched = false; foreach (Object value in currentValues) { if (requirement.Evaluate(value)) { matched = true; break; } } //Stop on first mis-match, (ie: at least one requirement didn't match) if (!matched) { //First failed requirement //Note: This has to be order based, since production checks conditions in-order //and will fail (and throw) according to the first one not meet failedrequirement = requirement; return(false); } } } failedrequirement = null; return(true); }
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); }