/*******************************************************************************
* Copyright (c) Gil Barash - chookapp@yahoo.com
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Gil Barash - initial API and implementation
*******************************************************************************/
package com.chookapp.org.bracketeer.core;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.ui.services.IDisposable;
import com.chookapp.org.bracketeer.Activator;
import com.chookapp.org.bracketeer.extensionpoint.BracketeerProcessor;
public class ProcessingThread implements Runnable, IDocumentListener, IDisposable
{
private Thread _thread = null;
private IDocument _doc;
private BracketeerProcessor _processor;
private BracketeerProcessingContainer _bracketContainer;
//private Lock _bracketContainerLock = new ReentrantLock();
private boolean _documentChanged;
// private boolean _isProcessing;
// private boolean _cancelProcessing;
// private Semaphore _processingCanceled = new Semaphore(0);
private Object _docChangedLock = new Object();
private boolean _docIsChanging;
private boolean _disposing;
public ProcessingThread(IDocument doc, BracketeerProcessor processor)
{
_processor = processor;
_documentChanged = false;
_docIsChanging = false;
_disposing = false;
_doc = doc;
_bracketContainer = new BracketeerProcessingContainer(_doc);
// _isProcessing = false;
_doc.addDocumentListener(this);
// initial mapping...
documentChanged(null);
}
@Override
public void dispose()
{
_doc.removeDocumentListener(this);
_disposing = true;
}
public void run()
{
while(!_disposing)
{
while(_documentChanged || _docIsChanging ||
_bracketContainer.isUpdatingListeners())
{
_documentChanged = false;
try
{
Thread.sleep(250);
}
catch (InterruptedException e)
{
Activator.log(e);
}
} // waiting for document to stop changing
_bracketContainer.markAllToBeDeleted();
boolean reRun = true;
try
{
reRun = !_processor.process(_bracketContainer);
}
catch (Exception e)
{
Activator.log(e);
}
synchronized (_docChangedLock)
{
if( reRun || _documentChanged )
{
_documentChanged = true;
continue;
}
_thread = null;
break;
}
}
_bracketContainer.deleteAllMarked();
_bracketContainer.updateComplete();
}
// public void run()
// {
// synchronized(_lock)
// {
// _cancelProcessing = false;
// _isProcessing = true;
// }
//
// _processor.process(_bracketContainer);
//
// synchronized(_lock)
// {
// _isProcessing = false;
// if( _cancelProcessing )
// _processingCanceled.release();
// }
// }
//
// @Override
// public void documentAboutToBeChanged(DocumentEvent event)
// {
// synchronized(_lock)
// {
// if( !_isProcessing )
// return;
// _cancelProcessing = true;
// }
//
// _processor.cancel();
//
// try
// {
// _processingCanceled.acquire();
// }
// catch (InterruptedException e)
// {
// Activator.log(e);
// }
// }
public BracketeerProcessingContainer getBracketContainer()
{
return _bracketContainer;
}
@Override
public void documentAboutToBeChanged(DocumentEvent event)
{
_docIsChanging = true;
}
@Override
public void documentChanged(DocumentEvent event)
{
// TODO: optimize - put the event in an events list so that the processor could parse only part of the file
_docIsChanging = false;
synchronized (_docChangedLock)
{
_documentChanged = true;
if( _thread == null)
{
_thread = new Thread(this, "ProcessingThread"); //$NON-NLS-1$
_thread.start();
}
}
}
}