Commit 29371b34 authored by Sebastian Pretscher's avatar Sebastian Pretscher

Changed some thread handling

parent 6abf08f3
......@@ -15,6 +15,7 @@ import org.eclipse.ui.texteditor.IDocumentProvider;
import de.tum.in.www2.cupplugin.editors.CupPartionScanner;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.editors.RevisionManager;
public class Controller {
......@@ -44,6 +45,8 @@ public class Controller {
private List<DocumentEvent> documentEvents;
private final EnumSet<JobsToDo> jobElements = EnumSet
.noneOf(JobsToDo.class);
private long currentRevisionNumber = 0;
/*
* Static singleton getter
......@@ -116,6 +119,7 @@ public class Controller {
public void initialRun() {
addJobToDo(JobsToDo.parseCode);
addJobToDo(JobsToDo.buildTable);
myJob.schedule(0);
}
......@@ -130,9 +134,13 @@ public class Controller {
IDocument document = myEditor.getDocumentProvider().getDocument(
myEditor.getEditorInput());
currentRevisionNumber = RevisionManager.increment(document);
try {
ITypedRegion region = document.getPartition(event.getOffset());
if (event.getText().trim().length() == 0) {
//TODO: Space for performance improvements
if (event.getText().trim().length() == 0 && (document.getLength()<=(event.getOffset()+1) || document.getChar(event.getOffset()+1) == (' '))) {
System.out.println("0 Trim detected");
if (event.getText().equals(
System.getProperty("line.separator"))) {
// Some debug outut...
......@@ -211,10 +219,12 @@ public class Controller {
if (myJob.getState() == Job.NONE
|| (!myJob.running() && myJob.getState() == Job.SLEEPING)) {
myJob.cancel();
myJob.revNumber = RevisionManager.increment(document);
myJob.schedule(SET_CHANGED_AFTER_SECONDS * 1000);
} else {
RevisionManager.increment(document);
changeJobReRunRequested = System.currentTimeMillis();
}
}
......@@ -230,10 +240,11 @@ public class Controller {
// TODO:
// DELETE!
if (changeJobReRunRequested > 0) {
changeJobReRunRequested = 0;
long remainderOfDelay = (SET_CHANGED_AFTER_SECONDS * 100)
- (System.currentTimeMillis() - changeJobReRunRequested);
myJob.revNumber = RevisionManager.get(myEditor.getDocumentProvider().getDocument(
myEditor.getEditorInput()));
myJob.schedule((remainderOfDelay >= 0) ? remainderOfDelay : 0);
}
}
......
......@@ -19,14 +19,17 @@ import org.eclipse.ui.texteditor.IDocumentProvider;
import de.in.tum.www2.cup.CupContext;
import de.in.tum.www2.cup.CupParser;
import de.in.tum.www2.cup.LALRResult;
import de.in.tum.www2.cup.NoopErrorReporter;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.analysis.LocationPatchVisitor;
import de.in.tum.www2.cup.ast.ParserResult;
import de.in.tum.www2.cup.internal.internal_error;
import de.tum.in.www2.cupplugin.controller.Controller.JobsToDo;
import de.tum.in.www2.cupplugin.editors.CupEditorErrorReporter;
import de.tum.in.www2.cupplugin.editors.CupPartionScanner;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.editors.RevisionManager;
import de.tum.in.www2.cupplugin.model.Model;
public class DocumentDidChangeJob extends Job {
......@@ -38,6 +41,12 @@ public class DocumentDidChangeJob extends Job {
private EnumSet<JobsToDo> jobs;
private ParserResult result;
private CupContext context;
private LALRResult lalrResult;
private String codeText;
// Revision Number for checks
public long revNumber;
public DocumentDidChangeJob(CupTextEditor editor) {
super("" + editor.hashCode());
......@@ -51,35 +60,47 @@ public class DocumentDidChangeJob extends Job {
@Override
protected IStatus run(IProgressMonitor monitor) {
iAmCurrentlyRunning = true;
SetupJob setup = new SetupJob(this);
setup.setSystem(true);
setup.schedule();
try {
setup.join();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (setup.getResult() == Status.CANCEL_STATUS) {
return Status.CANCEL_STATUS;
}
// TODO: can we really works with the document just like that
// on this thread? What about changes that are happening
// to the document? We should probably copy the document
// data first or something !!!
// -> We should instead read the document into a buffer in the UI thread.
// and store it, along with the revision that we also get on the UI thread.
// -> The actual parsing and analysis can then be done on the background job.
// on this thread? What about changes that are happening
// to the document? We should probably copy the document
// data first or something !!!
// -> We should instead read the document into a buffer in the UI
// thread.
// and store it, along with the revision that we also get on the UI
// thread.
// -> The actual parsing and analysis can then be done on the background
// job.
// We need these null checks, because the document might have been
// closed already.
// We need these null checks, because the document might have been closed already.
if (myEditor == null)
return Status.CANCEL_STATUS;
IDocumentProvider provider = myEditor.getDocumentProvider();
if (provider == null)
return Status.CANCEL_STATUS;
IDocument document = provider.getDocument(myEditor.getEditorInput());
if (document == null)
return Status.CANCEL_STATUS;
Controller controller = Controller.getInstance(myEditor);
documentEvents = controller.popAllDocumentEvents();
jobs = controller.popJobsToDo();
if (jobs.contains(JobsToDo.locationPatch)
&& (jobs.contains(JobsToDo.parseCode) || jobs
......@@ -93,7 +114,7 @@ public class DocumentDidChangeJob extends Job {
int oldRemovedLength = 0;
int newLength = 0;
LocationPatchVisitor visitor = new LocationPatchVisitor(
oldRemovedFrom, oldRemovedLength, newLength);
oldRemovedFrom, oldRemovedLength, newLength);
if (result != null)
result.accept(visitor, null);
else {
......@@ -102,12 +123,13 @@ public class DocumentDidChangeJob extends Job {
}
if (jobs.contains(JobsToDo.parseCode)) {
String codeText = document.get();
InputStream in = new ByteArrayInputStream(codeText.getBytes());
IFile file = ((FileEditorInput) myEditor.getEditorInput()).getFile();
IFile file = ((FileEditorInput) myEditor.getEditorInput())
.getFile();
CupEditorErrorReporter errorReporter = new CupEditorErrorReporter(file);
CupEditorErrorReporter errorReporter = new CupEditorErrorReporter(
file);
CupParser p = new CupParser(errorReporter, in);
result = null;
context = null;
......@@ -121,22 +143,41 @@ public class DocumentDidChangeJob extends Job {
}
errorReporter.pushToUIThread();
if (result != null) {
// System.out.println(result.toString());
ParserResultJob resultModelJob = new ParserResultJob(result);
// System.out.println(result.toString());
ParserResultJob resultModelJob = new ParserResultJob(result,
revNumber);
resultModelJob.setSystem(true);
resultModelJob.schedule();
} else {
return Status.CANCEL_STATUS;
}
}
if (jobs.contains(JobsToDo.buildTable)) {
lalrResult = null;
try {
lalrResult = LALRResult.Compute(context,
context.start_production);
} catch (internal_error e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (lalrResult != null) {
LaLrResultJob resultLaLrModelJob = new LaLrResultJob(lalrResult, revNumber);
resultLaLrModelJob.setSystem(true);
resultLaLrModelJob.schedule();
} else {
return Status.CANCEL_STATUS;
}
}
System.out.println(jobs);
/*
*/
documentEvents.clear();
jobs.clear();
// nichts mehr ändern ab hier
iAmCurrentlyRunning = false;
CallbackJob cb = new CallbackJob(myEditor);
......@@ -162,11 +203,13 @@ public class DocumentDidChangeJob extends Job {
class ParserResultJob extends UIJob {
ParserResult result;
ParserResult parserResult;
long parserModelRevisionNumber;
public ParserResultJob(ParserResult result) {
public ParserResultJob(ParserResult result, long revisionNumber) {
super("Parser Result UI Job");
this.result = result;
this.parserResult = result;
this.parserModelRevisionNumber = revisionNumber;
}
@Override
......@@ -174,16 +217,97 @@ public class DocumentDidChangeJob extends Job {
IDocumentProvider provider = myEditor.getDocumentProvider();
if (provider != null) {
IDocument document = provider.getDocument(
myEditor.getEditorInput());
IDocument document = provider.getDocument(myEditor
.getEditorInput());
if (document != null) {
Model model = Model.getInstanceForDocument(document);
model.setASTModel(this.parserResult, revNumber);
return Status.OK_STATUS;
}
}
return Status.CANCEL_STATUS;
}
}
class LaLrResultJob extends UIJob {
LALRResult lalrReult;
long lalrResulRevisionNumber;
public LaLrResultJob(LALRResult result, long revisionNumber) {
super("LaLr Result UI Job");
this.lalrReult = result;
this.lalrResulRevisionNumber = revisionNumber;
}
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
IDocumentProvider provider = myEditor.getDocumentProvider();
if (provider != null) {
IDocument document = provider.getDocument(myEditor
.getEditorInput());
if (document != null) {
Model model = Model.getInstanceForDocument(document);
model.setASTModel(result);
model.setLaLrResultModel(this.lalrReult, lalrResulRevisionNumber);
return Status.OK_STATUS;
}
}
return Status.CANCEL_STATUS;
}
}
class SetupJob extends UIJob {
private DocumentDidChangeJob documentDidChangeJob;
public SetupJob(DocumentDidChangeJob documentDidChangeJob) {
super("Parswer Setup Job");
this.documentDidChangeJob = documentDidChangeJob;
}
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
Controller controller = Controller.getInstance(myEditor);
if (documentDidChangeJob.documentEvents == null
|| documentDidChangeJob.documentEvents.isEmpty()) {
documentDidChangeJob.documentEvents = controller
.popAllDocumentEvents();
} else {
documentDidChangeJob.documentEvents.addAll(controller
.popAllDocumentEvents());
}
if (documentDidChangeJob.jobs == null
|| documentDidChangeJob.jobs.isEmpty()) {
documentDidChangeJob.jobs = controller.popJobsToDo();
} else {
documentDidChangeJob.jobs.addAll(controller.popJobsToDo());
}
if (myEditor == null)
return Status.CANCEL_STATUS;
IDocumentProvider provider = documentDidChangeJob.myEditor
.getDocumentProvider();
if (provider == null)
return Status.CANCEL_STATUS;
IDocument document = provider
.getDocument(myEditor.getEditorInput());
if (revNumber != RevisionManager.get(document)) {
return Status.CANCEL_STATUS;
}
documentDidChangeJob.codeText = document.get();
return Status.OK_STATUS;
}
}
......
......@@ -51,8 +51,6 @@ class CTEDocumentListener implements IDocumentListener {
IDocument doc = event.getDocument();
RevisionManager.increment(doc);
//System.out.println("starting job chain"); // Log message TODO: DELETE!
Controller controller = Controller.getInstance(doc);
controller.notifyChange(event);
......
......@@ -6,6 +6,7 @@ import java.util.WeakHashMap;
import org.eclipse.jface.text.IDocument;
import de.in.tum.www2.cup.LALRResult;
import de.in.tum.www2.cup.ast.ParserResult;
public class Model {
......@@ -13,7 +14,13 @@ public class Model {
private static WeakHashMap<IDocument, Model> instances = new WeakHashMap<IDocument, Model> ();
private ParserResult astModel;
private final Object lock = new Object();
private long astModelRevisionNumber;
private LALRResult lalrModel;
private long lalrModelRevisionNumber;
private final Object parserModelLock = new Object();
private final Object lalrModellock = new Object();
private List<Object> modelObservers;
public static void deleteForDocument(IDocument document) {
......@@ -30,7 +37,7 @@ public class Model {
}
public void dispose() {
synchronized (lock) {
synchronized (parserModelLock) {
if (modelObservers != null)
modelObservers.clear();
}
......@@ -62,7 +69,7 @@ public class Model {
public void registerModelObserver(Object modelObserver) {
if (modelObserver == null)
return;
synchronized (lock) {
synchronized (parserModelLock) {
this.modelObservers.add(modelObserver);
}
}
......@@ -70,7 +77,7 @@ public class Model {
public boolean deRegisterModelObserver(Object modelObserver) {
if (modelObserver == null)
return false;
synchronized (lock) {
synchronized (parserModelLock) {
if (this.modelObservers.contains(modelObserver)) {
this.modelObservers.remove(modelObserver);
return true;
......@@ -80,14 +87,15 @@ public class Model {
}
public ParserResult getAstModel() {
synchronized(lock) {
synchronized(parserModelLock) {
return astModel;
}
}
public void setASTModel(ParserResult result) {
synchronized (lock) {
public void setASTModel(ParserResult result, long revisionNumber) {
synchronized (parserModelLock) {
this.astModel = result;
this.astModelRevisionNumber = revisionNumber;
for(Object observer : modelObservers) {
if(observer instanceof CupParserASTChangeObserver) {
((CupParserASTChangeObserver)observer).modelChanged(this);
......@@ -95,4 +103,38 @@ public class Model {
}
}
}
public void setAstModelRevisionNumber(long revisionNumber) {
synchronized(parserModelLock) {
this.astModelRevisionNumber = revisionNumber;
}
}
public long getAstModelRevisionNumber() {
return this.astModelRevisionNumber;
}
public LALRResult getLaLrResult() {
synchronized (lalrModellock) {
return this.lalrModel;
}
}
public void setLaLrResultModel(LALRResult result, long revisionNumber) {
synchronized (lalrModellock) {
this.lalrModel = result;
this.lalrModelRevisionNumber = revisionNumber;
//TODO: NotifyKram....
}
}
public void setLaLrModelRevisionNumber(long revisionNumber) {
synchronized (lalrModellock) {
this.lalrModelRevisionNumber = revisionNumber;
}
}
public long getLaLrRevisionNumber() {
return this.lalrModelRevisionNumber;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment