001: /*
002: * $RCSfile: Field.java,v $
003: *
004: * @(#)Field.java 1.25 99/03/09 16:36:15
005: *
006: * Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
007: *
008: * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
009: * modify and redistribute this software in source and binary code form,
010: * provided that i) this copyright notice and license appear on all copies of
011: * the software; and ii) Licensee does not utilize the software in a manner
012: * which is disparaging to Sun.
013: *
014: * This software is provided "AS IS," without a warranty of any kind. ALL
015: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
016: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
017: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
018: * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
019: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
020: * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
021: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
022: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
023: * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGES.
025: *
026: * This software is not designed or intended for use in on-line control of
027: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
028: * the design, construction, operation or maintenance of any nuclear
029: * facility. Licensee represents and warrants that it will not use or
030: * redistribute the Software for such purposes.
031: *
032: * $Revision: 1.2 $
033: * $Date: 2005/02/03 23:06:55 $
034: * $State: Exp $
035: */
036: /*
037: * @Author: Rick Goldberg
038: * @Author: Doug Gehringer
039: *
040: */
041: package org.jdesktop.j3d.loaders.vrml97.impl;
042:
043: import org.jdesktop.j3d.loaders.vrml97.impl.*;
044: import java.util.Enumeration;
045: import java.util.Hashtable;
046: import java.util.Vector;
047:
048: /** Description of the Class */
049: public abstract class Field {
050:
051: String fieldName = new String("?");
052: BaseNode ownerNode = null;
053: double lastUpdate = -1.0;// to allow one update only in loader case
054: Vector connections = null;
055: /** Description of the Field */
056: public ConstField constField;
057: /** Description of the Field */
058: public int fieldType = EXPOSED_FIELD;// least restrictive for transition
059:
060: // Field types
061: final static int FIELD = 0;
062: final static int EVENT_IN = 1;
063: final static int EVENT_OUT = 2;
064: final static int EXPOSED_FIELD = 3;
065:
066: // debugging
067: final static boolean printRoutes = false;
068:
069: /**Constructor for the Field object */
070: Field() {
071: }
072:
073: // should be called for all fields in Node in initFields()
074: /**
075: * Description of the Method
076: *
077: *@param node Description of the Parameter
078: *@param fieldSpec Description of the Parameter
079: *@param fieldType Description of the Parameter
080: *@param fieldName Description of the Parameter
081: */
082: void init(BaseNode node, Hashtable fieldSpec, int fieldType,
083: String fieldName) {
084: this .ownerNode = node;
085: this .fieldType = fieldType;
086: this .fieldName = fieldName;
087: if (fieldSpec != null) {
088: fieldSpec.put(fieldName, this );
089: }
090: }
091:
092: /**
093: * Gets the eventOut attribute of the Field object
094: *
095: *@return The eventOut value
096: */
097: boolean isEventOut() {
098: return ((fieldType & EVENT_OUT) != 0);
099: }
100:
101: /**
102: * Gets the eventIn attribute of the Field object
103: *
104: *@return The eventIn value
105: */
106: boolean isEventIn() {
107: return ((fieldType & EVENT_IN) != 0);
108: }
109:
110: // to implement ROUTE
111: // Node: fields used to be connected using ConstField->Field. Changed
112: // to do this here so that all the timing logic is together. ConstFields
113: // are now just wrappers that limit access to Fields.
114: /** Description of the Method */
115: synchronized void route() {
116: double eventTime;
117: if (ownerNode != null) {
118: if (ownerNode.browser != null) {
119: eventTime = ownerNode.browser.beginRoute();
120: } else {
121: // if no browser, then time is always 0.0. lastUpdate is
122: // initialized to -1.0 to allow one update but no more.
123: eventTime = 0.0;
124: }
125: if (printRoutes) {
126: System.out.println("Owner of field "
127: + this .toStringId() + " is "
128: + ownerNode.toStringId());
129: System.out.println("Field type is " + fieldType);
130: }
131: if (isEventIn() && ownerNode.implReady) {
132: if (printRoutes) {
133: System.out
134: .println("Calling notifyMethod() on owner");
135: }
136: ownerNode.notifyMethod(fieldName, eventTime);
137: }
138: } else {
139: eventTime = Time.getNow();
140: }
141: // Test time to avoid sending two events with same timestamp from
142: // a EventOut
143: if (lastUpdate != eventTime) {
144: lastUpdate = eventTime;
145: if (connections != null) {
146: for (Enumeration e = connections.elements(); e
147: .hasMoreElements();) {
148: Field routeField = (Field) e.nextElement();
149: // Test time to avoid sending two event with same
150: // timestamps to an EventIn
151: if (routeField.lastUpdate != eventTime) {
152: if (printRoutes) {
153: System.out.println("Field.route: field "
154: + fieldName + " " + this
155: + "\n is updating "
156: + routeField.fieldName + " "
157: + routeField);
158: }
159: routeField.update(this );
160: } else {
161: if (printRoutes) {
162: System.out
163: .println("Field.route: Not updating "
164: + "routeField "
165: + routeField.fieldName
166: + " "
167: + routeField
168: + "\n lastUpdate ("
169: + ownerNode.browser
170: .relativeTime(routeField.lastUpdate)
171: + ") == eventTime");
172: }
173: }
174: }
175: }
176: } else {
177: if (printRoutes) {
178: System.out.println("After update, field " + fieldName
179: + " " + this + "\n lastUpdate ("
180: + ownerNode.browser.relativeTime(lastUpdate)
181: + ") == eventTime, not routing");
182: }
183: }
184: if ((ownerNode != null) && (ownerNode.browser != null)) {
185: ownerNode.browser.endRoute();
186: }
187: }
188:
189: /**
190: * Description of the Method
191: *
192: *@param field Description of the Parameter
193: */
194: void connectToField(Field field) {
195: if (connections == null) {
196: connections = new Vector();
197: }
198: if (!connections.contains(field)) {
199: connections.addElement(field);
200: }
201: }
202:
203: /**
204: * Description of the Method
205: *
206: *@param field Description of the Parameter
207: */
208: void deleteConnection(Field field) {
209: connections.removeElement(field);
210: }
211:
212: /**
213: * Description of the Method
214: *
215: *@param field Description of the Parameter
216: */
217: abstract void update(Field field);
218:
219: // should initialize constField
220: /**
221: * Description of the Method
222: *
223: *@return Description of the Return Value
224: */
225: abstract ConstField constify();
226:
227: /**
228: * Description of the Method
229: *
230: *@return Description of the Return Value
231: */
232: public abstract Object clone();
233:
234: /**
235: * Description of the Method
236: *
237: *@return Description of the Return Value
238: */
239: public abstract vrml.Field wrap();
240:
241: /**
242: * Description of the Method
243: *
244: *@return Description of the Return Value
245: */
246: public String toStringId() {
247: return this .getClass().getName() + "@"
248: + Integer.toHexString(this .hashCode());
249: }
250:
251: // This should be done only to nodes that are j3d impls that
252: // benefit from compile. Eg, audioclip now has to if check each
253: // simtick for route_ prefix but it never uses the prefix.
254: // possibly an interface called RoutePrefixable ? If ownernode
255: // instance of RoutePrefixable then notifyMethod.
256: /** Description of the Method */
257: public void markWriteable() {
258: ownerNode.notifyMethod("route_" + fieldName, 0.0d);
259: }
260:
261: // remove the "set_" or "_changed" from a fieldName
262: /**
263: * Description of the Method
264: *
265: *@param fieldName Description of the Parameter
266: *@return Description of the Return Value
267: */
268: public static String baseName(String fieldName) {
269: String newName = fieldName;
270: if (fieldName.startsWith("set_")) {
271: newName = fieldName.substring(4);
272: //System.out.println("Field.baseName() Removed set_: old " +
273: // fieldName + " new: " + newName);
274: }
275: if (fieldName.endsWith("_changed")) {
276: newName = fieldName.substring(0, fieldName
277: .indexOf("_changed"));
278: //System.out.println("Field.baseName() Removed _changed: old " +
279: // fieldName + " new: " + newName);
280: }
281: return newName;
282: }
283: }
|