Ignore:
Timestamp:
2020-10-10T17:18:25+02:00 (4 years ago)
Author:
GerdP
Message:

see #19885: memory leak with "temporary" objects in validator and actions

  • use ChangeNodesCommand instead of ChangeCommand
  • further simplifications

This one was a bit more complex. I hope I didn't mess up any special use case.

File:
1 edited

Legend:

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

    r16438 r17143  
    3333import org.openstreetmap.josm.actions.JosmAction;
    3434import org.openstreetmap.josm.command.AddCommand;
    35 import org.openstreetmap.josm.command.ChangeCommand;
     35import org.openstreetmap.josm.command.ChangeNodesCommand;
    3636import org.openstreetmap.josm.command.Command;
    3737import org.openstreetmap.josm.command.SequenceCommand;
     
    516516        Collection<Command> cmds = new LinkedList<>();
    517517        Collection<OsmPrimitive> newSelection = new LinkedList<>(ds.getSelected());
    518         List<Way> reuseWays = new ArrayList<>();
    519         List<Way> replacedWays = new ArrayList<>();
     518        Map<Way, List<Node>> reuseWays = new HashMap<>();
    520519
    521520        if (newNode) {
     
    538537                    tryToMoveNodeOnIntersection(wss, n);
    539538                }
    540                 insertNodeIntoAllNearbySegments(wss, n, newSelection, cmds, replacedWays, reuseWays);
     539                insertNodeIntoAllNearbySegments(wss, n, newSelection, cmds, reuseWays);
    541540            }
    542541        }
     
    600599                // user wants a new way.
    601600                Way way = alt ? null : (selectedWay != null ? selectedWay : getWayForNode(n0));
    602                 Way wayToSelect;
    603601
    604602                // Don't allow creation of self-overlapping ways
     
    613611                    way = new Way();
    614612                    way.addNode(n0);
     613                    way.addNode(n);
    615614                    cmds.add(new AddCommand(ds, way));
    616                     wayToSelect = way;
    617615                } else {
    618                     int i;
    619                     if ((i = replacedWays.indexOf(way)) != -1) {
    620                         way = reuseWays.get(i);
    621                         wayToSelect = way;
    622                     } else {
    623                         wayToSelect = way;
    624                         Way wnew = new Way(way);
    625                         cmds.add(new ChangeCommand(way, wnew));
    626                         way = wnew;
     616                    List<Node> modNodes = reuseWays.get(way);
     617                    boolean reuse = (modNodes != null);
     618                    if (modNodes == null) {
     619                        modNodes = way.getNodes();
     620                    }
     621                    // Connected to a node that's already in the way
     622                    if (modNodes.contains(n)) {
     623                        wayIsFinished = true;
     624                        selection.clear();
     625                    }
     626                    if (modNodes.get(modNodes.size() - 1) == n0)
     627                        modNodes.add(n);
     628                    else
     629                        modNodes.add(0, n);
     630                    if (!reuse) {
     631                        cmds.add(new ChangeNodesCommand(way, modNodes));
    627632                    }
    628633                }
    629634
    630                 // Connected to a node that's already in the way
    631                 if (way.containsNode(n)) {
    632                     wayIsFinished = true;
    633                     selection.clear();
    634                 }
    635 
    636                 // Add new node to way
    637                 if (way.getNode(way.getNodesCount() - 1) == n0) {
    638                     way.addNode(n);
    639                 } else {
    640                     way.addNode(0, n);
    641                 }
    642 
    643635                extendedWay = true;
    644636                newSelection.clear();
    645                 newSelection.add(wayToSelect);
     637                newSelection.add(way);
    646638            }
    647639        }
     
    670662    }
    671663
    672     private static String getTitle(boolean newNode, Node n, Collection<OsmPrimitive> newSelection, List<Way> reuseWays,
     664    private static String getTitle(boolean newNode, Node n, Collection<OsmPrimitive> newSelection, Map<Way, List<Node>> reuseWays,
    673665            boolean extendedWay) {
    674666        String title;
     
    678670            } else {
    679671                title = tr("Add node into way");
    680                 for (Way w : reuseWays) {
     672                for (Way w : reuseWays.keySet()) {
    681673                    newSelection.remove(w);
    682674                }
     
    695687
    696688    private void insertNodeIntoAllNearbySegments(List<WaySegment> wss, Node n, Collection<OsmPrimitive> newSelection,
    697             Collection<Command> cmds, List<Way> replacedWays, List<Way> reuseWays) {
     689            Collection<Command> cmds, Map<Way, List<Node>> reuseWays) {
    698690        Map<Way, List<Integer>> insertPoints = new HashMap<>();
    699691        for (WaySegment ws : wss) {
     
    715707            List<Integer> is = insertPoint.getValue();
    716708
    717             Way wnew = new Way(w);
    718 
     709            List<Node> modNodes = w.getNodes();
    719710            pruneSuccsAndReverse(is);
    720711            for (int i : is) {
    721712                segSet.add(Pair.sort(new Pair<>(w.getNode(i), w.getNode(i+1))));
    722                 wnew.addNode(i + 1, n);
     713                modNodes.add(i + 1, n);
    723714            }
    724715
     
    732723            }
    733724
    734             cmds.add(new ChangeCommand(insertPoint.getKey(), wnew));
    735             replacedWays.add(insertPoint.getKey());
    736             reuseWays.add(wnew);
     725            cmds.add(new ChangeNodesCommand(insertPoint.getKey(), modNodes));
     726            reuseWays.put(w, modNodes);
    737727        }
    738728
Note: See TracChangeset for help on using the changeset viewer.