public class DialogRunner<T extends DialogRunnerI> implements DialogRunnerI
{
- private Map<Response, RunResponse> callbacks = new java.util.HashMap<>();
+ private Map<Response, List<RunResponse>> callbacks = new java.util.HashMap<>();
public T dialog;
*/
public void resetResponses()
{
- for (RunResponse response : callbacks.values())
+ for (List<RunResponse> lr : callbacks.values())
{
- response.reset();
+ for (RunResponse response : lr)
+ {
+ response.reset();
+ }
}
responses.clear();
firstRunWasCalled = false;
@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<RunResponse> 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<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
private void run(Response response)
{
responses.add(response);
- RunResponse action = callbacks.get(response);
- if (action == null)
+ List<RunResponse> 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);
}
}
returned = new Response("DONE");
}
};
+ final RunResponse befok = new RunResponse("OK")
+ {
+
+ @Override
+ public void run()
+ {
+ returned = new Response("OK");
+ }
+ };
+
cancel = new RunResponse("CANCEL")
{
@Override
}
};
+ 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.
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);
}
}