public bool Check(IRelevantObject relevantObject, RelevantObjectsGenerator generator) { return(Predicates.Count == 0 || Predicates.Any(o => o.Check(relevantObject, generator))); }
public RelevantObjectCollection GetSubset(SelectionPredicateCollection predicate, RelevantObjectsGenerator generator) { var result = new RelevantObjectCollection(); if (predicate == null) { foreach (var kvp in this) { result.Add(kvp.Key, kvp.Value); } return(result); } foreach (var kvp in this) { result.Add(kvp.Key, kvp.Value.Where(o => predicate.Check(o, generator)).ToList()); } return(result); }
/// <summary> /// Regenerates the relevant objects of this layer using the active generators. Any relevant objects that already exist do not get replaced and any relevant objects that should not exist get removed. /// </summary> public void GenerateNewObjects(bool forcePropagate = false) { if (GeneratorCollection == null) { return; } // Get all active generators for this layer var activeGenerators = GeneratorCollection.GetActiveGenerators().ToArray(); // Get the previous layers objects if any generators are deep var deepObjects = activeGenerators.Any(o => o.Settings.IsDeep) ? GetAllPreviousLayersCollection() : null; // Initialize list for objects to add later var objectsToAdd = new List <IRelevantObject>(); // Loop through all active generators foreach (var generator in activeGenerators) { // Get the generator methods var methods = generator.GetGeneratorMethods(); // Get the required relevant object collection for this generator var objects = generator.Settings.IsDeep ? deepObjects.GetSubset(generator.Settings.InputPredicate, generator) : PreviousLayer?.Objects?.GetSubset(generator.Settings.InputPredicate, generator); // Loop through all generator methods in this generator foreach (var method in methods) { // Get the dependencies for this generator method var dependencies = RelevantObjectsGenerator.GetDependencies(method); // Continue if there are dependencies but nothing to get the values from if (dependencies.Length > 0 && PreviousLayer == null) { continue; } // Get all the combinations of relevant objects to use this generator method on var parametersList = RelevantObjectPairGenerator.GetParametersList(dependencies, objects, generator.Settings.IsSequential); // Generate all the new relevant objects foreach (var parameters in parametersList) { // Generate the new relevant object(s) var result = method.Invoke(generator, parameters); // Cast parameters to relevant objects var relevantParents = new HashSet <IRelevantObject>(parameters.Cast <IRelevantObject>()); // Handle different return types switch (result) { case IEnumerable <IRelevantObject> newRelevantObjectsEnumerable: { // Enumerate to array var newRelevantObjectsArray = newRelevantObjectsEnumerable as IRelevantObject[] ?? newRelevantObjectsEnumerable.ToArray(); // Add the new relevant objects to the children of the parents foreach (var relevantParent in relevantParents) { relevantParent.ChildObjects.UnionWith(newRelevantObjectsArray); } // Add parents and generator to the new relevant objects foreach (var relevantObject in newRelevantObjectsArray) { relevantObject.Generator = generator; // Generator has to be set before parents, otherwise temporal position will go wrong relevantObject.ParentObjects = relevantParents; // Set the IsInheritable setting according to the generator settings relevantObject.IsInheritable = generator.Settings.GeneratesInheritable; } // Add the new relevant objects to this layer objectsToAdd.AddRange(newRelevantObjectsArray); break; } case IRelevantObject newRelevantObject: // Add the new relevant object to the children of the parents foreach (var relevantParent in relevantParents) { relevantParent.ChildObjects.Add(newRelevantObject); } // Add parents and generator to the new relevant object newRelevantObject.Generator = generator; // Generator has to be set before parents, otherwise temporal position will go wrong newRelevantObject.ParentObjects = relevantParents; // Set the IsInheritable setting according to the generator settings newRelevantObject.IsInheritable = generator.Settings.GeneratesInheritable; // Add the new relevant objects to this layer objectsToAdd.Add(newRelevantObject); break; } } } } // Avoid adding too many objects var newCount = objectsToAdd.Count + Objects.GetCount(); var overshot = newCount - ParentCollection.MaxObjects; if (overshot > 0) { return; //objectsToAdd.RemoveRange(objectsToAdd.Count - overshot, overshot); } // Set all DoNotDispose to false foreach (var relevantObject in Objects.Values.SelectMany(list => list)) { relevantObject.DoNotDispose = false; } // Add objects to this layer // This sets DoNotDispose for all the relevant objects that already exist in this layer and are consuming the objects to add. Add(objectsToAdd, false); // Dispose all relevant objects in this layer that were generated from a generator, but not generated now. foreach (var objectLayerObject in Objects.Values) { for (var i = 0; i < objectLayerObject.Count; i++) { var obj = objectLayerObject[i]; // Continue for relevant objects with no generator or DoNotDispose if (!obj.DefinitelyDispose && (obj.Generator == null || obj.DoNotDispose)) { continue; } obj.Dispose(); i--; } } // Don't propagate if this layer has more than the max number of relevant objects if (Objects.GetCount() > ParentCollection.MaxObjects) { return; } // Propagate if anything was added to this layer if (objectsToAdd.Count > 0 || forcePropagate) { NextLayer?.GenerateNewObjects(forcePropagate); } }