001: /*
002: * $RCSfile: NodeComponentRetained.java,v $
003: *
004: * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.7 $
028: * $Date: 2008/02/28 20:17:26 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import java.util.ArrayList;
035:
036: /**
037: * Retained version of NodeComponent
038: */
039:
040: class NodeComponentRetained extends SceneGraphObjectRetained {
041:
042: // duplicate or make a reference when cloneTree() is called
043: // on this object.
044: boolean duplicateOnCloneTree = false;
045:
046: // This keeps track of how many times this NodeComponent is referenced in
047: // the Scene Graph
048: int refCount = 0; // this is used in setLive
049: int refCnt = 0; // this is used in compile
050:
051: // This is true when this appearance is referenced in an immediate mode context
052: private boolean inImmCtx = false;
053:
054: // A list of NodeRetained Objects that refer, directly or indirectly, to this
055: // NodeComponentRetained
056: ArrayList users = new ArrayList(1);
057:
058: // Mirror object of this node compoenent object
059: NodeComponentRetained mirror = null;
060:
061: // Sole User FrequencyBit
062: // In the case of Appearance, its a bitmask of all components
063: int changedFrequent = 0;
064: int compChanged = 0;
065:
066: // Increment the refcount. If this is the first, mark it as live.
067: void doSetLive(boolean inBackgroundGroup, int refCount) {
068: int oldRefCount = this .refCount;
069: this .refCount += refCount;
070: if (oldRefCount <= 0) {
071: super .doSetLive(inBackgroundGroup);
072:
073: // Create and init a mirror object if not already there
074: // The two procedures is combined since it is redunctant to
075: // call initMirrorObject() if mirror == this (static object).
076: createMirrorObject();
077: }
078: }
079:
080: void setLive(boolean inBackgroundGroup, int refCount) {
081: int oldRefCount = this .refCount;
082: doSetLive(inBackgroundGroup, refCount);
083: if (oldRefCount <= 0) {
084: super .markAsLive();
085: }
086: }
087:
088: // Decrement the refcount. If this is the last, mark it as not live.
089: void clearLive(int refCount) {
090: this .refCount -= refCount;
091:
092: if (this .refCount <= 0) {
093: super .clearLive();
094: }
095: }
096:
097: // increment the compile reference count
098: synchronized void incRefCnt() {
099: refCnt++;
100: }
101:
102: // decrement the compile reference count
103: synchronized void decRefCnt() {
104: refCnt--;
105: }
106:
107: // remove mirror shape from the list of users
108: void removeAMirrorUser(Shape3DRetained ms) {
109: synchronized (mirror.users) {
110: mirror.users.remove(ms);
111: }
112: }
113:
114: // Add a mirror shape to the list of users
115: void addAMirrorUser(Shape3DRetained ms) {
116: synchronized (mirror.users) {
117: mirror.users.add(ms);
118: }
119: }
120:
121: // Copy the list of useres passed in into this
122: void copyMirrorUsers(NodeComponentRetained node) {
123: synchronized (mirror.users) {
124: synchronized (node.mirror.users) {
125: int size = node.mirror.users.size();
126: for (int i = 0; i < size; i++) {
127: mirror.users.add(node.mirror.users.get(i));
128: }
129: }
130: }
131: }
132:
133: // Remove the users of "node" from "this" node compoenent
134: void removeMirrorUsers(NodeComponentRetained node) {
135:
136: synchronized (mirror.users) {
137: synchronized (node.mirror.users) {
138: for (int i = node.mirror.users.size() - 1; i >= 0; i--) {
139: mirror.users.remove(mirror.users
140: .indexOf(node.mirror.users.get(i)));
141: }
142: }
143: }
144: }
145:
146: // Add a user to the list of users
147: synchronized void removeUser(NodeRetained node) {
148: if (node.source.isLive())
149: users.remove(users.indexOf(node));
150: }
151:
152: // Add a user to the list of users
153: synchronized void addUser(NodeRetained node) {
154: if (node.source.isLive())
155: users.add(node);
156: }
157:
158: // Add a user to the list of users
159: synchronized void notifyUsers() {
160:
161: if (source == null || !source.isLive()) {
162: return;
163: }
164:
165: for (int i = users.size() - 1; i >= 0; i--) {
166: ((NodeRetained) users.get(i))
167: .notifySceneGraphChanged(false);
168: }
169: }
170:
171: /**
172: * This sets the immedate mode context flag
173: */
174: void setInImmCtx(boolean inCtx) {
175: inImmCtx = inCtx;
176: }
177:
178: /**
179: * This gets the immedate mode context flag
180: */
181: boolean getInImmCtx() {
182: return (inImmCtx);
183: }
184:
185: /**
186: * Sets this node's duplicateOnCloneTree value. The
187: * <i>duplicateOnCloneTree</i> value is used to determine if NodeComponent
188: * objects are to be duplicated or referenced during a
189: * <code>cloneTree</code> operation. A value of <code>true</code> means
190: * that this NodeComponent object should be duplicated, while a value
191: * of <code>false</code> indicates that this NodeComponent object's
192: * reference will be copied into the newly cloned object. This value
193: * can be overriden via the <code>forceDuplicate</code> parameter of
194: * the <code>cloneTree</code> method.
195: * @param duplicate the value to set.
196: * @see Node#cloneTree
197: */
198: void setDuplicateOnCloneTree(boolean duplicate) {
199: duplicateOnCloneTree = duplicate;
200: }
201:
202: /**
203: * Returns this node's duplicateOnCloneTree value. The
204: * <i>duplicateOnCloneTree</i> value is used to determine if NodeComponent
205: * objects are to be duplicated or referenced during a
206: * <code>cloneTree</code> operation. A value of <code>true</code> means
207: * that this NodeComponent object should be duplicated, while a value
208: * of <code>false</code> indicates that this NodeComponent object's
209: * reference will be copied into the newly cloned object. This value
210: * can be overriden via the <code>forceDuplicate</code> parameter of
211: * the <code>cloneTree</code> method.
212: * @return the value of this node's duplicateOnCloneTree
213: * @see Node#cloneTree
214: */
215: boolean getDuplicateOnCloneTree() {
216: return duplicateOnCloneTree;
217: }
218:
219: void initMirrorObject() {
220: }
221:
222: void updateMirrorObject(int component, Object obj) {
223: }
224:
225: void createMirrorObject() {
226: // Overridden by appearance and other classes
227: initMirrorObject();
228: mirror = null;
229: }
230:
231: void setFrequencyChangeMask(int bit, int mask) {
232: if (source.getCapabilityIsFrequent(bit))
233: changedFrequent |= mask;
234: else if (!source.isLive()) {
235: // Record the freq->infreq change only for non-live node components
236: changedFrequent &= ~mask;
237: }
238: }
239:
240: protected Object clone() {
241: NodeComponentRetained ncr = (NodeComponentRetained) super
242: .clone();
243: ncr.changedFrequent = changedFrequent;
244: return ncr;
245: }
246:
247: protected void set(NodeComponentRetained nc) {
248: changedFrequent = nc.changedFrequent;
249: }
250: }
|