@Override public void install(ITextViewer textViewer) { Assert.isNotNull(textViewer); fViewer= textViewer; synchronized (this) { if (fThread != null) return; fThread= new BackgroundThread(getClass().getName()); } fDirtyRegionQueue= new DirtyRegionQueue(); fListener= new Listener(); fViewer.addTextInputListener(fListener); // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=67046 // if the reconciler gets installed on a viewer that already has a document // (e.g. when reusing editors), we force the listener to register // itself as document listener, because there will be no input change // on the viewer. // In order to do that, we simulate an input change. IDocument document= textViewer.getDocument(); if (document != null) { fListener.inputDocumentAboutToBeChanged(fDocument, document); fListener.inputDocumentChanged(fDocument, document); } }
@Override public void documentChanged(DocumentEvent e) { if (fThread.isActive() || !fThread.isDirty() && fThread.isAlive()) { if (!fIsAllowedToModifyDocument && Thread.currentThread() == fThread) throw new UnsupportedOperationException("The reconciler thread is not allowed to modify the document"); //$NON-NLS-1$ aboutToBeReconciled(); } /* * The second OR condition handles the case when the document * gets changed while still inside initialProcess(). */ if (fThread.isActive() || fThread.isDirty() && fThread.isAlive()) fProgressMonitor.setCanceled(true); if (fIsIncrementalReconciler) createDirtyRegion(e); fThread.reset(); }
break; if (!isDirty()) continue;
break; if (!isDirty()) continue;
/** * Starts the reconciler to reconcile the queued dirty-regions. * Clients may extend this method. */ protected synchronized void startReconciling() { if (fThread == null) return; if (!fThread.isAlive()) { try { fThread.start(); } catch (IllegalThreadStateException e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=40549 // This is the only instance where the thread is started; since // we checked that it is not alive, it must be dead already due // to a run-time exception or error. Exit. } } else { fThread.reset(); } }
/** * Starts the reconciler to reconcile the queued dirty-regions. * Clients may extend this method. */ protected synchronized void startReconciling() { if (fThread == null) return; if (!fThread.isAlive()) { try { fThread.start(); } catch (IllegalThreadStateException e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=40549 // This is the only instance where the thread is started; since // we checked that it is not alive, it must be dead already due // to a run-time exception or error. Exit. } } else { fThread.reset(); } }
@Override public void install(ITextViewer textViewer) { Assert.isNotNull(textViewer); fViewer= textViewer; synchronized (this) { if (fThread != null) return; fThread= new BackgroundThread(getClass().getName()); } fDirtyRegionQueue= new DirtyRegionQueue(); fListener= new Listener(); fViewer.addTextInputListener(fListener); // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=67046 // if the reconciler gets installed on a viewer that already has a document // (e.g. when reusing editors), we force the listener to register // itself as document listener, because there will be no input change // on the viewer. // In order to do that, we simulate an input change. IDocument document= textViewer.getDocument(); if (document != null) { fListener.inputDocumentAboutToBeChanged(fDocument, document); fListener.inputDocumentChanged(fDocument, document); } }
@Override public void uninstall() { if (fListener != null) { fViewer.removeTextInputListener(fListener); if (fDocument != null) { fListener.inputDocumentAboutToBeChanged(fDocument, null); fListener.inputDocumentChanged(fDocument, null); } fListener= null; synchronized (this) { // http://dev.eclipse.org/bugs/show_bug.cgi?id=19135 BackgroundThread bt= fThread; fThread= null; bt.cancel(); } } }
@Override public void uninstall() { if (fListener != null) { fViewer.removeTextInputListener(fListener); if (fDocument != null) { fListener.inputDocumentAboutToBeChanged(fDocument, null); fListener.inputDocumentChanged(fDocument, null); } fListener= null; synchronized (this) { // http://dev.eclipse.org/bugs/show_bug.cgi?id=19135 BackgroundThread bt= fThread; fThread= null; bt.cancel(); } } }
@Override public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { if (oldInput == fDocument) { if (fDocument != null) fDocument.removeDocumentListener(this); if (fIsIncrementalReconciler) { synchronized (fDirtyRegionQueue) { fDirtyRegionQueue.purgeQueue(); } if (fDocument != null && fDocument.getLength() > 0 && fThread.isDirty() && fThread.isAlive()) { DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), ""); //$NON-NLS-1$ createDirtyRegion(e); fThread.reset(); fThread.suspendCallerWhileDirty(); } } fDocument= null; } }
@Override public void documentChanged(DocumentEvent e) { if (fThread.isActive() || !fThread.isDirty() && fThread.isAlive()) { if (!fIsAllowedToModifyDocument && Thread.currentThread() == fThread) throw new UnsupportedOperationException("The reconciler thread is not allowed to modify the document"); //$NON-NLS-1$ aboutToBeReconciled(); } /* * The second OR condition handles the case when the document * gets changed while still inside initialProcess(). */ if (fThread.isActive() || fThread.isDirty() && fThread.isAlive()) fProgressMonitor.setCanceled(true); if (fIsIncrementalReconciler) createDirtyRegion(e); fThread.reset(); }
/** * Forces the reconciler to reconcile the structure of the whole document. * Clients may extend this method. */ protected void forceReconciling() { if (fDocument != null) { if (!fThread.isDirty()&& fThread.isAlive()) aboutToBeReconciled(); if (fThread.isActive()) fProgressMonitor.setCanceled(true); if (fIsIncrementalReconciler) { DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), fDocument.get()); createDirtyRegion(e); } startReconciling(); } }
@Override public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { if (oldInput == fDocument) { if (fDocument != null) fDocument.removeDocumentListener(this); if (fIsIncrementalReconciler) { synchronized (fDirtyRegionQueue) { fDirtyRegionQueue.purgeQueue(); } if (fDocument != null && fDocument.getLength() > 0 && fThread.isDirty() && fThread.isAlive()) { DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), ""); //$NON-NLS-1$ createDirtyRegion(e); fThread.reset(); fThread.suspendCallerWhileDirty(); } } fDocument= null; } }
/** * Forces the reconciler to reconcile the structure of the whole document. * Clients may extend this method. */ protected void forceReconciling() { if (fDocument != null) { if (!fThread.isDirty()&& fThread.isAlive()) aboutToBeReconciled(); if (fThread.isActive()) fProgressMonitor.setCanceled(true); if (fIsIncrementalReconciler) { DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), fDocument.get()); createDirtyRegion(e); } startReconciling(); } }
@Override public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { fDocument= newInput; if (fDocument == null) return; reconcilerDocumentChanged(fDocument); fDocument.addDocumentListener(this); if (!fThread.isDirty()) aboutToBeReconciled(); startReconciling(); } }
/** * Creates a new background thread. The thread * runs with minimal priority. * * @param name the thread's name */ public BackgroundThread(String name) { super(name); setPriority(Thread.MIN_PRIORITY); setDaemon(true); }
/** * Creates a new background thread. The thread * runs with minimal priority. * * @param name the thread's name */ public BackgroundThread(String name) { super(name); setPriority(Thread.MIN_PRIORITY); setDaemon(true); }
@Override public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { fDocument= newInput; if (fDocument == null) return; reconcilerDocumentChanged(fDocument); fDocument.addDocumentListener(this); if (!fThread.isDirty()) aboutToBeReconciled(); startReconciling(); } }