From: Mateusz Warowny Date: Tue, 4 Jul 2023 11:31:25 +0000 (+0200) Subject: JAL-4199 Implement AlignCalcWorker adapter for annot tasks X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=4ad368a5d0d8ba69afc2048e1f97b60d0f2e075b JAL-4199 Implement AlignCalcWorker adapter for annot tasks --- diff --git a/src/jalview/ws2/actions/annotation/AlignCalcWorkerAdapter.java b/src/jalview/ws2/actions/annotation/AlignCalcWorkerAdapter.java new file mode 100644 index 0000000..7e8724a --- /dev/null +++ b/src/jalview/ws2/actions/annotation/AlignCalcWorkerAdapter.java @@ -0,0 +1,138 @@ +package jalview.ws2.actions.annotation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import jalview.api.AlignViewportI; +import jalview.api.AlignmentViewPanel; +import jalview.api.PollableAlignCalcWorkerI; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.workers.AlignCalcWorker; +import jalview.ws.params.ArgumentI; +import jalview.ws2.actions.alignment.AlignmentResult; +import jalview.ws2.actions.api.JobI; +import jalview.ws2.actions.api.TaskEventListener; +import jalview.ws2.actions.api.TaskI; +import jalview.ws2.api.Credentials; +import jalview.ws2.api.JobStatus; + +public class AlignCalcWorkerAdapter extends AlignCalcWorker implements PollableAlignCalcWorkerI +{ + private final AnnotationAction action; + + private final List args; + + private final Credentials credentials; + + private TaskI currentTask = null; + + private TaskEventListener internalTaskListener = new TaskEventListener<>() + { + @Override + public void taskCompleted(TaskI source, AnnotationResult result) + { + updateOurAnnots(result.getAnnotations()); + } + }; + + // task event listeners managed by this worker, passed to each creates task + private List> taskListeners = new CopyOnWriteArrayList<>(); + { + taskListeners.add(internalTaskListener); + } + + public AlignCalcWorkerAdapter(AlignViewportI alignViewport, AlignmentViewPanel alignPanel, AnnotationAction action, + List args, Credentials credentials) + { + super(alignViewport, alignPanel); + this.action = action; + this.args = args; + this.credentials = credentials; + } + + @Override + public void updateAnnotation() + { + + } + + private void updateOurAnnots(List newAnnots) + { + List oldAnnots = ourAnnots != null ? ourAnnots : List.of(); + AlignmentI alignment = alignViewport.getAlignment(); + for (AlignmentAnnotation annotation : oldAnnots) + if (!newAnnots.contains(annotation)) + alignment.deleteAnnotation(annotation); + for (AlignmentAnnotation annotation : newAnnots) + alignment.validateAnnotation(annotation); + ap.adjustAnnotationHeight(); + ourAnnots = Collections.synchronizedList(newAnnots); + } + + @Override + public synchronized void startUp() throws Throwable + { + if (alignViewport.isClosed()) + { + calcMan.disableWorker(this); + abortAndDestroy(); + throw new IllegalStateException("Starting calculation for closed viewport"); + } + currentTask = action.createTask(alignViewport, args, credentials); + for (var listener : taskListeners) + currentTask.addTaskEventListener(listener); + currentTask.init(); + } + + @Override + public boolean poll() throws Throwable + { + return currentTask.poll(); + } + + @Override + public synchronized void cancel() + { + try + { + currentTask.cancel(); + } finally + { + for (var listener : taskListeners) + currentTask.removeTaskEventListener(listener); + } + } + + @Override + public synchronized void done() + { + try + { + currentTask.complete(); + } catch (Exception e) + { + } finally + { + for (var listener : taskListeners) + currentTask.removeTaskEventListener(listener); + } + } + + public void addTaskEventListener(TaskEventListener listener) + { + taskListeners.add(listener); + if (currentTask != null) + currentTask.addTaskEventListener(listener); + } + + public void removeTaskEventListener(TaskEventListener listener) + { + taskListeners.remove(listener); + if (currentTask != null) + currentTask.removeTaskEventListener(listener); + } +}