/// <summary> /// Replace all mappings for a given shape with its new (copied) form. /// </summary> /// <param name="oldShape">TBD</param> /// <param name="newShape">TBD</param> /// <param name="indent">TBD</param> /// <exception cref="ArgumentException">TBD</exception> public void Rewire(Shape oldShape, Shape newShape, int indent) { if (Fusing.IsDebug) { Fusing.Log(indent, $"rewiring {PrintShape(oldShape)} -> {PrintShape(newShape)}"); } { var oins = oldShape.Inlets.GetEnumerator(); var nins = newShape.Inlets.GetEnumerator(); while (oins.MoveNext() && nins.MoveNext()) { var x = RemoveMapping(oins.Current, NewInputs); if (!x.HasValue) { throw new ArgumentException($"rewiring {oins.Current} -> {nins.Current}", nameof(oldShape)); } AddMapping(nins.Current, x.Value, NewInputs); } } { var oouts = oldShape.Outlets.GetEnumerator(); var nouts = newShape.Outlets.GetEnumerator(); while (oouts.MoveNext() && nouts.MoveNext()) { var x = RemoveMapping(oouts.Current, NewOutputs); if (!x.HasValue) { throw new ArgumentException($"rewiring {oouts.Current} -> {nouts.Current}", nameof(oldShape)); } AddMapping(nouts.Current, x.Value, NewOutputs); } } }
/// <summary> /// Create and return a new grouping (i.e. an AsyncBoundary-delimited context) /// </summary> /// <param name="indent">TBD</param> /// <returns>TBD</returns> public ISet <IModule> CreateGroup(int indent) { var group = new HashSet <IModule>(); if (Fusing.IsDebug) { Fusing.Log(indent, $"creating new group {Hash(group)}"); } Groups.AddLast(group); return(group); }
/// <summary> /// Register the outlets of the given Shape as sources for internal connections within imported /// (and not dissolved) GraphModules. See also the comment in addModule where this is partially undone. /// </summary> /// <param name="shape">TBD</param> /// <param name="indent">TBD</param> public void RegisterInternals(Shape shape, int indent) { if (Fusing.IsDebug) { Fusing.Log(indent, $"registerInternals({string.Join(",", shape.Outlets.Select(Hash))}"); } foreach (var outlet in shape.Outlets) { InternalOuts.Add(outlet); } }
/// <summary> /// Record a wiring between two copied ports, using (and reducing) the port mappings. /// </summary> /// <param name="outPort">TBD</param> /// <param name="inPort">TBD</param> /// <param name="indent">TBD</param> /// <exception cref="ArgumentException">TBD</exception> public void Wire(OutPort outPort, InPort inPort, int indent) { if (Fusing.IsDebug) { Fusing.Log(indent, $"wiring {outPort} ({Hash(outPort)}) -> {inPort} ({Hash(inPort)})"); } var newOut = RemoveMapping(outPort, NewOutputs); if (!newOut.HasValue) { throw new ArgumentException($"wiring {outPort} -> {inPort}", nameof(outPort)); } var newIn = RemoveMapping(inPort, NewInputs); if (!newIn.HasValue) { throw new ArgumentException($"wiring {outPort} -> {inPort}", nameof(inPort)); } Downstreams.Add(newOut.Value, newIn.Value); Upstreams.Add(newIn.Value, newOut.Value); }
/// <summary> /// Add a module to the given group, performing normalization (i.e. giving it a unique port identity). /// </summary> /// <param name="module">TBD</param> /// <param name="group">TBD</param> /// <param name="inheritedAttributes">TBD</param> /// <param name="indent">TBD</param> /// <param name="oldShape">TBD</param> /// <returns>TBD</returns> public Atomic AddModule(IModule module, ISet <IModule> group, Attributes inheritedAttributes, int indent, Shape oldShape = null) { var copy = oldShape == null ? new CopiedModule(module.Shape.DeepCopy(), inheritedAttributes, GetRealModule(module)) : module; oldShape = oldShape ?? module.Shape; if (Fusing.IsDebug) { Fusing.Log(indent, $"adding copy {Hash(copy)} {PrintShape(copy.Shape)} of {PrintShape(oldShape)}"); } group.Add(copy); Modules.Add(copy); foreach (var outlet in copy.Shape.Outlets) { OutGroups.Add(outlet, group); } var orig1 = oldShape.Inlets.GetEnumerator(); var mapd1 = copy.Shape.Inlets.GetEnumerator(); while (orig1.MoveNext() && mapd1.MoveNext()) { var orig = orig1.Current; var mapd = mapd1.Current; AddMapping(orig, mapd, NewInputs); InOwners[mapd] = copy; } var orig2 = oldShape.Outlets.GetEnumerator(); var mapd2 = copy.Shape.Outlets.GetEnumerator(); while (orig2.MoveNext() && mapd2.MoveNext()) { var orig = orig2.Current; var mapd = mapd2.Current; AddMapping(orig, mapd, NewOutputs); OutOwners[mapd] = copy; } /* * In Descend() we add internalOuts entries for all shapes that belong to stages that * are part of a GraphModule that is not dissolved. This includes the exposed Outlets, * which of course are external and thus need to be removed again from the internalOuts * set. */ if (module is GraphModule) { foreach (var outlet in module.Shape.Outlets) { InternalOuts.Remove(outlet); } } if (IsCopiedModuleWithGraphStageAndMaterializedValue(copy)) { PushMaterializationSource((CopiedModule)copy); } else if (copy is GraphModule) { var mvids = ((GraphModule)copy).MaterializedValueIds; foreach (IModule mvid in mvids) { if (IsCopiedModuleWithGraphStageAndMaterializedValue(mvid)) { PushMaterializationSource((CopiedModule)mvid); } } } return(new Atomic(copy)); }