From be9359e9a28efb6aade9bdac054d76b4f9452c47 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Mon, 2 Jul 2018 15:34:02 +0100 Subject: [PATCH] JAL-3048 allow a chain of responses for a particular response code (needed when intermediate dialogs are raised which determine if rest of chain executes) --- src/jalview/util/dialogrunner/DialogRunner.java | 93 ++++++++++++++++---- src/jalview/util/dialogrunner/DialogRunnerI.java | 1 - .../util/dialogrunner/DialogRunnerTest.java | 28 ++++++ 3 files changed, 106 insertions(+), 16 deletions(-) diff --git a/src/jalview/util/dialogrunner/DialogRunner.java b/src/jalview/util/dialogrunner/DialogRunner.java index fc1a73d..b631128 100644 --- a/src/jalview/util/dialogrunner/DialogRunner.java +++ b/src/jalview/util/dialogrunner/DialogRunner.java @@ -39,7 +39,7 @@ import java.util.Map; public class DialogRunner implements DialogRunnerI { - private Map callbacks = new java.util.HashMap<>(); + private Map> callbacks = new java.util.HashMap<>(); public T dialog; @@ -54,9 +54,12 @@ public class DialogRunner implements DialogRunnerI */ public void resetResponses() { - for (RunResponse response : callbacks.values()) + for (List lr : callbacks.values()) { - response.reset(); + for (RunResponse response : lr) + { + response.reset(); + } } responses.clear(); firstRunWasCalled = false; @@ -65,11 +68,59 @@ public class DialogRunner implements DialogRunnerI @Override public T response(RunResponse action) { - callbacks.put(action.ourTrigger, action); + return addResponse(false, action); + } + + /** + * insert a response at the beginning of the chain for the action. Useful to add + * pre-action validations local to the Dialog class + * + * @param action + * @return + */ + public T firstResponse(RunResponse action) + { + return addResponse(true, action); + } + + protected T addResponse(boolean prePend, RunResponse action) + { + List laction = callbacks.get(action.ourTrigger); + if (laction == null) + { + laction = new ArrayList<>(); + callbacks.put(action.ourTrigger, laction); + } + if (prePend) + { + laction.add(0,action); + } else { + laction.add(action); + } return dialog; } /** + * + * @param action + * @return true if action is a registered callback + */ + public boolean isRegistered(RunResponse action) + { + List resp = callbacks.get(action.ourTrigger); + if (resp != null) + { + for (RunResponse r : resp) + { + if (r == action) + { + return true; + } + } + } + return false; + } + /** * handle a response * * @param responseCode @@ -125,24 +176,36 @@ public class DialogRunner implements DialogRunnerI private void run(Response response) { responses.add(response); - RunResponse action = callbacks.get(response); - if (action == null) + List laction = callbacks.get(response); + + if (laction == null) { System.err.println("Doing nothing for " + response); return; } - if (action.wasRun) + boolean wasRun = false; + int num = 0; + for (RunResponse action : laction) { - System.err - .println("IMPLEMENTATION ERROR: Cycle in DialogRunner ! for " - + action); + num++; + // find next action to execute + if (!action.wasRun) + { + System.err + .println("Executing action (" + num + ") for " + response); + wasRun = true; + action.wasRun = true; + action.run(); + if (action.returned != null) + { + run(action.returned); + } + break; + } } - System.err.println("Executing action for " + response); - action.wasRun = true; - action.run(); - if (action.returned != null) + if (!wasRun) { - run(action.returned); + System.err.println("Did nothing for " + response); } } diff --git a/src/jalview/util/dialogrunner/DialogRunnerI.java b/src/jalview/util/dialogrunner/DialogRunnerI.java index 9df6d33..aaeb304 100644 --- a/src/jalview/util/dialogrunner/DialogRunnerI.java +++ b/src/jalview/util/dialogrunner/DialogRunnerI.java @@ -38,5 +38,4 @@ public interface DialogRunnerI * @return the dialog */ T response(RunResponse action); - } diff --git a/test/jalview/util/dialogrunner/DialogRunnerTest.java b/test/jalview/util/dialogrunner/DialogRunnerTest.java index e956124..e69ae87 100644 --- a/test/jalview/util/dialogrunner/DialogRunnerTest.java +++ b/test/jalview/util/dialogrunner/DialogRunnerTest.java @@ -42,6 +42,16 @@ public class DialogRunnerTest returned = new Response("DONE"); } }; + final RunResponse befok = new RunResponse("OK") + { + + @Override + public void run() + { + returned = new Response("OK"); + } + }; + cancel = new RunResponse("CANCEL") { @Override @@ -68,8 +78,12 @@ public class DialogRunnerTest } }; + Assert.assertFalse(dialog.runner.isRegistered(ok)); + dialog.response(ok).response(cancel).response(help).response(ineed); + Assert.assertTrue(dialog.runner.isRegistered(ok)); + Assert.assertFalse(dialog.runner.firstRunWasCalled); dialog.doDialog("OK"); // OK called, nothing else. @@ -97,5 +111,19 @@ public class DialogRunnerTest Assert.assertFalse(ok.wasRun); Assert.assertEquals(ineed.returned, ooh); Assert.assertEquals(dialog.runner.responses.size(), 3); + + // TODO: test prepend and chained execution of tasks for a response. + Assert.assertFalse(dialog.runner.isRegistered(befok)); + dialog.runner.firstResponse(befok); + + Assert.assertTrue(dialog.runner.isRegistered(befok)); + Assert.assertTrue(dialog.runner.isRegistered(ok)); + + dialog.runner.resetResponses(); + + dialog.doDialog("OK"); + Assert.assertTrue(befok.wasRun); + Assert.assertTrue(ok.wasRun); + Assert.assertEquals(dialog.runner.responses.size(), 3); } } -- 1.7.10.2