//----------------------------------------------------------------------------// // // // A b s t r a c t S y s t e m S t e p // // // //----------------------------------------------------------------------------// // <editor-fold defaultstate="collapsed" desc="hdr"> // // Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. // // This software is released under the GNU General Public License. // // Goto http://kenai.com/projects/audiveris to report bugs or suggestions. // //----------------------------------------------------------------------------// // </editor-fold> package omr.step; import omr.Main; import omr.sheet.Sheet; import omr.sheet.SystemInfo; import omr.util.OmrExecutors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.Callable; /** * Class {@code AbstractSystemStep} is a basis for any step working in * parallel on the sheet systems. * * @author Hervé Bitteur */ public abstract class AbstractSystemStep extends AbstractStep { //~ Static fields/initializers --------------------------------------------- /** Usual logger utility */ private static final Logger logger = LoggerFactory.getLogger( AbstractSystemStep.class); //~ Constructors ----------------------------------------------------------- //--------------------// // AbstractSystemStep // //--------------------// /** * Creates a new AbstractSystemStep object. * * @param level score level only or sheet level * @param mandatory step must be done before any output * @param label The title of the related (or most relevant) view tab * @param description A step description for the end user */ public AbstractSystemStep (String name, Level level, Mandatory mandatory, String label, String description) { super(name, level, mandatory, label, description); } //~ Methods ---------------------------------------------------------------- // //-------------// // clearErrors // //-------------// @Override public void clearErrors (Sheet sheet) { // Void, since this is done system per system } //-------------------// // clearSystemErrors // //-------------------// /** * Clear the errors of just the provided system * * @param system the system to clear of errors */ protected void clearSystemErrors (SystemInfo system) { if (Main.getGui() != null) { system.getSheet().getErrorsEditor().clearSystem(this, system.getId()); } } //----------// // doSystem // //----------// /** * Actually perform the step on the given system. This method must be * actually defined for any concrete system step. * * @param system the system to process * @throws StepException raised if processing failed */ public abstract void doSystem (SystemInfo system) throws StepException; //------// // doit // //------// /** * Actually perform the step. * This method is run when this step is explicitly selected * * @param systems systems to process (null means all systems) * @param sheet the sheet to process * @throws StepException raised if processing failed */ @Override public void doit (Collection<SystemInfo> systems, Sheet sheet) throws StepException { // Preliminary actions doProlog(systems, sheet); // Processing system per system doitPerSystem(systems, sheet); // Final actions doEpilog(systems, sheet); } //----------// // doEpilog // //----------// /** * Final processing for this step, once all systems have been * processed. * * @param systems the systems which have been updated * @throws StepException raised if processing failed */ protected void doEpilog (Collection<SystemInfo> systems, Sheet sheet) throws StepException { // Empty by default } //----------// // doProlog // //----------// /** * Do preliminary common work before all systems processings are * launched in parallel. * * @param systems the systems which will be updated * @throws StepException raised if processing failed */ protected void doProlog (Collection<SystemInfo> systems, Sheet sheet) throws StepException { // Empty by default } //---------------// // doitPerSystem // //---------------// /** * Launch the system processing in parallel, one task per system * * @param systems the systems to process * @param sheet the containing sheet */ private void doitPerSystem (Collection<SystemInfo> systems, final Sheet sheet) { try { Collection<Callable<Void>> tasks = new ArrayList<>(); if (systems == null) { systems = sheet.getSystems(); } for (SystemInfo info : systems) { final SystemInfo system = info; tasks.add( new Callable<Void>() { @Override public Void call () throws Exception { try { logger.debug("{} doSystem #{}", AbstractSystemStep.this, system.idString()); doSystem(system); } catch (Exception ex) { logger.warn(sheet.getLogPrefix() + "Interrupt on " + system.idString(), ex); } return null; } }); } // Launch all system tasks in parallel and wait for their completion OmrExecutors.getLowExecutor().invokeAll(tasks); } catch (InterruptedException ex) { logger.warn("doitPerSystem got interrupted"); throw new ProcessingCancellationException(ex); } } }