/* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.util.dialogrunner; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * A helper class that executes registered Runnable actions corresponding to * user responses in a dialog. This is to enable dialog execution in JalviewJS, * where everything must happen in a single thread of execution. That is, the * dialog has to 'know' all actions that follow a user choice, rather than * returning a response to allow a separate thread to decide the next action. * * @author jprocter */ public class DialogRunner implements DialogRunnerI { private Map> callbacks = new HashMap<>(); /** * Constructor */ public DialogRunner() { } @Override public DialogRunnerI addResponse(Object response, RunResponse action) { List actions = callbacks.get(response); if (actions == null) { actions = new ArrayList<>(); callbacks.put(response, actions); } actions.add(action); return this; } /** * Handles a response by running the chain of registered actions (if any). * Answers the list of responses run (in order). * * @param response */ @Override public List handleResponse(Object response) { List responsesRun = new ArrayList(); /* * this test is for NaN in Chrome */ if (response != null && !response.equals(response)) { return responsesRun; } runResponse(response, responsesRun); if (responsesRun.isEmpty()) { System.err.println("Did nothing for " + response); } return responsesRun; } /** * 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 alreadyRun) { /* * this test is for NaN in Chrome */ if (response != null && !response.equals(response)) { return; } List actions = response == null ? null : callbacks.get(response); if (actions == null) { System.err.println("Doing nothing for " + response); return; } for (RunResponse action : actions) { if (!alreadyRun.contains(action)) { action.setReturnValue(null); action.run(); alreadyRun.add(action); Object returnValue = action.getReturnValue(); if (returnValue != null) { /* * RunResponse wants to chain another action */ runResponse(returnValue, alreadyRun); } break; } } } }