/* * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code 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 General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. * */ package javax.media.j3d; import java.util.Hashtable; /** * NodeComponent is a common superclass for all scene graph node * component objects such as: Geometry, Appearance, Material, Texture, etc. * *
* For more information, see the * Introduction to the Java 3D API. */ public abstract class NodeComponent extends SceneGraphObject { // This is use for cloneTree only, set to false after the operation boolean forceDuplicate = false; /** * Constructs a NodeComponent object with default parameters. * The default values are as follows: *
cloneTree
operation. A value of true
means
* that this NodeComponent object should be duplicated, while a value
* of false
indicates that this NodeComponent object's
* reference will be copied into the newly cloned object. This value
* can be overriden via the forceDuplicate
parameter of
* the cloneTree
method.
* @param duplicate the value to set.
* @see Node#cloneTree
*/
public void setDuplicateOnCloneTree(boolean duplicate) {
((NodeComponentRetained)retained).setDuplicateOnCloneTree(duplicate);
}
/**
* Returns this node's duplicateOnCloneTree value. The
* duplicateOnCloneTree value is used to determine if NodeComponent
* objects are to be duplicated or referenced during a
* cloneTree
operation. A value of true
means
* that this NodeComponent object should be duplicated, while a value
* of false
indicates that this NodeComponent object's
* reference will be copied into the newly cloned object. This value
* can be overriden via the forceDuplicate
parameter of
* the cloneTree
method.
* @return the value of this node's duplicateOnCloneTree
* @see Node#cloneTree
*/
public boolean getDuplicateOnCloneTree() {
return ((NodeComponentRetained)retained).getDuplicateOnCloneTree();
}
/**
* @deprecated As of Java 3D version 1.2, replaced by
* cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
throw new RuntimeException(J3dI18N.getString("NodeComponent0"));
}
/**
* NOTE: Applications should not call this method directly.
* It should only be called by the cloneNode method.
*
* @deprecated As of Java 3D version 1.2, replaced by
* duplicateNodeComponent(NodeComponent
* originalNodeComponent, boolean forceDuplicate)
*/
public void duplicateNodeComponent(NodeComponent originalNodeComponent) {
duplicateAttributes(originalNodeComponent,
originalNodeComponent.forceDuplicate);
}
/**
* Copies all node information from originalNodeComponent
into
* the current node component. This method is called from subclass of
* duplicateNodeComponent
method which is, in turn, called by the
* cloneNodeComponent
method.
*
* For any NodeComponent objects
* contained by the object being duplicated, each NodeComponent
* object's duplicateOnCloneTree
value is used to determine
* whether the NodeComponent should be duplicated in the new node
* or if just a reference to the current node should be placed in the
* new node. This flag can be overridden by setting the
* forceDuplicate
parameter in the cloneTree
* method to true
.
*
* @param originalNodeComponent the original node component to duplicate.
*/
final void checkDuplicateNodeComponent(
NodeComponent originalNodeComponent) {
if (originalNodeComponent.nodeHashtable != null) {
duplicateAttributes(originalNodeComponent,
originalNodeComponent.forceDuplicate);
} else {
// user call cloneNodeComponent() or duplicateNodeComponent()
// directly instead of via cloneTree()
originalNodeComponent.nodeHashtable = new Hashtable();
duplicateAttributes(originalNodeComponent,
originalNodeComponent.forceDuplicate);
originalNodeComponent.nodeHashtable = null;
}
}
/**
* Copies all node information from originalNodeComponent
* into the current node. This method is called from the
* cloneNodeComponent
method which is, in turn, called
* by the cloneNode
method.
* true
, causes the
* duplicateOnCloneTree
flag to be ignored. When
* false
, the value of each node's
* duplicateOnCloneTree
variable determines whether
* NodeComponent data is duplicated or copied.
*
* @exception RestrictedAccessException if forceDuplicate is set and
* this object is part of a compiled scenegraph
*
* @see NodeComponent#cloneNodeComponent
* @see Node#cloneNode
* @see Node#cloneTree
*
* @since Java 3D 1.2
*/
public void duplicateNodeComponent(NodeComponent originalNodeComponent,
boolean forceDuplicate) {
originalNodeComponent.forceDuplicate = forceDuplicate;
try {
duplicateNodeComponent(originalNodeComponent);
} catch (RuntimeException e) {
originalNodeComponent.forceDuplicate = false;
throw e;
}
originalNodeComponent.forceDuplicate = false;
}
/**
* Used to create a new instance of a NodeComponent object. This
* routine is called by cloneNode
to duplicate the
* current node. cloneNodeComponent
should be overridden by any user
* subclassed NodeComponent objects. All subclasses must have their
* cloneNodeComponent
* method consist of the following lines:
* * * @param forceDuplicate when set to* public NodeComponent cloneNodeComponent(boolean forceDuplicate) { * UserNodeComponent unc = new UserNodeComponent(); * unc.duplicateNodeComponent(this, forceDuplicate); * return unc; * } *
true
, causes the
* duplicateOnCloneTree
flag to be ignored. When
* false
, the value of each node's
* duplicateOnCloneTree
variable determines whether
* NodeComponent data is duplicated or copied.
*
* @exception RestrictedAccessException if forceDuplicate is set and
* this object is part of a compiled scenegraph
*
* @see NodeComponent#duplicateNodeComponent
* @see Node#cloneNode
* @see Node#cloneTree
*
* @since Java 3D 1.2
*/
public NodeComponent cloneNodeComponent(boolean forceDuplicate) {
// For backward compatibility !
//
// If user did not overwrite this procedure, it will fall back
// to call cloneNodeComponent()
// So for core API,
// don't implement cloneNodeComponent(boolean forceDuplicate)
// otherwise this prcedure will not call and the user
// cloneNodeComponent() will not invoke.
NodeComponent nc;
this.forceDuplicate = forceDuplicate;
try {
nc = cloneNodeComponent();
} catch (RuntimeException e) {
this.forceDuplicate = false;
throw e;
}
this.forceDuplicate = false;
return nc;
}
/**
* Copies all NodeComponent information from
* originalNode
into
* the current node. This method is called from the
* cloneNode
method which is, in turn, called by the
* cloneTree
method.
*
* @param originalNode the original node to duplicate.
* @param forceDuplicate when set to true
, causes the
* duplicateOnCloneTree
flag to be ignored. When
* false
, the value of each node's
* duplicateOnCloneTree
variable determines whether
* NodeComponent data is duplicated or copied.
*
* @see Group#cloneNode
* @see Node#duplicateNode
* @see Node#cloneTree
* @see NodeComponent#setDuplicateOnCloneTree
*/
void duplicateAttributes(NodeComponent originalNode,
boolean forceDuplicate) {
if (forceDuplicate && originalNode.isCompiled()) {
throw new RestrictedAccessException(
J3dI18N.getString("NodeComponent1"));
}
super.duplicateSceneGraphObject(originalNode);
setDuplicateOnCloneTree(originalNode.getDuplicateOnCloneTree());
}
/**
* Creates the retained mode NodeComponentRetained object that this
* NodeComponent object will point to.
*/
@Override
void createRetained() {
this.retained = new NodeComponentRetained();
this.retained.setSource(this);
}
/**
* This function is called from getNodeComponent() to see if any of
* the sub-NodeComponents duplicateOnCloneTree flag is true.
* If it is the case, current NodeComponent needs to
* duplicate also even though current duplicateOnCloneTree flag is false.
* This should be overwrite by NodeComponent which contains sub-NodeComponent.
*/
boolean duplicateChild() {
return getDuplicateOnCloneTree();
}
/*
* @exception IllegalSharingException if this NodeComponent is live and
* the specified image is being used by a Canvas3D as an off-screen buffer.
*
* @exception IllegalSharingException if this NodeComponent is
* being used by an immediate mode context and
* the specified image is being used by a Canvas3D as an off-screen buffer.
*/
void validateImageIllegalSharing(ImageComponent image) {
// Do illegal sharing check
if(image != null) {
ImageComponentRetained imageRetained = (ImageComponentRetained) image.retained;
NodeComponentRetained ncRetained = (NodeComponentRetained)this.retained;
if(imageRetained.getUsedByOffScreen()) {
if(isLive()) {
throw new IllegalSharingException(J3dI18N.getString("NodeComponent2"));
}
if(ncRetained.getInImmCtx()) {
throw new IllegalSharingException(J3dI18N.getString("NodeComponent3"));
}
}
}
}
}