Esempio n. 1
0
        /// <summary>
        /// Returns true if this task's graph sync data is a super set of the other
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        private bool Contains(UpdateGraphAsyncTask other)
        {
            // Be more conservative here. Not only check ModifiedNodes, but
            // also check *all* nodes in graph sync data. For example, consider
            // a CBN outputs to a node, the node is a downstream node of cbn.
            //
            // Now if node is modified and request a run, task's ModifiedNodes
            // will cotain this node; then CBN is modified and request a run,
            // ModifiedNodes would contain both CBN and the node, and previous
            // task will be thrown away.
            if (!other.ModifiedNodes.All(ModifiedNodes.Contains))
            {
                return(false);
            }

            if (graphSyncData == null)
            {
                return(other.graphSyncData == null);
            }
            else if (other.graphSyncData == null)
            {
                return(true);
            }

            return(other.graphSyncData.AddedNodeIDs.All(graphSyncData.AddedNodeIDs.Contains) &&
                   other.graphSyncData.ModifiedNodeIDs.All(graphSyncData.ModifiedNodeIDs.Contains) &&
                   other.graphSyncData.DeletedNodeIDs.All(graphSyncData.DeletedNodeIDs.Contains));
        }
Esempio n. 2
0
        /// <summary>
        /// Returns true if this task's graph sync data is a super set of the other
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        private bool CanReplace(UpdateGraphAsyncTask other)
        {
            // Be more conservative here. Not only check ModifiedNodes, but
            // also check *all* nodes in graph sync data. For example, consider
            // a CBN outputs to a node, the node is a downstream node of cbn.
            //
            // Now if node is modified and request a run, task's ModifiedNodes
            // will cotain this node; then CBN is modified and request a run,
            // ModifiedNodes would contain both CBN and the node, and previous
            // task will be thrown away.
            if (!other.ModifiedNodes.All(ModifiedNodes.Contains))
            {
                return(false);
            }

            if (graphSyncData == null)
            {
                return(other.graphSyncData == null);
            }
            else if (other.graphSyncData == null)
            {
                return(true);
            }

            // Merging additions and removals can make the changeSetComputer internal state get corrupted.
            // Imagine a sequence of queued tasks with changes like these: +A | -A | +AB
            // Imagine a new task with change -A, ending up with the following sequence: -A | +A | -A | +AB
            // While the merge routine would simplify this sequence to: -A | +A | +AB
            // That creates an inconsistent sequence of changes where subtree A is added when it already exists!
            // Modifications are not susceptible to this problem. Imagine ~A incoming with sequence: +A | -A | ~A | +AB
            // The resulting sequence is: ~A | +A | -A | +AB, which is valid.
            // Because modifications do not create or remove entries in the changeSetComputer internal state,
            // if we remove one from anywhere in the sequence we remain consistent.
            return(other.graphSyncData.AddedNodeIDs.Count() == 0 &&
                   other.graphSyncData.ModifiedNodeIDs.All(graphSyncData.ModifiedNodeIDs.Contains) &&
                   other.graphSyncData.DeletedNodeIDs.Count() == 0);
        }
Esempio n. 3
0
 private bool IsScheduledAfter(UpdateGraphAsyncTask other)
 {
     return CreationTime > other.CreationTime;
 }
Esempio n. 4
0
        /// <summary>
        /// Returns true if this task's graph sync data is a super set of the other
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        private bool Contains(UpdateGraphAsyncTask other)
        {
            // Be more conservative here. Not only check ModifiedNodes, but
            // also check *all* nodes in graph sync data. For example, consider
            // a CBN outputs to a node, the node is a downstream node of cbn.
            //
            // Now if node is modified and request a run, task's ModifiedNodes
            // will cotain this node; then CBN is modified and request a run,
            // ModifiedNodes would contain both CBN and the node, and previous
            // task will be thrown away.
            if (!other.ModifiedNodes.All(ModifiedNodes.Contains))
                return false;

            if (graphSyncData == null)
                return other.graphSyncData == null;
            else if (other.graphSyncData == null)
                return true;

            return other.graphSyncData.AddedNodeIDs.All(graphSyncData.AddedNodeIDs.Contains) &&
                   other.graphSyncData.ModifiedNodeIDs.All(graphSyncData.ModifiedNodeIDs.Contains) &&
                   other.graphSyncData.DeletedNodeIDs.All(graphSyncData.DeletedNodeIDs.Contains);
        }
