public abstract class AbstractVTKNodeMap<E extends INode> implements VTKNodeMap<E>, IMappingListener, RenderListener, NodeListener, UndoRedoSupport.ChangeListener{
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
protected Session session;
protected IMapping<Object,E> mapping;
return n + "@" + Integer.toHexString(n.hashCode());
}
+ protected boolean filterChange(List<Pair<E,String>> list,E n) {
+ for (int i = list.size()-1; i >= 0; i--) {
+ if (list.get(i).first == n) {
+ list.remove(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
@SuppressWarnings("unchecked")
protected void updateCycle() {
rem.clear();
synchronized (syncMutex) {
- // Check for overlapping additions and deletions, prevent deleting objects that are also added.
+ // Check for overlapping additions and deletions, prevent deleting objects that are also added and vice versa.
Deque<E> stack = new ArrayDeque<E>();
for (Pair<E, String> n : added) {
stack.add(n.first);
}
while (!stack.isEmpty()) {
E n = stack.pop();
- for (int i = removed.size()-1; i >= 0; i--) {
- if (removed.get(i).first == n) {
- removed.remove(i);
- break;
- }
+ boolean conflict = filterChange(removed, n);
+ if (conflict) {
+ filterChange(added, n);
}
if (n instanceof ParentNode) {
ParentNode<INode> pn = (ParentNode<INode>)n;
package org.simantics.g3d.scenegraph.base;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import org.simantics.utils.datastructures.MapList;
private MapList<String, T> children = new MapList<String, T>();
public synchronized void addNode(String relName, T child) {
- if (child.getParent() != null)
+ if (child == null)
+ throw new NullPointerException("Cannot add null child");
+ if (child.getParent() != null) {
+ if (child.getParent() == this)
+ throw new IllegalArgumentException("Given node is already a child");
child.getParent().deattachNode(child.getParentRel(), child);
+ }
child.setParent(this, relName);
children.add(relName, (T) child);