public Path(FlowLevel baseFlowLevel, List <string> components) { _baseTargetLevel = baseFlowLevel; _components = components; }
public Parsed.Path PathRelativeTo(Parsed.Object otherObj) { var ownAncestry = ancestry; var otherAncestry = otherObj.ancestry; Parsed.Object highestCommonAncestor = null; int minLength = System.Math.Min(ownAncestry.Count, otherAncestry.Count); for (int i = 0; i < minLength; ++i) { var a1 = ancestry [i]; var a2 = otherAncestry [i]; if (a1 == a2) { highestCommonAncestor = a1; } else { break; } } FlowBase commonFlowAncestor = highestCommonAncestor as FlowBase; if (commonFlowAncestor == null) { commonFlowAncestor = highestCommonAncestor.ClosestFlowBase(); } var pathComponents = new List <string> (); bool hasWeavePoint = false; FlowLevel baseFlow = FlowLevel.WeavePoint; var ancestor = this; while (ancestor && (ancestor != commonFlowAncestor) && !(ancestor is Fiction)) { if (ancestor == commonFlowAncestor) { break; } if (!hasWeavePoint) { var weavePointAncestor = ancestor as IWeavePoint; if (weavePointAncestor != null && weavePointAncestor.name != null) { pathComponents.Add(weavePointAncestor.name); hasWeavePoint = true; continue; } } var flowAncestor = ancestor as FlowBase; if (flowAncestor) { pathComponents.Add(flowAncestor.name); baseFlow = flowAncestor.flowLevel; } ancestor = ancestor.parent; } pathComponents.Reverse(); if (pathComponents.Count > 0) { return(new Path(baseFlow, pathComponents)); } return(null); }
public Path(FlowLevel baseFlowLevel, List<string> components) { _baseTargetLevel = baseFlowLevel; _components = components; }
// See whether "context" contains a child with a given name at a given flow level // Can either be a named knot/stitch (a FlowBase) or a weave point within a Weave (Choice or Gather) // This function also ignores any other object types that are neither FlowBase nor Weave. // Called from both ResolveBase (force deep) and ResolveTail for the individual components. Parsed.Object TryGetChildFromContext(Parsed.Object context, string childName, FlowLevel? minimumLevel, bool forceDeepSearch = false) { // null childLevel means that we don't know where to find it bool ambiguousChildLevel = minimumLevel == null; // Search for WeavePoint within Weave var weaveContext = context as Weave; if ( weaveContext != null && (ambiguousChildLevel || minimumLevel == FlowLevel.WeavePoint)) { return (Parsed.Object) weaveContext.WeavePointNamed (childName); } // Search for content within Flow (either a sub-Flow or a WeavePoint) var flowContext = context as FlowBase; if (flowContext != null) { // When searching within a Knot, allow a deep searches so that // named weave points (choices and gathers) can be found within any stitch // Otherwise, we just search within the immediate object. var shouldDeepSearch = forceDeepSearch || flowContext.flowLevel == FlowLevel.Knot; return flowContext.ContentWithNameAtLevel (childName, minimumLevel, shouldDeepSearch); } return null; }
public Path(FlowLevel baseFlowLevel, List <Identifier> components) { _baseTargetLevel = baseFlowLevel; this.components = components; }
public Parsed.Object ContentWithNameAtLevel(string name, FlowLevel? level = null, bool deepSearch = false) { // Referencing self? if (level == this.flowLevel || level == null) { if (name == this.name) { return this; } } if ( level == FlowLevel.WeavePoint || level == null ) { Parsed.Object weavePointResult = null; if (_rootWeave) { weavePointResult = (Parsed.Object)_rootWeave.WeavePointNamed (name); if (weavePointResult) return weavePointResult; } // Stop now if we only wanted a result if it's a weave point? if (level == FlowLevel.WeavePoint) return deepSearch ? DeepSearchForAnyLevelContent(name) : null; } // If this flow would be incapable of containing the requested level, early out // (e.g. asking for a Knot from a Stitch) if (level != null && level < this.flowLevel) return null; FlowBase subFlow = null; if (_subFlowsByName.TryGetValue (name, out subFlow)) { if (level == null || level == subFlow.flowLevel) return subFlow; } return deepSearch ? DeepSearchForAnyLevelContent(name) : null; }