Esempio n. 5
0
        /// <summary>
        /// This method is typically called from the main application thread (as 
        /// a result of user actions such as button click or node UI changes) to
        /// schedule an update of the graph. This call may or may not represent 
        /// an actual update. In the event that the user action does not result 
        /// in actual graph update (e.g. moving of node on UI), the update task 
        /// will not be scheduled for execution.
        /// </summary>
        public void Run()
        {
            graphExecuted = true;

            // When Dynamo is shut down, the workspace is cleared, which results
            // in Modified() being called. But, we don't want to run when we are
            // shutting down so we check whether an engine controller is available.
            if (this.EngineController == null)
            {
                return;
            }

            var traceData = PreloadedTraceData;
            if ((traceData != null) && traceData.Any())
            {
                // If we do have preloaded trace data, set it here first.
                var setTraceDataTask = new SetTraceDataAsyncTask(scheduler);
                if (setTraceDataTask.Initialize(EngineController, this))
                    scheduler.ScheduleForExecution(setTraceDataTask);
            }

            // If one or more custom node have been updated, make sure they
            // are compiled first before the home workspace gets evaluated.
            // 
            EngineController.ProcessPendingCustomNodeSyncData(scheduler);

            var task = new UpdateGraphAsyncTask(scheduler, verboseLogging);
            if (task.Initialize(EngineController, this))
            {
                task.Completed += OnUpdateGraphCompleted;
                RunSettings.RunEnabled = false; // Disable 'Run' button.

                // Reset node states
                foreach (var node in Nodes)
                {
                    node.WasInvolvedInExecution = false;
                }

                // The workspace has been built for the first time
                silenceNodeModifications = false;

                OnEvaluationStarted(EventArgs.Empty);
                scheduler.ScheduleForExecution(task);
            }
            else
            {
                // Notify handlers that evaluation did not take place.
                var e = new EvaluationCompletedEventArgs(false);
                OnEvaluationCompleted(e);
            }
        }
Esempio n. 6
0
 private bool IsScheduledAfter(UpdateGraphAsyncTask other)
 {
     return(CreationTime > other.CreationTime);
 }
Esempio n. 7
0
        public void TestUpdateGraphyAsyncTaskMerge()
        {
            // Verify a UpdateGraphAysncTask can't be merged with the other one
            // if they modifiy different nodes.
            OpenModel(TestDirectory + @"\core\scheduler\simple.dyn");

            var cbn = CurrentDynamoModel.CurrentWorkspace.Nodes.OfType<CodeBlockNodeModel>().FirstOrDefault();
            var funcNode = CurrentDynamoModel.CurrentWorkspace.Nodes.OfType<DSFunction>().FirstOrDefault();

            // Keep code block node be silent so that the graph won't be
            // executed automatically
            cbn.RaisesModificationEvents = false;

            var elementResolver = CurrentDynamoModel.CurrentWorkspace.ElementResolver;
            cbn.SetCodeContent("-22", elementResolver); // Invalid numeric value.
            cbn.MarkNodeAsModified();

            // Get a UpdateGrapyAsyncTask for the modification of cbn
            var scheduler = new DynamoScheduler(new SampleSchedulerThread(), TaskProcessMode.Synchronous);
            UpdateGraphAsyncTask task1 = new UpdateGraphAsyncTask(scheduler, false);
            task1.Initialize(CurrentDynamoModel.EngineController, CurrentDynamoModel.CurrentWorkspace);

            // Get a UpdateGraphAsyncTask for the modification of Math.Sin()
            funcNode.MarkNodeAsModified();
            UpdateGraphAsyncTask task2 = new UpdateGraphAsyncTask(scheduler, false);
            task2.Initialize(CurrentDynamoModel.EngineController, CurrentDynamoModel.CurrentWorkspace);

            // And both async tasks should be kept.
            var mergeResult = task1.CanMergeWith(task2);
            Assert.AreEqual(AsyncTask.TaskMergeInstruction.KeepBoth, mergeResult);

            mergeResult = task2.CanMergeWith(task1);
            Assert.AreEqual(AsyncTask.TaskMergeInstruction.KeepBoth, mergeResult);

            scheduler.Shutdown();
        }