--- /dev/null
+package jalview.api;
+
+public interface AlignCalcManagerI
+{
+
+
+ /**
+ * tell manager that a worker is initialised and has started to run
+ * @param worker
+ */
+ void notifyStart(AlignCalcWorkerI worker);
+
+ /**
+ * check if a calculation of this type is already active
+ * @param worker
+ * @return
+ */
+ boolean alreadyDoing(AlignCalcWorkerI worker);
+
+ /**
+ * tell manager that worker is now processing data
+ * @param worker
+ */
+ void notifyWorking(AlignCalcWorkerI worker);
+
+
+ /**
+ * notify manager that the worker has completed, and results may be ready to collect
+ * @param worker
+ */
+ void workerComplete(AlignCalcWorkerI worker);
+
+ /**
+ * indicate that a worker like this cannot run on the platform and shouldn't be started again
+ * @param worker
+ */
+ void workerCannotRun(AlignCalcWorkerI worker);
+
+ /**
+ * launch a new worker
+ * @param worker
+ */
+ void startWorker(AlignCalcWorkerI worker);
+
+}
--- /dev/null
+package jalview.workers;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import jalview.api.AlignCalcManagerI;
+import jalview.api.AlignCalcWorkerI;
+
+public class AlignCalcManager implements AlignCalcManagerI
+{
+ private List<Class> blackList=new ArrayList<Class>();
+ /**
+ * global record of calculations in progress
+ */
+ private static Hashtable<Class,AlignCalcWorkerI> inProgress=new Hashtable<Class,AlignCalcWorkerI>();
+ /**
+ * record of calculations pending or in progress in the current context
+ */
+ private Map<Class,List<AlignCalcWorkerI>> updating=new Hashtable<Class,List<AlignCalcWorkerI>>();
+
+ @Override
+ public void notifyStart(AlignCalcWorkerI worker)
+ {
+ List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
+ if (upd==null)
+ {
+ updating.put(worker.getClass(), upd=new ArrayList<AlignCalcWorkerI>());
+ }
+ upd.add(worker);
+ }
+
+ @Override
+ public boolean alreadyDoing(AlignCalcWorkerI worker)
+ {
+ return inProgress.containsKey(worker.getClass());
+ }
+
+ @Override
+ public void notifyWorking(AlignCalcWorkerI worker)
+ {
+ // TODO: decide if we should throw exceptions here if multiple workers start to work
+ if (inProgress.get(worker.getClass())!=null)
+ {
+ System.err.println("Warning: Multiple workers are running of type "+worker.getClass());
+ }
+ inProgress.put(worker.getClass(), worker);
+
+ }
+
+ @Override
+ public void workerComplete(AlignCalcWorkerI worker)
+ {
+ inProgress.remove(worker);
+ }
+
+ @Override
+ public void workerCannotRun(AlignCalcWorkerI worker)
+ {
+ blackList.add(worker.getClass());
+ }
+ public boolean isBlackListed(Class workerType)
+ {
+ return blackList.contains(workerType);
+ }
+
+ @Override
+ public void startWorker(AlignCalcWorkerI worker)
+ {
+ new Thread(worker).start();
+ }
+}
--- /dev/null
+/**
+ *
+ */
+package jalview.workers;
+
+import jalview.api.AlignCalcManagerI;
+import jalview.api.AlignCalcWorkerI;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+
+/**
+ * Base class for alignment calculation workers
+ * @author jimp
+ *
+ */
+public abstract class AlignCalcWorker implements AlignCalcWorkerI
+{
+ /**
+ * manager and data source for calculations
+ */
+ protected AlignViewportI alignViewport;
+ protected AlignCalcManagerI calcMan;
+ protected AlignmentViewPanel ap;
+
+ public AlignCalcWorker(AlignViewportI alignViewport,
+ AlignmentViewPanel alignPanel)
+ {
+ this.alignViewport = alignViewport;
+ calcMan=alignViewport.getCalcManager();
+ ap = alignPanel;
+ }
+ protected void abortAndDestroy()
+ {
+ if (calcMan!=null) {
+ calcMan.workerComplete(this);
+ }
+ alignViewport=null;
+ calcMan=null;
+ ap=null;
+
+ }
+
+
+}