Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/trapezium/vrml/fields/Field.java


1   /*
2    * @(#)Field.java
3    *
4    * Copyright (c) 1998 by Trapezium Development LLC.  All Rights Reserved.
5    *
6    * The information in this file is the property of Trapezium Development LLC
7    * and may be used only in accordance with the terms of the license granted
8    * by Trapezium.
9    *
10   */
11  package com.trapezium.vrml.fields;
12  
13  import com.trapezium.parse.TokenEnumerator;
14  import com.trapezium.vrml.MultipleTokenElement;
15  import com.trapezium.vrml.VrmlElement;
16  import com.trapezium.vrml.FieldId;
17  import com.trapezium.vrml.Scene;
18  import com.trapezium.vrml.node.Node;
19  import com.trapezium.vrml.node.DEFUSENode;
20  import com.trapezium.vrml.node.NodeType;
21  import com.trapezium.vrml.grammar.VRML97;
22  import com.trapezium.pattern.Visitor;
23  
24  /**
25   *  Base class for all field instances.
26   *
27   *  A Field is the range of tokens from the field id to the last token 
28   *  in the field value..
29   *  
30   *  @author          Johannes N. Johannsen
31   *  @version         1.1, 13 Jan 1998
32   *
33   *  @since           1.0
34   */
35  public class Field extends MultipleTokenElement {
36    /** used only for indicating if PROTO field declarations are used by IS */
37    // need to move this over into PROTO interface vector
38    boolean inUse = false;
39    public void markInUse() {
40      inUse = true;
41    }
42    public boolean isInUse() {
43      return( inUse );
44    }
45    
46    /** check if this field is an ISField */
47    public boolean isISfield() {
48        if ( fieldValue != null ) {
49            return( fieldValue.getChildAt( 0 ) instanceof ISField );
50        } else {
51            return( false );
52        }
53    }
54  
55    
56    /** base constructor */
57    public Field( int tokenOffset ) {
58      super( tokenOffset );
59    }
60  
61      FieldValue fieldValue;
62      
63    /** Get a FieldValue for this field */
64    public FieldValue getFieldValue() {
65        return( fieldValue );
66    }
67    
68    public void setFieldValue( FieldValue fv ) {
69        fieldValue = fv;
70        if ( fv != null ) {
71            fieldValue.setParent( this );
72        }
73    }
74    
75    public void fieldValueTraverse( Visitor v ) {
76        if ( fieldValue != null ) {
77            if ( v.isTwoPassVisitor() ) {
78                fieldValue.twoPassTraverse( v );
79            } else {
80                   fieldValue.traverse( v );
81               }
82        }
83    }
84  
85    /**
86     *  Get a string identifying the type of this field.
87     */
88    int fieldType;
89    public int getFieldType() {
90      return( fieldType );
91    }
92    public void setFieldType( String fieldType ) {
93        setFieldType( VRML97.typeStrToInt( fieldType ));
94    }
95    public void setFieldType( int ft ) {
96      fieldType = ft;
97    }
98  
99      /** Template, get the interface type
100      *
101      *  @returns one of the following: VRML97.exposedField, VRML97.field,
102      *     VRML97.eventIn, VRML97.eventOut
103      */
104     public int getInterfaceType() {
105         return( -1 );
106     }
107     
108   String fieldId;
109   
110   /** Get the name identifying this field */
111   public String getFieldId() {
112       return( fieldId );
113   }
114   
115   /** Set the name identifying this field */
116   public void setFieldId( String id ) {
117       fieldId = id;
118   }
119 
120     /** Get the Node that is the parent of this Field */
121   public Node getNodeParent() {
122     VrmlElement p = getParent();
123     while (( p != null ) && ( !( p instanceof Node ))) {
124       p = p.getParent();
125     }
126     if ( p != null ) {
127       return( (Node)p );
128     } else {
129       return( null );
130     }
131   }
132   
133   /** Get the Node that is the field value of this field, bypassing DEF/USE */
134   public Node getNodeValue() {
135       // this is convenience routine for Fields representing Nodes
136       if ( fieldValue instanceof SFNodeValue ) {
137           VrmlElement node = fieldValue.getChildAt( 0 );
138           if ( node instanceof Node ) {
139               if ( node instanceof DEFUSENode ) {
140                   node = ((DEFUSENode)node).getNode();
141               }
142               return( (Node)node );
143           }
144       }
145       return( null );
146   }
147   
148   /** Get the Node that is the field value, returning DEF/USE if present */
149   public Node getNode() {
150       if ( fieldValue instanceof SFNodeValue ) {
151           VrmlElement node = fieldValue.getChildAt( 0 );
152           if ( node instanceof Node ) {
153               return( (Node)node );
154           }
155       }
156       return( null );
157   }
158 
159     /** Get a float value at a particular offset in a list for this Field.
160      *
161      *  @param dataSource TokenEnumerator containing data
162      *  @param offset offset of the NumberToken to get the value for
163      *  @return the float value at the offset
164      *  @throws IndexOutOfBoundsException if the offset is outside token range
165      */
166      class GetFloatOptimizer {
167         final int SaveSize = 20;
168         int[] offsets;
169         int[] scannerValues;
170         int firstOffset;
171         int lastOffset;
172         int idx;
173         
174         public GetFloatOptimizer( TokenEnumerator dataSource, int firstOffset, int lastOffset ) {
175             this.firstOffset = firstOffset;
176             this.lastOffset = lastOffset;
177             idx = 0;
178             offsets = new int[SaveSize];
179             scannerValues = new int[SaveSize];
180             idx = 0;
181             setup( dataSource );
182         }
183         
184         void setup( TokenEnumerator dataSource ) {
185             int scanSize = ( lastOffset - firstOffset )/( SaveSize + 1 );
186             if ( scanSize <= 0 ) {
187                 return;
188             }
189             
190             int counter = 1;
191             int scanner = firstOffset;
192             dataSource.setState( scanner );
193             while ( scanner < lastOffset ) {
194                 scanner = dataSource.skipToNumber( scanSize );
195                 if ( scanner == -1 ) {
196                     break;
197                 }
198                 offsets[ idx ] = scanSize*counter;
199                 scannerValues[ idx ] = scanner;
200                 idx++;
201                 counter++;
202                 if ( idx >= SaveSize ) {
203                     break;
204                 }
205             }
206         }
207                 
208         
209         int skipToNumber( TokenEnumerator dataSource, int offset ) {
210             int originalOffset = offset;
211             int foundIdx = -1;
212             int foundDistance = -1;
213             for ( int i = 0; i < idx; i++ ) {
214                 if ( offsets[i] < offset ) {
215                     if ( foundIdx == -1 ) {
216                         foundIdx = i;
217                         foundDistance = offsets[i];
218                     } else if ( offsets[i] > foundDistance ) {
219                         foundIdx = i;
220                         foundDistance = offsets[i];
221                     }
222                 } else {
223                     break;
224                 }
225             }
226             if ( foundIdx != -1 ) {
227                 offset -= offsets[foundIdx];
228                 dataSource.setState( scannerValues[foundIdx] );
229             } else {
230                 dataSource.setState( firstOffset );
231             }
232             return( dataSource.skipToNumber( offset ));
233         }
234      }
235      transient GetFloatOptimizer getFloatOptimizer;
236   public float getFloat( TokenEnumerator dataSource, int offset ) throws IndexOutOfBoundsException {
237       if ( getFloatOptimizer == null ) {
238           getFloatOptimizer = new GetFloatOptimizer( dataSource, getFirstTokenOffset(), getLastTokenOffset() );
239       }
240       int oldState = dataSource.getState();
241       int scanner = getFloatOptimizer.skipToNumber( dataSource, offset );
242 //        dataSource.setState( firstToken );
243 //      int scanner = dataSource.skipToNumber( offset );
244 //        if (( scanner >= lastToken ) || ( scanner == -1 )) {
245         if ( scanner == -1 ) {
246             dataSource.setState( oldState );
247             throw new IndexOutOfBoundsException( "Bad offset " + offset );
248         }
249         float result = dataSource.getFloat( scanner );
250         dataSource.setState( oldState );
251         return( result );
252   }
253 
254   /** Clone a field value into a new Field */
255   protected void cloneFieldValue( Field result, VrmlElement protoInstance ) {
256       result.setFieldId( getFieldId() );
257       FieldValue fv = getFieldValue();
258       if ( fv != null ) {
259           FieldValue fvClone = (FieldValue)fv.vrmlClone( protoInstance );
260           VrmlElement preservedParent = null;
261           if ( fvClone == fv ) {
262               preservedParent = fv.getParent();
263           }
264           result.setFieldValue( fvClone );
265           if ( preservedParent != null ) {
266               fv.setParent( preservedParent );
267           }
268       }
269   }
270 }
271 
272