ProcessChange() public method

Processes a single text change incrementally. Enqueues resulting tree changes in the supplied queue. Does not modify the tree. Changes are to be sent to the main thread and applied from there. Caller is responsible for the tree read lock acquisition.
public ProcessChange ( TextChange textChange, Microsoft.R.Editor.Tree.EditorTreeChangeCollection treeChanges ) : void
textChange TextChange
treeChanges Microsoft.R.Editor.Tree.EditorTreeChangeCollection Collection of tree changes to apply /// from the main thread
return void
Example #1
0
        /// <summary>
        /// Main asyncronous task body
        /// </summary>
        void ProcessTextChanges(TextChange changeToProcess, bool async, Func <bool> isCancelledCallback)
        {
            lock (_disposeLock) {
                if (_editorTree == null || _disposed || isCancelledCallback())
                {
                    return;
                }

                EditorTreeChangeCollection treeChanges = null;
                // Cache id since it can change if task is canceled
                long taskId = TaskId;

                try {
                    AstRoot rootNode;

                    // We only need read lock since changes will be applied
                    // from the main thread
                    if (async)
                    {
                        rootNode = _editorTree.AcquireReadLock(_treeUserId);
                    }
                    else
                    {
                        rootNode = _editorTree.GetAstRootUnsafe();
                    }

                    treeChanges = new EditorTreeChangeCollection(changeToProcess.Version, changeToProcess.FullParseRequired);
                    TextChangeProcessor changeProcessor = new TextChangeProcessor(_editorTree, rootNode, isCancelledCallback);

                    bool fullParseRequired = changeToProcess.FullParseRequired;
                    if (fullParseRequired)
                    {
                        changeProcessor.FullParse(treeChanges, changeToProcess.NewTextProvider);
                    }
                    else
                    {
                        changeProcessor.ProcessChange(changeToProcess, treeChanges);
                    }
                } finally {
                    if (async && _editorTree != null)
                    {
                        _editorTree.ReleaseReadLock(_treeUserId);
                    }
                }

                // Lock should be released at this point since actual application
                // of tree changes is going to be happen from the main thread.

                if (!isCancelledCallback() && treeChanges != null)
                {
                    // Queue results for the main thread application. This must be done before
                    // signaling that the task is complete since if EnsureProcessingComplete
                    // is waiting it will want to apply changes itself rather than wait for
                    // the DispatchOnUIThread to go though and hence it will need all changes
                    // stored and ready for application.

                    _backgroundParsingResults.Enqueue(treeChanges);
                }

                // Signal task complete now so if main thread is waiting
                // it can proceed and appy the changes immediately.
                SignalTaskComplete(taskId);

                if (_backgroundParsingResults.Count > 0)
                {
                    _uiThreadTransitionRequestTime = DateTime.UtcNow;

                    // It is OK to post results while main thread might be working
                    // on them since if if it does, by the time posted request comes
                    // queue will already be empty.
                    if (async)
                    {
                        // Post request to apply tree changes to the main thread.
                        // This must NOT block or else task will never enter 'RanToCompletion' state.
                        EditorShell.DispatchOnUIThread(() => ApplyBackgroundProcessingResults());
                    }
                    else
                    {
                        // When processing is synchronous, apply changes and fire events right away.
                        ApplyBackgroundProcessingResults();
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Main asyncronous task body
        /// </summary>
        void ProcessTextChanges(TextChange changeToProcess, bool async, Func<bool> isCancelledCallback) {
            lock (_disposeLock) {
                if (_editorTree == null || _disposed || isCancelledCallback())
                    return;

                EditorTreeChangeCollection treeChanges = null;
                // Cache id since it can change if task is canceled
                long taskId = TaskId;

                try {
                    AstRoot rootNode;

                    // We only need read lock since changes will be applied 
                    // from the main thread
                    if (async) {
                        rootNode = _editorTree.AcquireReadLock(_treeUserId);
                    } else {
                        rootNode = _editorTree.GetAstRootUnsafe();
                    }

                    treeChanges = new EditorTreeChangeCollection(changeToProcess.Version, changeToProcess.FullParseRequired);
                    TextChangeProcessor changeProcessor = new TextChangeProcessor(_editorTree, rootNode, isCancelledCallback);

                    bool fullParseRequired = changeToProcess.FullParseRequired;
                    if (fullParseRequired) {
                        changeProcessor.FullParse(treeChanges, changeToProcess.NewTextProvider);
                    } else {
                        changeProcessor.ProcessChange(changeToProcess, treeChanges);
                    }
                } finally {
                    if (async && _editorTree != null)
                        _editorTree.ReleaseReadLock(_treeUserId);
                }

                // Lock should be released at this point since actual application
                // of tree changes is going to be happen from the main thread.

                if (!isCancelledCallback() && treeChanges != null) {
                    // Queue results for the main thread application. This must be done before 
                    // signaling that the task is complete since if EnsureProcessingComplete 
                    // is waiting it will want to apply changes itself rather than wait for 
                    // the DispatchOnUIThread to go though and hence it will need all changes
                    // stored and ready for application.

                    _backgroundParsingResults.Enqueue(treeChanges);
                }

                // Signal task complete now so if main thread is waiting
                // it can proceed and appy the changes immediately.
                SignalTaskComplete(taskId);

                if (_backgroundParsingResults.Count > 0) {
                    _uiThreadTransitionRequestTime = DateTime.UtcNow;

                    // It is OK to post results while main thread might be working
                    // on them since if if it does, by the time posted request comes
                    // queue will already be empty.
                    if (async) {
                        // Post request to apply tree changes to the main thread.
                        // This must NOT block or else task will never enter 'RanToCompletion' state.
                        EditorShell.DispatchOnUIThread(() => ApplyBackgroundProcessingResults());
                    } else {
                        // When processing is synchronous, apply changes and fire events right away.
                        ApplyBackgroundProcessingResults();
                    }
                }
            }
        }