*******************************************************************************/
package org.simantics.g3d.vtk.common;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
-import java.util.function.Consumer;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.progress.IProgressService;
import org.simantics.db.ReadGraph;
import org.simantics.db.Session;
import org.simantics.db.UndoContext;
import org.simantics.db.WriteGraph;
-import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.UniqueRead;
import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.procedure.SyncProcedure;
import org.simantics.db.service.UndoRedoSupport;
import org.simantics.g3d.ontology.G3D;
import org.simantics.g3d.scenegraph.RenderListener;
import org.simantics.utils.datastructures.MapSet;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.ui.ExceptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import vtk.vtkProp;
public abstract class AbstractVTKNodeMap<DBObject,E extends INode> implements VTKNodeMap<DBObject,E>, IMappingListener, RenderListener, NodeListener, UndoRedoSupport.ChangeListener{
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractVTKNodeMap.class);
protected Session session;
protected IMapping<DBObject, INode> mapping;
protected void removeMap(E node) {
Collection<vtkProp> coll = nodeToActor.getValuesUnsafe(node);
- for (vtkProp p : coll) {
- actorToNode.remove(p);
+ if (coll.size() > 0) {
+ view.lock();
+ for (vtkProp p : coll) {
+ actorToNode.remove(p);
+ if (p.GetVTKId() != 0) {
+ view.getRenderer().RemoveActor(p);
+ p.Delete();
+ }
+ }
+ view.unlock();
}
nodeToActor.remove(node);
}
}
protected void doCommit() {
- session.asyncRequest(new WriteRequest() {
-
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- if (DEBUG) System.out.println("Commit " + commitMessage);
- if (commitMessage != null) {
- Layer0Utils.addCommentMetadata(graph, commitMessage);
- graph.markUndoPoint();
- commitMessage = null;
+ IProgressService service = PlatformUI.getWorkbench().getProgressService();
+ try {
+ service.busyCursorWhile(monitor -> {
+ try {
+ session.syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ if (DEBUG) System.out.println("Commit " + commitMessage);
+ if (commitMessage != null) {
+ Layer0Utils.addCommentMetadata(graph, commitMessage);
+ graph.markUndoPoint();
+ commitMessage = null;
+ }
+ commit(graph);
+ }
+ });
+ } catch (DatabaseException e) {
+ ExceptionUtils.logAndShowError("Cannot commit editor changes", e);
}
- commit(graph);
- }
-
- }, new Consumer<DatabaseException>() {
-
- @Override
- public void accept(DatabaseException parameter) {
- if (parameter != null)
- ExceptionUtils.logAndShowError("Cannot commit editor changes", parameter);
- }
- });
+ });
+ } catch (InvocationTargetException | InterruptedException e) {
+ LOGGER.error("Unexpected exception", e);
+ }
}
protected void commit(WriteGraph graph) throws DatabaseException {
if (graphUpdates)
return;
if (DEBUG)System.out.println("domainModified");
- session.asyncRequest(new ReadRequest() {
-
+ session.asyncRequest(new UniqueRead<Object>() {
@Override
- public void run(ReadGraph graph) throws DatabaseException {
+ public Object perform(ReadGraph graph) throws DatabaseException {
+ return new Object();
+ }
+ }, new SyncProcedure<Object>() {
+ @Override
+ public void execute(ReadGraph graph, Object result) throws DatabaseException {
+ // Perform all updates to the model in a single query thread
update(graph);
+ };
+
+ @Override
+ public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {
+ LOGGER.error("Failed to update pipeline changes" + throwable);
}
});
-
}
protected void reset(ReadGraph graph) throws MappingException {
if (DEBUG) System.out.println("Reset");
- synchronized (syncMutex) {
- graphUpdates = true;
- mapping.getRangeModified().clear();
- for (DBObject o : mapping.getDomain())
- mapping.domainModified(o);
- mapping.updateRange(graph);
- graphModified.clear();
- graphUpdates = false;
- }
+ graphUpdates = true;
+ mapping.getRangeModified().clear();
+ for (DBObject o : mapping.getDomain())
+ mapping.domainModified(o);
+ mapping.updateRange(graph);
+ graphModified.clear();
+ graphUpdates = false;
}
private boolean useFullSyncWithUndo = false;
protected void update(ReadGraph graph) throws DatabaseException {
- if (DEBUG) System.out.println("Graph update start");
- if (runUndo && useFullSyncWithUndo) {
- reset(graph);
- } else {
- synchronized (syncMutex) {
+ synchronized (syncMutex) {
+ if (DEBUG) System.out.println("Graph update start");
+
+ if (runUndo && useFullSyncWithUndo) {
+ reset(graph);
+ } else {
graphUpdates = true;
for (DBObject domainObject : mapping.getDomainModified()) {
@SuppressWarnings("unchecked")
syncDeletes();
clearDeletes();
graphUpdates = false;
- }
+ }
+
+ if (mapping.isRangeModified() && !runUndo && !runRedo)
+ commit((String)null);
+
+ if (DEBUG) System.out.println("Graph update done");
}
-
- if (mapping.isRangeModified() && !runUndo && !runRedo)
- commit((String)null);
- if (DEBUG) System.out.println("Graph update done");
}
@Override
E n = stack.pop();
boolean conflict = filterChange(removed, n);
if (conflict) {
- System.out.println("Prevent removing " + n);
+ if (DEBUG) System.out.println("Prevent removing " + n);
//filterChange(added, n)
if (filterChange(added, n))
- System.out.println("Prevent adding " + n);
+ if (DEBUG) System.out.println("Prevent adding " + n);
}
if (n instanceof ParentNode) {
ParentNode<INode> pn = (ParentNode<INode>)n;
}
}
}
-
+ // Do not process updates for removed nodes.
+ for (Pair<E, String> r : removed) {
+ updated.removeValues(r.first);
+ }
rem.addAll(removed);
add.addAll(added);
for (E e : updated.getKeys()) {
}
-
for (Pair<E, String> n : rem) {
stopListening(n.first);
removeActor(n.first);
+ n.first.remove();
}
- for (Pair<E, String> n : add) {
- addActor(n.first);
- listen(n.first);
- }
+ for (Pair<E, String> n : add) {
+ addActor(n.first);
+ listen(n.first);
+ }
for (E e : mod.getKeys()) {
Set<String> ids = mod.getValues(e);
}
}
-// synchronized (syncMutex) {
-// rem.addAll(removed);
-// add.addAll(added);
-// //mod.addAll(updated);
-// for (E e : updated.getKeys()) {
-// for (String s : updated.getValues(e))
-// mod.add(e, s);
-// }
-//
-// removed.clear();
-// added.clear();
-// updated.clear();
-// }
-
for (E e : mod.getKeys()) {
Set<String> ids = mod.getValues(e);
updateActor(e,ids);
}
-
-
+
for (Pair<E, String> n : rem) {
for (NodeListener l : nodeListeners)
l.nodeRemoved(null, n.first, n.second);
//FIXME : 1. sometimes removed structural models cause ObjMap to add their children again.
// removing the listener here prevents corruption of visual model, but better fix is needed.
- // 2. detach causes nodeRemoved event, which then causes other critical events to be missed. Took out th
+ // 2. detach causes nodeRemoved event, which then causes other critical events to be missed. Took out call:
//stopListening(child);
}