*******************************************************************************/
package org.simantics.g3d.vtk.common;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import vtk.vtkProp;
-public abstract class AbstractVTKNodeMap<E extends INode> implements VTKNodeMap<E>, IMappingListener, RenderListener, NodeListener, UndoRedoSupport.ChangeListener{
+public abstract class AbstractVTKNodeMap<DBObject,E extends INode> implements VTKNodeMap<DBObject,E>, IMappingListener, RenderListener, NodeListener, UndoRedoSupport.ChangeListener{
private static final boolean DEBUG = false;
protected Session session;
- protected IMapping<Object,E> mapping;
+ protected IMapping<DBObject,E> mapping;
protected VtkView view;
protected MapList<E, vtkProp> nodeToActor = new MapList<E, vtkProp>();
protected int redoOpCount = 0;
protected boolean runUndo = false;
protected boolean runRedo = false;
- public AbstractVTKNodeMap(Session session, IMapping<Object,E> mapping, VtkView view, ParentNode<E> rootNode) {
+ public AbstractVTKNodeMap(Session session, IMapping<DBObject,E> mapping, VtkView view, ParentNode<E> rootNode) {
this.session = session;
this.mapping = mapping;
this.view = view;
private boolean rangeModified = false;
+ public boolean isRangeModified() {
+ return rangeModified;
+ }
+
@Override
public void onChanged() {
try {
protected void reset(ReadGraph graph) throws MappingException {
if (DEBUG) System.out.println("Reset");
+
synchronized (syncMutex) {
graphUpdates = true;
mapping.getRangeModified().clear();
- for (Object o : mapping.getDomain())
+ for (DBObject o : mapping.getDomain())
mapping.domainModified(o);
mapping.updateRange(graph);
graphModified.clear();
} else {
synchronized (syncMutex) {
graphUpdates = true;
- for (Object domainObject : mapping.getDomainModified()) {
+ for (DBObject domainObject : mapping.getDomainModified()) {
E rangeObject = mapping.get(domainObject);
if (rangeObject != null)
graphModified.add(rangeObject);
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 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();
+ boolean conflict = filterChange(removed, n);
+ if (conflict) {
+ System.out.println("Prevent removing " + n);
+ //filterChange(added, n)
+ if (filterChange(added, n))
+ System.out.println("Prevent adding " + n);
+ }
+ if (n instanceof ParentNode) {
+ ParentNode<INode> pn = (ParentNode<INode>)n;
+ for (INode cn : pn.getNodes()) {
+ stack.push((E)cn);
+ }
+ }
+ }
+
rem.addAll(removed);
add.addAll(added);
for (E e : updated.getKeys()) {
updated.clear();
}
+
+
for (Pair<E, String> n : rem) {
stopListening(n.first);
removeActor(n.first);
}
- public IMapping<Object,E> getMapping() {
+ public IMapping<DBObject,E> getMapping() {
return mapping;
}