JAL-3048 DialogRunner changes (wip)
[jalview.git] / src / jalview / util / dialogrunner / DialogRunner.java
index 05a63c7..59f3c98 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.util.dialogrunner;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -36,43 +37,32 @@ import java.util.Map;
  *          the actual dialog that will be shown - which will also initiate the
  *          response chain.
  */
-public class DialogRunner<T extends DialogRunnerI> implements DialogRunnerI
+public class DialogRunner implements DialogRunnerI
 {
+  private Map<Object, List<RunResponse>> callbacks = new HashMap<>();
 
-  private Map<Response, List<RunResponse>> callbacks = new java.util.HashMap<>();
+  private boolean firstRunWasCalled = false;
 
-  public T dialog;
-
-  public DialogRunner(T ourDialog)
+  /**
+   * Constructor
+   */
+  public DialogRunner()
   {
-    dialog = ourDialog;
   }
 
   /**
-   * clear all 'was ran' flags so responses can be called again, and firstRun will
-   * trigger response execution
+   * Reset so handleResponse will start response execution
    */
   public void resetResponses()
   {
-    for (List<RunResponse> lr : callbacks.values())
-    {
-      for (RunResponse response : lr)
-      {
-        response.reset();
-      }
-    }
-    responses.clear();
-    if (defaultResponse != null)
-    {
-      defaultResponse.reset();
-    }
     firstRunWasCalled = false;
   }
 
   @Override
-  public T addResponse(RunResponse action)
+  public DialogRunnerI addResponse(RunResponse action)
   {
-    return addResponse(false, action);
+    addResponse(false, action);
+    return this;
   }
 
   /**
@@ -82,26 +72,26 @@ public class DialogRunner<T extends DialogRunnerI> implements DialogRunnerI
    * @param action
    * @return
    */
-  public T firstResponse(RunResponse action)
+  public DialogRunnerI setFirstResponse(RunResponse action)
   {
     return addResponse(true, action);
   }
 
-  protected T addResponse(boolean prePend, RunResponse action)
+  protected DialogRunnerI addResponse(boolean prePend, RunResponse action)
   {
-    List<RunResponse> laction = callbacks.get(action.ourTrigger);
-    if (laction == null)
+    List<RunResponse> actions = callbacks.get(action.getTrigger());
+    if (actions == null)
     {
-      laction = new ArrayList<>();
-      callbacks.put(action.ourTrigger, laction);
+      actions = new ArrayList<>();
+      callbacks.put(action.getTrigger(), actions);
     }
     if (prePend)
     {
-      laction.add(0,action);
+      actions.add(0,action);
     } else {
-      laction.add(action);
+      actions.add(action);
     }
-    return dialog;
+    return this;
   }
 
   /**
@@ -111,160 +101,89 @@ public class DialogRunner<T extends DialogRunnerI> implements DialogRunnerI
    */
   public boolean isRegistered(RunResponse action)
   {
-    List<RunResponse> resp = callbacks.get(action.ourTrigger);
-    if (resp != null)
-    {
-      for (RunResponse r : resp)
-      {
-        if (r == action)
-        {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-  /**
-   * handle a response
-   * 
-   * @param responseCode
-   */
-  public void run(int responseCode)
-  {
-    run(new Response(responseCode));
-  }
-
-  public void run(String responseString)
-  {
-    run(new Response(responseString));
-  }
-
-  public void run(Object responseObj)
-  {
-    run(new Response(responseObj));
+    List<RunResponse> resp = callbacks.get(action.getTrigger());
+    return resp != null && resp.contains(action);
   }
 
   /**
-   * start of response handling.
+   * Handles a response by running the chain of registered actions (if any).
+   * Answers the list of responses run (in order).
    * 
-   * @param responseCode
+   * @param response
    */
-  public void firstRun(int responseCode)
-  {
-    doFirstRun(new Response(responseCode));
-  }
-
-  public void firstRun(String responseString)
+  @Override
+  public List<RunResponse> handleResponse(Object response)
   {
-    doFirstRun(new Response(responseString));
-  }
+       List<RunResponse> responsesRun = new ArrayList<RunResponse>();
 
-  public void firstRun(Object responseObj)
-  {
-    if (responseObj != null && !responseObj.equals(responseObj))
+    /*
+        * this test is for NaN in Chrome
+        */
+    if (response != null && !response.equals(response))
     {
-      // NaN is an object in Chrome - catch this weirdness
-      // this so we don't cause issues later
-      return;
+      return responsesRun;
     }
-    doFirstRun(new Response(responseObj));
-  }
-
-
-  boolean firstRunWasCalled = false;
-
-  private void doFirstRun(Response response)
-  {
+    
+    /*
+     * failsafe check for illegal duplicate call(?)
+     */
     if (firstRunWasCalled)
     {
-      return;
+//      return responsesRun;
     }
     firstRunWasCalled = true;
-    run(response);
+    
+       runResponse(response, responsesRun);
+    if (responsesRun.isEmpty())
+    {
+      System.err.println("Did nothing for " + response);
+    }
+    
+    return responsesRun;
   }
 
-  private void run(Response response)
+  /**
+   * Runs any response handlers registered for the given response. If any
+   * response provides a return value, then the handler for that value is
+   * run next recursively. Handlers are only run once.
+   * 
+   * @param response
+ * @param alreadyRun 
+   */
+  private void runResponse(Object response, List<RunResponse> alreadyRun)
   {
-    if (response.objresp != null
-            && !response.objresp.equals(response.objresp))
+       /*
+        * this test is for NaN in Chrome
+        */
+    if (response != null && !response.equals(response))
     {
-      // NaN is an object in Chrome - catch this weirdness
-      // this so we don't cause issues later
       return;
     }
-    responses.add(response);
     
-    List<RunResponse> laction = response.isNull() ? null : callbacks.get(response);
+    List<RunResponse> actions = response == null ? null : callbacks.get(response);
 
-    if (laction == null)
+    if (actions == null)
     {
-      if (defaultResponse != null)
-      {
-        defaultResponse.ourTrigger = response;
-        defaultResponse.wasRun = true;
-        defaultResponse.run();
-      }
-      else
-      {
-        System.err.println("Doing nothing for " + response);
-      }
+      System.err.println("Doing nothing for " + response);
       return;
     }
-    boolean wasRun = false;
-    int num = 0;
-    for (RunResponse action : laction)
+    for (RunResponse action : actions)
     {
-      num++;
-      // find next action to execute
-      if (!action.wasRun)
+      if (!alreadyRun.contains(action))
       {
-        System.err
-                .println("Executing action (" + num + ") for " + response);
-        wasRun = true;
-        action.wasRun = true;
+       action.setReturnValue(null);
         action.run();
-        if (action.returned != null)
+        alreadyRun.add(action);
+        Object returnValue = action.getReturnValue();
+               if (returnValue != null)
         {
-          run(action.returned);
+                 /*
+                  * RunResponse wants to chain another action
+                  */
+          runResponse(returnValue, alreadyRun);
         }
         break;
       }
     }
-    if (!wasRun)
-    {
-      System.err.println("Did nothing for " + response);
-    }
-  }
-
-  List<Response> responses = new ArrayList<>();
-
-  RunResponse defaultResponse = null;
-
-  /**
-   * Convenience wrapper for setting default response to a runnable
-   * 
-   * @param runnable
-   */
-  public void setDefaultResponse(Runnable runnable)
-  {
-    defaultResponse = new RunResponse(runnable)
-    {
-      @Override
-      public void run()
-      {
-        runnable.run();
-      }
-    };
-  }
-
-  /**
-   * Default responses are called once, with ourTrigger set to the unHandled
-   * response received
-   * 
-   * @param runnable
-   */
-  public void setDefaultResponse(RunResponse runnable)
-  {
-    defaultResponse = runnable;
   }
 }