package de.venjinx.jme3.scenegraph;
import java.util.HashSet;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import de.venjinx.jme3.scenegraph.SceneNodeListener.NodeChangedEvent;
import de.venjinx.jme3.scenegraph.SceneNodeListener.NodeChangedEvent.EventType;
public class ScenegraphNode extends Node {
private Scenegraph scenegraph = null;
private HashSet<SceneNodeListener> listeners = new HashSet<>();
private boolean active = true;
public ScenegraphNode() {
super("Scenegraph node");
}
public ScenegraphNode(String name) {
super(name);
}
public ScenegraphNode(String name, Scenegraph scenegraph) {
super(name);
setScenegraph(scenegraph);
}
@Override
public int attachChild(Spatial child) {
if (child instanceof ScenegraphNode)
((ScenegraphNode) child).setScenegraph(scenegraph);
if (child.getParent() != this)
notifyListeners(new NodeChangedEvent(this, child, EventType.ATTACHED));
super.attachChild(child);
return children.size();
}
@Override
public int attachChildAt(Spatial child, int index) {
if (child instanceof ScenegraphNode)
((ScenegraphNode) child).setScenegraph(scenegraph);
if (child.getParent() != this)
notifyListeners(new NodeChangedEvent(this, child, EventType.ATTACHED));
super.attachChildAt(child, index);
return children.size();
}
@Override
public int detachChild(Spatial child) {
if (hasChild(child))
notifyListeners(new NodeChangedEvent(this, child, EventType.DETACHED));
super.detachChild(child);
if (child instanceof ScenegraphNode)
((ScenegraphNode) child).setScenegraph(null);
return children.size();
}
@Override
public int detachChildNamed(String childName) {
for (int x = 0, max = children.size(); x < max; x++) {
Spatial child = children.get(x);
if (childName.equals(child.getName())) {
notifyListeners(new NodeChangedEvent(this, child, EventType.DETACHED));
detachChildAt(x);
if (child instanceof ScenegraphNode)
((ScenegraphNode) child).setScenegraph(null);
return x;
}
}
return -1;
}
@Override
public Spatial detachChildAt(int index) {
Spatial child = children.get(index);
if (hasChild(child))
notifyListeners(new NodeChangedEvent(this, child, EventType.DETACHED));
super.detachChildAt(index);
if (child instanceof ScenegraphNode)
((ScenegraphNode) child).setScenegraph(null);
return child;
}
public void setScenegraph(Scenegraph scenegraph) {
this.scenegraph = scenegraph;
for (Spatial s : children)
if (s instanceof ScenegraphNode)
((ScenegraphNode) s).setScenegraph(scenegraph);
}
public Scenegraph getScenegraph() {
return scenegraph;
}
public void addSceneNodeListener(SceneNodeListener listener) {
listeners.add(listener);
}
public void removeListener(SceneNodeListener listener) {
listeners.remove(listener);
}
public HashSet<SceneNodeListener> getListeners() {
return listeners;
}
public void setActive(boolean active) {
this.active = active;
}
public boolean isActive() {
return active;
}
private void notifyListeners(NodeChangedEvent e) {
if (scenegraph != null)
scenegraph.onNodeChanged(e);
if (active)
for (SceneNodeListener sl : listeners)
sl.onNodeChanged(e);
}
}