/* * Copyright (C) 2014 Alfons Wirtz * website www.freerouting.net * * This program 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. * * This program 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 at <http://www.gnu.org/licenses/> * for more details. * * InteractiveActionThread.java * * Created on 2. Maerz 2006, 07:23 * */ package interactive; /** * Used for running an interactive action in a seperate Thread, * that can be stopped by the user. * * @author Alfons Wirtz */ public abstract class InteractiveActionThread extends Thread implements datastructures.Stoppable { public static InteractiveActionThread get_autoroute_instance(BoardHandling p_board_handling) { return new AutorouteThread(p_board_handling); } public static InteractiveActionThread get_batch_autorouter_instance(BoardHandling p_board_handling) { return new BatchAutorouterThread(p_board_handling); } public static InteractiveActionThread get_fanout_instance(BoardHandling p_board_handling) { return new FanoutThread(p_board_handling); } public static InteractiveActionThread get_pull_tight_instance(BoardHandling p_board_handling) { return new PullTightThread(p_board_handling); } public static InteractiveActionThread get_read_logfile_instance(BoardHandling p_board_handling, java.io.InputStream p_input_stream) { return new ReadLogfileThread(p_board_handling, p_input_stream); } /** Creates a new instance of InteractiveActionThread */ protected InteractiveActionThread(BoardHandling p_board_handling) { this.hdlg = p_board_handling; } protected abstract void thread_action(); public void run() { thread_action(); hdlg.repaint(); } public synchronized void request_stop() { stop_requested = true; } public synchronized boolean is_stop_requested() { return stop_requested; } public synchronized void draw(java.awt.Graphics p_graphics) { // Can be overwritten in derived classes. } private boolean stop_requested = false; public final BoardHandling hdlg; private static class AutorouteThread extends InteractiveActionThread { private AutorouteThread(BoardHandling p_board_handling) { super(p_board_handling); } protected void thread_action() { if (!(hdlg.interactive_state instanceof SelectedItemState)) { return; } InteractiveState return_state = ((SelectedItemState) hdlg.interactive_state).autoroute(this); hdlg.set_interactive_state(return_state); } } private static class FanoutThread extends InteractiveActionThread { private FanoutThread(BoardHandling p_board_handling) { super(p_board_handling); } protected void thread_action() { if (!(hdlg.interactive_state instanceof SelectedItemState)) { return; } InteractiveState return_state = ((SelectedItemState) hdlg.interactive_state).fanout(this); hdlg.set_interactive_state(return_state); } } private static class PullTightThread extends InteractiveActionThread { private PullTightThread(BoardHandling p_board_handling) { super(p_board_handling); } protected void thread_action() { if (!(hdlg.interactive_state instanceof SelectedItemState)) { return; } InteractiveState return_state = ((SelectedItemState) hdlg.interactive_state).pull_tight(this); hdlg.set_interactive_state(return_state); } } private static class ReadLogfileThread extends InteractiveActionThread { private ReadLogfileThread(BoardHandling p_board_handling, java.io.InputStream p_input_stream) { super(p_board_handling); this.input_stream = p_input_stream; } protected void thread_action() { java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("interactive.resources.InteractiveState", hdlg.get_locale()); boolean saved_board_read_only = hdlg.is_board_read_only(); hdlg.set_board_read_only(true); String start_message = resources.getString("logfile") + " " + resources.getString("stop_message"); hdlg.screen_messages.set_status_message(start_message); hdlg.screen_messages.set_write_protected(true); boolean done = false; InteractiveState previous_state = hdlg.interactive_state; if (!hdlg.logfile.start_read(this.input_stream)) { done = true; } boolean interrupted = false; int debug_counter = 0; hdlg.get_panel().board_frame.refresh_windows(); hdlg.paint_immediately = true; while (!done) { if (is_stop_requested()) { interrupted = true; done = true; } ++debug_counter; LogfileScope logfile_scope = hdlg.logfile.start_read_scope(); if (logfile_scope == null) { done = true; // end of logfile } if (!done) { try { InteractiveState new_state = logfile_scope.read_scope(hdlg.logfile, hdlg.interactive_state, hdlg); if (new_state == null) { System.out.println("BoardHandling:read_logfile: inconsistent logfile scope"); new_state = previous_state; } hdlg.repaint(); hdlg.set_interactive_state(new_state); } catch (Exception e) { done = true; } } } hdlg.paint_immediately = false; try { this.input_stream.close(); } catch (java.io.IOException e) { System.out.println("ReadLogfileThread: unable to close input stream"); } hdlg.get_panel().board_frame.refresh_windows(); hdlg.screen_messages.set_write_protected(false); String curr_message; if (interrupted) { curr_message = resources.getString("interrupted"); } else { curr_message = resources.getString("completed"); } String end_message = resources.getString("logfile") + " " + curr_message; hdlg.screen_messages.set_status_message(end_message); hdlg.set_board_read_only(saved_board_read_only); hdlg.get_panel().board_frame.repaint_all(); } private final java.io.InputStream input_stream; } }