public static ObjMap GetDependencyGraph(Object root, Object[] targets) { var cycleFree = GetCycleFreeDependencies(root, targets); if (!cycleFree.Keys.Any()) { return(new ObjMap()); } // cycleFree -> graph var graphRoot = cycleFree.ContainsKey(root) ? root : cycleFree .Keys .OfType <CycleRep>() .Where(x => x.members.Contains(root)) .SingleOrDefault(); if (graphRoot == null) { // root object is not in the graph (using a scene as root obj does that) // add a representative for the scene object as new graph root graphRoot = CycleRep.Create(new[] { root }); graphRoot.name = root.name; var notSoMuchRoots = GetRoots(cycleFree); cycleFree[graphRoot] = notSoMuchRoots.ToHashSet(); } // structure the dependencies return(cycleFree.ToDictionary ( pair => pair.Key, pair => pair.Value .Where(obj => obj != pair.Key && pair.Value.Except(new[] { obj }).Any(sibling => cycleFree[sibling].Contains(obj)) == false) .ToHashSet() )); }
public static ObjMap GetCycleFreeDependencies(Object root, Object[] targets) { var connectedDeps = GetConnectedDependencies(root, targets); // replace cycles by a single objects // connectedDeps -> cycleFree // group the map keys by value. // that will create one group for each dependency-cycle, containing all its members var cycleGrouped = connectedDeps.Keys.GroupBy(key => connectedDeps[key], new SetComparer()); // create a representative object for each group and map it to the group members var repToMembers = cycleGrouped .Where(group => group.Count() > 1) .ToDictionary(group => (Object)CycleRep.Create(group), group => group.ToHashSet()); // map all keys to their representative var objToRep = new Dictionary <Object, Object>(); foreach (var pair in repToMembers) { foreach (var obj in pair.Value) { objToRep[obj] = pair.Key; } } System.Func <Object, Object> newObj = (obj) => objToRep.ContainsKey(obj) ? objToRep[obj] : obj; return(cycleGrouped.ToDictionary ( group => newObj(group.First()), group => connectedDeps[group.First()] .Select(newObj) .Except(new[] { newObj(group.First()) }) .ToHashSet() )); }
public bool EqualMembers(CycleRep other) { return(other != null && other.members.SetEquals(this.members)); }