X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.g3d%2Fsrc%2Forg%2Fsimantics%2Fg3d%2Fscenegraph%2Fbase%2FParentNode.java;fp=org.simantics.g3d%2Fsrc%2Forg%2Fsimantics%2Fg3d%2Fscenegraph%2Fbase%2FParentNode.java;h=681121778d8cf2cb083a874809774a8f18fb6475;hb=87b3241ec277ba3d8e414b26186a032c9cdcaeed;hp=0000000000000000000000000000000000000000;hpb=1f0bcd66274375f2278d2e6c486cb28257a5f7b2;p=simantics%2F3d.git diff --git a/org.simantics.g3d/src/org/simantics/g3d/scenegraph/base/ParentNode.java b/org.simantics.g3d/src/org/simantics/g3d/scenegraph/base/ParentNode.java new file mode 100644 index 00000000..68112177 --- /dev/null +++ b/org.simantics.g3d/src/org/simantics/g3d/scenegraph/base/ParentNode.java @@ -0,0 +1,153 @@ +package org.simantics.g3d.scenegraph.base; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.simantics.utils.datastructures.MapList; + +public abstract class ParentNode extends Node { + + private MapList children = new MapList(); + + public synchronized void addNode(String relName, T child) { + if (child.getParent() != null) + child.getParent().removeNode(child.getParentRel(), child); + + child.setParent(this, relName); + children.add(relName, (T) child); + + childrenChanged(); + fireNodeAdded(child, relName); + } + + /** + * Removes child node and it's hierarchy. + * @param relName + * @param child + * @return + */ + @SuppressWarnings("unchecked") + public synchronized final boolean removeNode(String relName, INode child) { + if (children.remove(relName, (T) child)) { + fireNodeRemoved(child, relName); + child.remove(); + child.setParent(null, null); + return true; + } + return false; + } + + /** + * Removes child node. The child nodes hierarchy is left intact. + * @param relName + * @param child + * @return + */ + @SuppressWarnings("unchecked") + public synchronized final boolean deattachNode(String relName, INode child) { + if (children.remove(relName, (T) child)) { + fireNodeRemoved(child, relName); + child.setParent(null, null); + return true; + } + return false; + } + + public synchronized final boolean removeNodes(String relName) { + List nodes = children.getValues(relName); + for (T child : nodes) { + if (children.remove(relName, (T) child)) { + fireNodeRemoved(child, relName); + child.remove(); + child.setParent(null, null); + + } + } + return nodes.size() > 0; + } + + public synchronized final void removeNodes() { + synchronized (children) { + boolean changed = false; + for (String key : children.getKeys()) { + for (T child : children.getValues(key)) { + if (child != null) { + changed = true; + if (child instanceof ParentNode) { + ((ParentNode) child).removeNodes(); + } + child.cleanup(); + child.setParent(null, null); + // if (propertyChangeListener != null) { + // propertyChangeListener.propertyChange(new + // PropertyChangeEvent(this, + // "children["+child.getId()+"]", child.getClass(), + // NULL)); // "children" is a special field name + // } + } + } + } + children.clear(); + if (changed) + childrenChanged(); + } + } + + public synchronized List getNodes(String rel) { + return children.getValues(rel); + } + + public synchronized List getNodes() { + List result = new ArrayList(); + for (String s : children.getKeys()) + result.addAll(children.getValues(s)); + return result; + } + + protected void childrenChanged() { + } + + + @Override + public void remove() { + synchronized (children) { + List toRemove = new ArrayList(); + + for (String key : children.getKeys()) { + + for (T child : children.getValues(key)) { + if (child != null) { + toRemove.add(child); + } + } + } + + for (T n : toRemove) { + n.remove(); + } + + children.clear(); + if (toRemove.size() > 0) + childrenChanged(); + super.remove(); + + } + } + + + + + protected void fireNodeAdded(INode node, String rel) { + for (NodeListener listener : listeners) { + listener.nodeAdded(this, node, rel); + } + } + + protected void fireNodeRemoved(INode node, String rel) { + for (NodeListener listener : listeners) { + listener.nodeRemoved(this, node, rel); + } + } + +}