Changeset 13309 in josm


Ignore:
Timestamp:
2018-01-13T00:52:54+01:00 (5 days ago)
Author:
Don-vip
Message:

fix #15766, see #15688 - fix performance regression introduced in r13229 when drawing a way of many nodes while the filter dialog is open

Location:
trunk/src/org/openstreetmap/josm
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java

    r13293 r13309  
    199199    /**
    200200     * Checks if a map redraw is required and does so if needed. Also updates the status bar.
     201     * @param e event, can be null
    201202     * @return true if a repaint is needed
    202203     */
    203     private boolean redrawIfRequired() {
     204    private boolean redrawIfRequired(Object e) {
    204205        updateStatusLine();
    205206        // repaint required if the helper line is active.
     
    236237                needsRepaint = true;
    237238            } else if (!alt && continueFrom != null && !continueFrom.isSelected()) {
    238                 currentDataSet.addSelected(continueFrom);
     239                addSelection(currentDataSet, continueFrom);
    239240                needsRepaint = true;
    240241            }
     242        }
     243
     244        if (!needsRepaint && e instanceof SelectionChangeEvent) {
     245            SelectionChangeEvent event = (SelectionChangeEvent) e;
     246            needsRepaint = !event.getOldSelection().isEmpty() && event.getSelection().isEmpty();
    241247        }
    242248
     
    250256        ds.beginUpdate(); // to prevent the selection listener to screw around with the state
    251257        try {
    252             ds.addSelected(toAdd);
    253             ds.clearSelection(toRemove);
     258            addSelection(ds, toAdd);
     259            clearSelection(ds, toRemove);
    254260        } finally {
    255261            ds.endUpdate();
    256262        }
     263    }
     264
     265    private static void updatePreservedFlag(OsmPrimitive osm, boolean state) {
     266        // Preserves selected primitives and selected way nodes
     267        osm.setPreserved(state);
     268        if (osm instanceof Way) {
     269            for (Node n : ((Way) osm).getNodes()) {
     270                n.setPreserved(state);
     271            }
     272        }
     273    }
     274
     275    private static void setSelection(DataSet ds, Collection<OsmPrimitive> toSet) {
     276        toSet.stream().forEach(x -> updatePreservedFlag(x, true));
     277        ds.setSelected(toSet);
     278    }
     279
     280    private static void setSelection(DataSet ds, OsmPrimitive toSet) {
     281        updatePreservedFlag(toSet, true);
     282        ds.setSelected(toSet);
     283    }
     284
     285    private static void addSelection(DataSet ds, OsmPrimitive toAdd) {
     286        updatePreservedFlag(toAdd, true);
     287        ds.addSelected(toAdd);
     288    }
     289
     290    private static void clearSelection(DataSet ds, OsmPrimitive toRemove) {
     291        ds.clearSelection(toRemove);
     292        updatePreservedFlag(toRemove, false);
    257293    }
    258294
     
    303339        map.statusLine.activateAnglePanel(false);
    304340
    305         removeHighlighting();
     341        DataSet ds = getLayerManager().getEditDataSet();
     342        if (ds != null) {
     343            ds.getSelected().stream().forEach(x -> updatePreservedFlag(x, false));
     344        }
     345
     346        removeHighlighting(null);
    306347        map.keyDetector.removeKeyListener(this);
    307348        map.keyDetector.removeModifierExListener(this);
     
    317358        updateKeyModifiersEx(modifiers);
    318359        computeHelperLine();
    319         addHighlighting();
     360        addHighlighting(null);
    320361    }
    321362
     
    326367        snapHelper.setFixedMode();
    327368        computeHelperLine();
    328         redrawIfRequired();
     369        redrawIfRequired(e);
    329370    }
    330371
     
    339380        snapHelper.unFixOrTurnOff();
    340381        computeHelperLine();
    341         redrawIfRequired();
     382        redrawIfRequired(e);
    342383    }
    343384
     
    351392        // Make sure helper line is computed later (causes deadlock in selection event chain otherwise)
    352393        SwingUtilities.invokeLater(() -> {
     394            event.getOldSelection().stream().forEach(x -> updatePreservedFlag(x, false));
     395            event.getSelection().stream().forEach(x -> updatePreservedFlag(x, true));
    353396            computeHelperLine();
    354             addHighlighting();
     397            addHighlighting(event);
    355398        });
    356399    }
    357400
    358401    private void tryAgain(MouseEvent e) {
    359         getLayerManager().getEditDataSet().setSelected();
     402        getLayerManager().getEditDataSet().clearSelection();
    360403        mouseReleased(e);
    361404    }
     
    374417        // Redraw to remove the helper line stub
    375418        computeHelperLine();
    376         removeHighlighting();
     419        removeHighlighting(null);
    377420    }
    378421
     
    445488                // have to switch modes)
    446489
    447                 ds.setSelected(n);
     490                setSelection(ds, n);
    448491                // If we extend/continue an existing way, select it already now to make it obvious
    449492                Way continueFrom = getWayForNode(n);
    450493                if (continueFrom != null) {
    451                     ds.addSelected(continueFrom);
     494                    addSelection(ds, continueFrom);
    452495                }
    453496
     
    627670        }
    628671
    629         ds.setSelected(newSelection);
     672        setSelection(ds, newSelection);
    630673
    631674        // "viewport following" mode for tracing long features
     
    635678        }
    636679        computeHelperLine();
    637         removeHighlighting();
     680        removeHighlighting(e);
    638681    }
    639682
     
    730773                (posn0 >= 1                            && targetNode.equals(selectedWay.getNode(posn0-1)))) || // previous node
    731774                (posn0 < selectedWay.getNodesCount()-1 && targetNode.equals(selectedWay.getNode(posn0+1)))) {  // next node
    732                 getLayerManager().getEditDataSet().setSelected(targetNode);
     775                setSelection(getLayerManager().getEditDataSet(), targetNode);
    733776                lastUsedNode = targetNode;
    734777                return true;
     
    789832
    790833        computeHelperLine();
    791         addHighlighting();
     834        addHighlighting(e);
    792835    }
    793836
     
    9611004        mousePos = e.getPoint();
    9621005        snapHelper.noSnapNow();
    963         boolean repaintIssued = removeHighlighting();
     1006        boolean repaintIssued = removeHighlighting(e);
    9641007        // force repaint in case snapHelper needs one. If removeHighlighting
    9651008        // caused one already, don't do it again.
     
    11231166     * bar both addHighlighting() and repaintIfRequired() are needed, since former fills newHighlights
    11241167     * and latter processes them into oldHighlights.
    1125      */
    1126     private void addHighlighting() {
     1168     * @param event event, can be null
     1169     */
     1170    private void addHighlighting(Object event) {
    11271171        newHighlights = new HashSet<>();
    11281172        MapView mapView = MainApplication.getMap().mapView;
     
    11311175        if (ctrl) {
    11321176            mapView.setNewCursor(cursor, this);
    1133             redrawIfRequired();
     1177            redrawIfRequired(event);
    11341178            return;
    11351179        }
     
    11431187            mapView.setNewCursor(cursorJoinNode, this);
    11441188            newHighlights.add(mouseOnExistingNode);
    1145             redrawIfRequired();
     1189            redrawIfRequired(event);
    11461190            return;
    11471191        }
     
    11501194        if (mouseOnExistingWays.isEmpty()) {
    11511195            mapView.setNewCursor(cursor, this);
    1152             redrawIfRequired();
     1196            redrawIfRequired(event);
    11531197            return;
    11541198        }
     
    11561200        mapView.setNewCursor(cursorJoinWay, this);
    11571201        newHighlights.addAll(mouseOnExistingWays);
    1158         redrawIfRequired();
     1202        redrawIfRequired(event);
    11591203    }
    11601204
    11611205    /**
    11621206     * Removes target highlighting from primitives. Issues repaint if required.
     1207     * @param event event, can be null
    11631208     * @return true if a repaint has been issued.
    11641209     */
    1165     private boolean removeHighlighting() {
     1210    private boolean removeHighlighting(Object event) {
    11661211        newHighlights = new HashSet<>();
    1167         return redrawIfRequired();
     1212        return redrawIfRequired(event);
    11681213    }
    11691214
     
    13141359    public Collection<? extends OsmPrimitive> getPreservedPrimitives() {
    13151360        DataSet ds = getLayerManager().getEditDataSet();
    1316         if (ds != null) {
    1317             // Preserves selected primitives and selected way nodes
    1318             Set<OsmPrimitive> result = new HashSet<>();
    1319             for (Way w : ds.getSelectedWays()) {
    1320                 result.addAll(w.getNodes());
    1321             }
    1322             result.addAll(ds.getSelected());
    1323             return result;
    1324         }
    1325         return Collections.emptySet();
     1361        return ds != null ? ds.allPreservedPrimitives() : Collections.emptySet();
    13261362    }
    13271363
     
    13681404            // select last added node - maybe we will continue drawing from it
    13691405            if (n != null) {
    1370                 getLayerManager().getEditDataSet().addSelected(n);
     1406                addSelection(getLayerManager().getEditDataSet(), n);
    13711407            }
    13721408        }
  • trunk/src/org/openstreetmap/josm/actions/mapmode/MapMode.java

    r13173 r13309  
    233233     * Gets a collection of primitives that should not be hidden by the filter.
    234234     * @return The primitives that the filter should not hide.
     235     * @deprecated use {@link org.openstreetmap.josm.data.osm.DataSet#allPreservedPrimitives}
    235236     * @since 11993
    236237     */
     238    @Deprecated
    237239    public Collection<? extends OsmPrimitive> getPreservedPrimitives() {
    238240        return Collections.emptySet();
  • trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java

    r12542 r13309  
    169169     */
    170170    protected static final short FLAG_ANNOTATED = 1 << 12;
     171
     172    /**
     173     * Determines if the primitive is preserved from the filter mechanism.
     174     */
     175    protected static final short FLAG_PRESERVED = 1 << 13;
    171176
    172177    /**
  • trunk/src/org/openstreetmap/josm/data/osm/DataSet.java

    r13208 r13309  
    518518
    519519    /**
     520     * Returns a collection containing all primitives preserved from filtering.
     521     * @return A collection containing all primitives preserved from filtering.
     522     * @see OsmPrimitive#isPreserved
     523     * @since 13309
     524     */
     525    public Collection<OsmPrimitive> allPreservedPrimitives() {
     526        return getPrimitives(OsmPrimitive::isPreserved);
     527    }
     528
     529    /**
    520530     * Adds a primitive to the dataset.
    521531     *
  • trunk/src/org/openstreetmap/josm/data/osm/FilterMatcher.java

    r12846 r13309  
    1111import org.openstreetmap.josm.data.osm.search.SearchMode;
    1212import org.openstreetmap.josm.data.osm.search.SearchParseError;
    13 import org.openstreetmap.josm.gui.MainApplication;
    14 import org.openstreetmap.josm.gui.MapFrame;
    1513import org.openstreetmap.josm.tools.SubclassFilteredCollection;
    1614
     
    225223
    226224    private static FilterType test(List<FilterInfo> filters, OsmPrimitive primitive, boolean hidden) {
    227         MapFrame map = MainApplication.getMap();
    228         if (primitive.isIncomplete() ||
    229                 (map != null && map.mapMode != null && map.mapMode.getPreservedPrimitives().contains(primitive)))
     225        if (primitive.isIncomplete() || primitive.isPreserved())
    230226            return FilterType.NOT_FILTERED;
    231227
  • trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

    r13173 r13309  
    428428
    429429    /**
     430     * Set binary property used internally by the filter mechanism.
     431     * @param isPreserved new "preserved" flag value
     432     * @since 13309
     433     */
     434    public void setPreserved(boolean isPreserved) {
     435        updateFlags(FLAG_PRESERVED, isPreserved);
     436    }
     437
     438    /**
    430439     * Replies true, if this primitive is disabled. (E.g. a filter applies)
    431440     * @return {@code true} if this object has the "disabled" flag enabled
     
    457466    public boolean getDisabledType() {
    458467        return (flags & FLAG_DISABLED_TYPE) != 0;
     468    }
     469
     470    /**
     471     * Replies true, if this primitive is preserved from filtering.
     472     * @return {@code true} if this object has the "preserved" flag enabled
     473     * @since 13309
     474     */
     475    public boolean isPreserved() {
     476        return (flags & FLAG_PRESERVED) != 0;
    459477    }
    460478
Note: See TracChangeset for help on using the changeset viewer.