Ejemplo n.º 1
0
        public Signal Manipulate(Signal rootSignal, IManipulationVisitor visitor, bool ignoreHold)
        {
            IScanStrategy allPathsStrat = Binder.GetSpecificInstance <IScanStrategy>(new MathIdentifier("AllPathsStrategy", "Traversing"));

            Dictionary <Guid, ManipulationPlan> plans = new Dictionary <Guid, ManipulationPlan>();
            Dictionary <Guid, Signal>           signalReplacements = new Dictionary <Guid, Signal>();
            Dictionary <Guid, Signal>           sentinels          = new Dictionary <Guid, Signal>();

            // ## ESTIMATE MANIPULATION PLAN
            _scanner.ForEachPort(rootSignal, delegate(Port p)
            {
                if (!plans.ContainsKey(p.InstanceId))
                {
                    plans.Add(p.InstanceId, visitor.EstimatePlan(p));
                }
                return(true);
            }, ignoreHold);

            // ## OPTIMIZE MANIPULATION PLAN (cycle analysis)
            ManipulatorPlanReducer reducer = new ManipulatorPlanReducer(plans, ignoreHold);

            allPathsStrat.Traverse(rootSignal, reducer, ignoreHold);

            // ## EXECUTE MANIPULATION
            ManipulatorPlanExecutor executor = new ManipulatorPlanExecutor(plans, signalReplacements, sentinels, visitor);

            allPathsStrat.Traverse(rootSignal, executor, ignoreHold);

            // ## SELECT NEW SYSTEM
            Signal ret;

            if (!signalReplacements.TryGetValue(rootSignal.InstanceId, out ret))
            {
                ret = rootSignal;
            }

            // ## FIX SENTINELS ON SELECTED NEW SYSTEM
            _scanner.ForEachPort(ret, delegate(Port p)
            {
                // look for sentinels on all input signals
                ReadOnlySignalSet inputs = p.InputSignals;
                for (int i = 0; i < inputs.Count; i++)
                {
                    Signal input = inputs[i];
                    if (FixSentinel(ref input, sentinels, signalReplacements))
                    {
                        p.ReplaceInputSignalBinding(i, input);
                    }
                }
                return(true);
            }, ignoreHold);
            FixSentinel(ref ret, sentinels, signalReplacements);

            // ## RETURN SELECTED NEW SYSTEM AS RESULT
            return(ret);
        }