/* * Moonlight|3D Copyright (C) 2005 The Moonlight|3D team * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Created on Jan 5, 2005 */ package ml.backend.og; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import ml.backend.document.Document; import ml.backend.selection.PathElement; import ml.core.exceptions.Exception; import ml.core.helper.NamedObject; import ml.core.helper.PropertyContainer; /** * This is the base class for all operator graph nodes. New nodes have * to be derived from this class. * * @author gregor */ public abstract class Node extends PropertyContainer implements PathElement, NamedObject { private Document document; private String name; private ArrayList slots; private HashMap slotMap; public Node() { slots = new ArrayList(); slotMap = new HashMap(); } /** * creates a new slot for this node */ public void createSlot(String name, Slot.Type type) { Slot newSlot = new Slot(); newSlot.setName(name); newSlot.setNode(this); newSlot.setType(type); slots.add(newSlot); slotMap.put(name, newSlot); } private String type; /** * This is overloaded by the children of this class to execute * the functionality of the node. */ abstract public void update() throws ml.core.exceptions.Exception; /** * This function is is called when an operator graph node is removed * from the scene to clean up any dependencies it may have in other * parts of the program, e.g. the SG node cache. * */ abstract public void removeDependencies(); /** * This function calls update() and passes the update request * down to the output Slots attached to this node so that the * change can propagate through the whole graph. * @throws Exception */ public void recursiveUpdate(Manager manager) throws Exception { boolean propagateChanges = false; if (hasUpdatedProperties()) { update(); clearHasUpdatedProperties(); propagateChanges = true; manager.notifyNodeUpdate(this); } for (int i = 0; i < slots.size(); i++) { if (slots.get(i).getType() == Slot.Type.Output) { if (propagateChanges) { if (slots.get(i).getCurrentLink() != null) { slots.get(i).getCurrentLink().getOutput().getNode().setHasUpdatedProperties(); } } slots.get(i).recursiveUpdate(manager); } } } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setType(String type) { this.type = type; } public String getType() { return type; } /** * returns the whole array of Slots this Node has. It contains * both Input and Output slots. */ public List getSlots() { return (ArrayList) slots.clone(); } /** * returns the Slot with the given name assigned to it or 0 if * the requested slot couldn't be found. */ public Slot getSlot(String name) throws ml.core.exceptions.Exception { // for (int i = 0; i < slots.size(); i++) { // if (slots.get(i).getName().equals(name)) { // return slots.get(i); // } // } Slot slot=slotMap.get(name); if(slot!=null) { return slot; } throw new ml.core.exceptions.Exception("unable to find slot with given name"); } /** * does this Node have any input Slots? */ public boolean isPureSource() { for (int i = 0; i != slots.size(); ++i) { if (slots.get(i).getType() == Slot.Type.Input) { return false; } } return true; } /** * does this Node have any output Slots? */ public boolean isPureDrain() { for (int i = 0; i != slots.size(); ++i) { if (slots.get(i).getType() == Slot.Type.Output) { return false; } } return true; } /** * does this Node have any linked input Slots? */ public boolean isSource() { for (int i = 0; i != slots.size(); ++i) { if (slots.get(i).getType() == Slot.Type.Input && slots.get(i).getCurrentLink() != null) { return false; } } return true; } /** * does this Node have any linked output Slots? */ public boolean isDrain() { for (int i = 0; i != slots.size(); ++i) { if (slots.get(i).getType() == Slot.Type.Output && slots.get(i).getCurrentLink() != null) { return false; } } return true; } public PathElement findChildElement(String childName) { try { return getSlot(childName); } catch (Exception e) { return null; } } public boolean isValidAppendixName(String appendix) { return false; } public Object getFromAppendix(String appendix) { return null; } public Document getDocument() { return document; } final void setDocument(Document document) { this.document = document; } }