//----------------------------------------------------------------------------// // // // G l y p h T a s k // // // //----------------------------------------------------------------------------// // <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.script; import omr.glyph.Glyphs; import omr.glyph.Shape; import omr.glyph.facets.Glyph; import omr.sheet.Sheet; import omr.sheet.SystemInfo; import omr.step.Stepping; import omr.step.Steps; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; /** * Class {@code GlyphTask} handles a collection of glyphs. * These glyphs may already exist (as in a plain {@link GlyphUpdateTask}) * or remain to be created (as in {@link InsertTask})</p> * * <h4>Glyphs and sections in a script:<br/> * <img src="doc-files/script.jpg"/> * </h4> * * @author Hervé Bitteur */ @XmlAccessorType(XmlAccessType.NONE) public abstract class GlyphTask extends SheetTask { //~ Instance fields -------------------------------------------------------- /** The collection of glyphs which are concerned by this task */ protected Set<Glyph> glyphs; /** The set of (pre) impacted systems, using status before action */ protected SortedSet<SystemInfo> initialSystems; //~ Constructors ----------------------------------------------------------- //-----------// // GlyphTask // //-----------// /** * Creates a new GlyphTask object. * * @param sheet the sheet impacted * @param glyphs the collection of glyphs concerned by this task */ protected GlyphTask (Sheet sheet, Collection<Glyph> glyphs) { super(sheet); // Check parameters if ((glyphs == null) || glyphs.isEmpty()) { throw new IllegalArgumentException( getClass().getSimpleName() + " needs at least one glyph"); } this.glyphs = new TreeSet<>(Glyph.byAbscissa); this.glyphs.addAll(glyphs); } //-----------// // GlyphTask // //-----------// /** * Creates a new GlyphTask object * * @param sheet the sheet impacted */ protected GlyphTask (Sheet sheet) { super(sheet); } //-----------// // GlyphTask // //-----------// /** No-arg constructor for JAXB only */ protected GlyphTask () { } //~ Methods ---------------------------------------------------------------- //--------// // epilog // //--------// @Override public void epilog (Sheet sheet) { Stepping.reprocessSheet( Steps.valueOf(Steps.SYMBOLS), sheet, getImpactedSystems(sheet), false); } //--------------------// // getImpactedSystems // //--------------------// /** * Report the set of systems that are impacted by the action * * @param sheet the containing sheet * @return the ordered set of impacted systems */ public SortedSet<SystemInfo> getImpactedSystems (Sheet sheet) { SortedSet<SystemInfo> impactedSystems = new TreeSet<>(); impactedSystems.addAll(initialSystems); impactedSystems.addAll(retrieveCurrentImpact(sheet)); return impactedSystems; } //------------------// // getInitialGlyphs // //------------------// /** * Report the collection of initial glyphs * * @return the impactedGlyphs */ public Set<Glyph> getInitialGlyphs () { return glyphs; } //------------------// // impactAllSystems // //------------------// /** * Set the impacted systems as all systems */ public void impactAllSystems () { initialSystems.addAll(sheet.getSystems()); } //--------// // prolog // //--------// @Override public void prolog (Sheet sheet) { super.prolog(sheet); this.sheet = sheet; // Make sure the concrete sections and glyphs are available if (glyphs == null) { retrieveGlyphs(); } initialSystems = retrieveCurrentImpact(sheet); } //-----------------// // internalsString // //-----------------// @Override protected String internalsString () { StringBuilder sb = new StringBuilder(super.internalsString()); if (glyphs != null) { sb.append(" ") .append(Glyphs.toString(glyphs)); } else { sb.append(" no-glyphs"); } return sb.toString(); } //-----------// // remaining // //-----------// /** * Report the collection of systems that follow the provided one * * @param system the one after which we pick any system * @return the remaining portion of the sequence of systems in the sheet */ protected Collection<SystemInfo> remaining (SystemInfo system) { List<SystemInfo> all = sheet.getSystems(); return all.subList(all.indexOf(system) + 1, all.size()); } //-----------------------// // retrieveCurrentImpact // //-----------------------// /** * Report the set of systems that are impacted by the action, as determined * by the *current status* of the glyphs *currently* pointed by the sections * * @param sheet the containing sheet * @return the ordered set of impacted systems */ protected SortedSet<SystemInfo> retrieveCurrentImpact (Sheet sheet) { SortedSet<SystemInfo> impactedSystems = new TreeSet<>(); for (Glyph glyph : glyphs) { SystemInfo system = sheet.getSystemOf(glyph); if (system != null) { impactedSystems.add(system); } if (glyph != null) { Shape shape = glyph.getShape(); if ((shape != null) && shape.isPersistent()) { // Include all following systems impactedSystems.addAll(remaining(system)); } } } return impactedSystems; } //----------------// // retrieveGlyphs // //----------------// /** * This method is in charge of retrieving the glyphs to be handled, using * either their composing sections ids or their shape and locations. */ protected abstract void retrieveGlyphs (); }