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

Quick Search    Search Deep

Source code: org/pqt/autorib/instr/InstrWReader.java


1   //AutoRIB
2   // Copyright © 1998 - 2002, P W Quint
3   //
4   // Contact: autorib00@aol.com
5   //
6   // This library is free software; you can redistribute it and/or
7   // modify it under the terms of the GNU General Public
8   // License as published by the Free Software Foundation; either
9   // version 2 of the License, or (at your option) any later version.
10  //
11  // This library is distributed in the hope that it will be useful,
12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  // General Public License for more details.
15  //
16  // You should have received a copy of the GNU General Public
17  // License along with this library; if not, write to the Free Software
18  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  
20  package org.pqt.autorib.instr;
21  import java.util.*;
22  import java.io.*;
23  
24  import org.pqt.autorib.tokenizer.*;
25  import org.pqt.autorib.globals.*;
26  import org.pqt.autorib.util.*;
27  import org.pqt.autorib.rib.*;
28  
29  
30  /**
31   * This class provides routines for reading and writing
32   * Instr (instrutions) files, for storing their contents,
33   * and for applying them to RIB.
34   * <p> The writing routines are used for debugging only.
35   *
36   */
37  
38  public class InstrWReader {
39      /** used for saving and restoring the state within blocks */
40      private Stack stateStack = new Stack();
41      /** the current state, by which we mean map dimensions,
42       * filtering etc.
43       */
44      public InstrState state = new InstrState();
45      /** a tokenizer for the instructions file */
46      public  InstrTokenizer tokenizer;
47      /** used to hold the current instruction being read in */
48      private InstrRequest rq = null;
49      /** the number of requests read in this and archived files*/
50      public   int requestsRead = 0;
51      /** true if rq holds a token that has been pushed back*/
52      private boolean pushedBack = false;
53      /** this holds the contents of the instructions file */
54      private Vector content = new Vector(50,25);
55      /** true if we are currently reading instructions from within a lights block*/
56      public boolean inLightBlock = false;
57      /** true if we are reading instructions from within a for block*/
58      public boolean inForBlock = false;
59      /** true if we are reading instructions inside an Objects block*/
60      public boolean inObjectBlock = false;
61      /** used to hold the rib stream being processed */
62      public RIBWReader rib = null;
63      /** this records whether we need to process any RIB added by GlobalRIB or
64       * FrameRIB */
65      public boolean globalOrFrameRIB = false;
66      /** this stores any lights added by FrameRIB (or, indeed, globalRIB) */
67      public Vector addedLights = new Vector(5,5);
68      /** this is used to manage the numbering of groups of individual primitives by name*/
69      public NameGroupManager nameGroupManager = new NameGroupManager();
70      /** this manages name / number lookups */
71      public NameNumberManager nameNumberManager = null;
72      /** this stores saved Pref values from objects */
73      public Hashtable storedPrefs = new Hashtable(50);
74      
75      /** Open the named Instr file
76       * @param name the name of the file to open
77       * @throws FormatException A syntax error
78       * @throws FileNotFoundException The file is not found
79       */
80      public InstrWReader(String name) throws FormatException,
81      FileNotFoundException {
82          tokenizer = new InstrTokenizer(name);
83      }
84      
85      /** Read in a single request
86       * @throws FormatException thrown if a syntax error is found
87       * @throws IOException an io error
88       * @return the instruction read in, or null if the
89       * end of file has been reached
90       */
91      public InstrRequest readRequest() throws FormatException, IOException {
92          if (!pushedBack) {
93              tokenizer.getToken();
94              if (tokenizer.token.tokenType == Token.EOF)
95                  rq = null;  //rq is a class wide variable
96              else if ((tokenizer.token.tokenType == Token.OPENBRACE) ||
97              (tokenizer.token.tokenType == Token.CLOSEBRACE))
98                  rq = new  InstrBrace(tokenizer.token.tokenType);
99              else if (tokenizer.token.tokenType != Token.REQUEST)
100                 throw new FormatException("Instruction expected",tokenizer);
101             else {
102                 tokenizer.token.requestID = findID(tokenizer.token.requestVal);
103                 tokenizer.pushBack();  //make sure token available to be read later
104                 switch (tokenizer.token.requestID) //read in this particular call
105                 {
106                     case InstrGlobals.LIGHTS:
107                         rq = new InstrLights(this);
108                         break;
109                     case InstrGlobals.FORHANDLES:
110                         rq = new InstrForHandles(this);
111                         break;
112                     case InstrGlobals.MAPFORMAT:
113                         rq = new InstrMapFormat(this);
114                         break;
115                     case InstrGlobals.MAPFORMATMULT:
116                         rq = new InstrMapFormatMult(this);
117                         break;
118                     case InstrGlobals.DEFAULTCONEANGLE:
119                         rq = new InstrDefaultConeAngle(this);
120                         break;
121                     case InstrGlobals.APPENDPARAM:
122                     case InstrGlobals.REPLACEPARAM:
123                         rq = new InstrAppendParam(this);
124                         break;
125                     case InstrGlobals.FORSHADERS:
126                         rq = new InstrForShaders(this);
127                         break;
128                     case InstrGlobals.SHADOWSPOT:
129                         rq = new InstrShadowSpot(this);
130                         break;
131                     case InstrGlobals.RENAMESHADER:
132                         rq = new InstrRenameShader(this);
133                         break;
134                     case InstrGlobals.SOFTSHADOWSPOT:
135                         rq = new InstrSoftShadowSpot(this);
136                         break;
137                     case InstrGlobals.FORCOLORS:
138                         rq = new InstrForColors(this);
139                         break;
140                     case InstrGlobals.REMOVEPARAM:
141                         rq = new InstrRemoveParam(this);
142                         break;
143                     case InstrGlobals.RENAMEPARAM:
144                         rq = new InstrRenameParam(this);
145                         break;
146                     case InstrGlobals.SHADOWPOINT:
147                         rq = new InstrShadowPoint(this);
148                         break;
149                     case InstrGlobals.SHADOWDIST:
150                         rq = new InstrShadowDist(this);
151                         break;
152                     case InstrGlobals.ADDRIB:
153                         rq = new InstrAddRIB(this);
154                         break;
155                     case InstrGlobals.OMIT:
156                         rq = new InstrOmit(this);
157                         break;
158                     case InstrGlobals.OBJECTS:
159                         rq = new InstrObjects(this);
160                         break;
161                     case InstrGlobals.ENVMAP:
162                         rq = new InstrEnvMap(this);
163                         break;
164                     case InstrGlobals.FORNAMES:
165                         rq = new InstrForNames(this);
166                         break;
167                     case InstrGlobals.MAPSAMPLES:
168                         rq = new InstrMapSamples(this);
169                         break;
170                     case InstrGlobals.MAPFILTER:
171                         rq = new InstrMapFilter(this);
172                         break;
173                     case InstrGlobals.MAPDISPLAY:
174                         rq = new InstrMapDisplay(this);
175                         break;
176                     case InstrGlobals.REFLMAP:
177                         rq = new InstrReflMap(this);
178                         break;
179                     case InstrGlobals.GLOBALRIB:
180                     case InstrGlobals.FRAMERIB:
181                         globalOrFrameRIB = true;
182                         rq = new InstrRIB(this);
183                         break;
184                     case InstrGlobals.INSTROPTION:
185                         rq = new InstrOption(this);
186                         break;
187                     case InstrGlobals.DELETEPRIMS:
188                         rq = new InstrDeletePrims(this);
189                         break;
190                     case InstrGlobals.APPENDNUMBER:
191                         rq = new InstrAppendNumber(this);
192                         break;
193                     case InstrGlobals.NUMBERGROUP:
194                         rq = new InstrNumberGroup(this);
195                         break;
196                     case InstrGlobals.SURFACE:
197                     case InstrGlobals.DISPLACEMENT:
198                     case InstrGlobals.INTERIOR:
199                     case InstrGlobals.EXTERIOR:
200                     case InstrGlobals.ATMOSPHERE:
201                         rq = new InstrShader(this);
202                         break;
203                     case InstrGlobals.TOSUBDIVISION:
204                         rq = new InstrToSubdivision(this);
205                         break;
206                     case InstrGlobals.ENVMAPAUTO:
207                         rq = new InstrEnvMapAuto(this);
208                         break;
209                     case InstrGlobals.REFLMAPAUTO:
210                         rq = new InstrReflMapAuto(this);
211                         break;
212                     case InstrGlobals.SHADOWDISTAUTO:
213                         rq = new InstrShadowDistAuto(this);
214                         break;
215                     case InstrGlobals.TIGHTCLIPPING:
216                         rq = new InstrTightClipping(this);
217                         break;
218                     case InstrGlobals.LIGHTDOME:
219                         rq = new InstrLightDome(this);
220                         break;
221                     case InstrGlobals.PERSPMAP:
222                         rq = new InstrPerspMap(this);
223                         break;
224                     case InstrGlobals.ORTHOMAP:
225                         rq = new InstrOrthoMap(this);
226                         break;
227                     case InstrGlobals.SIXSNAPS:
228                         rq = new InstrSixSnaps(this);
229                         break;
230                     case InstrGlobals.APPENDPRIMPARAM:
231                         rq = new InstrAppendPrimParam(this);
232                         break;
233                     case InstrGlobals.SAVEPREF:
234                         rq = new InstrSavePref(this);
235                         break;
236                     case InstrGlobals.CLEANPOLY:
237                         rq = new InstrCleanPoly(this);
238                         break;
239                     case InstrGlobals.COMBINEPOLYS:
240                         rq = new InstrCombinePolys(this);
241                         break;
242                     case InstrGlobals.GROUPENVMAP:
243                         rq = new InstrGroupEnvMap(this);
244                         break;
245                     default:
246                         throw new FormatException("Unrecognised request",
247                         tokenizer);
248                 }
249                 requestsRead++;
250             }
251         }
252         else
253             pushedBack = false;
254         return rq;
255     }
256     
257     
258     /**
259      * read a block assuming the opening brace '{' has already been read
260      * @param content instructions read will be added to this Vector
261      * @param valid - an array of instructions that are valid in the block being read
262      * @throws FormatException a syntax error
263      * @throws IOException an io exception
264      */
265     public void readToEndBlock(Vector content, int[] valid) throws FormatException,
266     IOException {
267         InstrRequest ir;
268         while (true) {
269             ir = readRequest();
270             if ((ir == null) || (ir.requestID == Token.OPENBRACE))
271                 throw new FormatException("} expected",tokenizer);
272             else if (ir.requestID == Token.CLOSEBRACE)
273                 break;
274             else {
275                 int i;
276                 for (i = 0; i < valid.length; i++)
277                     if (ir.requestID == valid[i]) break;
278                 if (i < valid.length)
279                     content.addElement(ir);
280                 else
281                     throw new FormatException("Instruction " +
282                     InstrGlobals.requests[ir.requestID - InstrGlobals.BASE] +
283                     " is not allowed here",
284                     tokenizer);
285             }
286         }
287     }
288     
289     /** Read in the whole instuctions file
290      * @throws FormatException if a syntax error is found
291      * @throws IOException an io error
292      */
293     public void read() throws FormatException,
294     IOException {
295         InstrRequest ir;
296         while (true) {
297             ir = readRequest();
298             if (ir == null)
299                 break;
300             else
301                 content.addElement(ir);
302         }
303         //set up the object number handling mechanism now all the groups are read in
304         nameNumberManager = new NameNumberManager(nameGroupManager);
305     }
306     
307     /** write out the entire contents of the stored
308      * instructions file
309      * @param outStream - the stream to write it to
310      * @throws IOException an io error
311      */
312     public void write(Writer outStream) throws IOException {
313         Enumeration i = content.elements();
314         while (i.hasMoreElements())
315             ((InstrRequest)i.nextElement()).write(outStream);
316     }
317     
318     
319     /** Push back the most recently read instruction, so
320      * that it will be returned in response to the next
321      * read
322      */
323     public void pushBack() {
324         if ((requestsRead > 0) && !pushedBack) {
325             pushedBack = true;
326             requestsRead--;
327         }
328     }
329     
330     /** push the current state onto a stack to be retrieved later */
331     public void saveState() {
332         stateStack.push(state.clone());
333     }
334     
335     /** restore the state from the top of the stack */
336     public void restoreState() {
337         if (!stateStack.empty())
338             state = (InstrState) stateStack.pop();
339     }
340     
341     /** process an individual light - go through the instructions file calling
342      * the process functions of all instuctions
343      * @param ribp a RIBWReader linked to the rib file being processed - used mainly to
344      * get line number information for reporting errors
345      * @param light the light to be processed
346      * @throws IOException an io error
347      * @throws FormatException a syntax error
348      */
349     public void process(RIBWReader ribp, RIBLight light) throws IOException,
350     FormatException {
351         rib = ribp;
352         Enumeration i =content.elements();
353         while (i.hasMoreElements())
354             ((InstrRequest)i.nextElement()).process(this, light);
355     }
356     
357     /** Process an object,
358      * @param ribp the rib file from which the object
359      * @param object the object to process
360      * @throws IOException an io error
361      * @throws FormatException a syntax error
362      */
363     public void process(RIBWReader ribp, RIBObjectGroup object) throws IOException,
364     FormatException {
365         rib = ribp;
366         Enumeration i =content.elements();
367         while (i.hasMoreElements())
368             ((InstrRequest)i.nextElement()).process(this, object);
369     }
370     
371     /** process the rib file and add rib. This function is used to add the rib
372      * specified in the GlobalRIB and FrameRIB instructions cf the AddRIB instruction
373      * which works on a per object/light basis
374      * @param ribp the rib stream being processed
375      * @param header the vector to which new rib will be added if it is not an option
376      * - this will either be the GlobalHeader or FrameHeader
377      * @param option the appropriate set of global or frame options - is the RIB to be
378      * added is an option then the contents of this class will be changed, else the
379      * rib will be added to the header
380      * @param instr the instruction request ID appropriate to the type of additions
381      * to be added - in practice either GLOBALRIB or FRAMERIB
382      * @throws IOException an io error
383      * @throws FormatException a syntax error
384      */
385     //this is a dreadful hack - sort it out some time
386     public void process(RIBWReader ribp, Vector header, RIBOptionRec option,
387     int instr) throws IOException, FormatException {
388         rib = ribp;
389         Enumeration i = content.elements();
390         //Add general RIB
391         while (i.hasMoreElements()) {
392             InstrRequest is = (InstrRequest) i.nextElement();
393             if (is.requestID == instr)
394                 ((InstrRIB) is).process(header, option);
395         }
396     }
397     
398     public void processMisc(RIBWReader ribp, RIBOptionRec option) throws IOException, FormatException {
399         rib = ribp;
400         Enumeration i = content.elements();
401         //Add general RIB
402         while (i.hasMoreElements()) {
403             InstrRequest is = (InstrRequest) i.nextElement();
404             if (is.requestID == InstrGlobals.TIGHTCLIPPING) 
405                 ((InstrTightClipping) is).process(ribp, option);
406             else if (is.requestID == InstrGlobals.LIGHTDOME)
407                 ((InstrLightDome) is).process(this, ribp);
408             else if (is.requestID == InstrGlobals.SIXSNAPS)
409                 ((InstrSixSnaps) is).process(ribp);
410         }
411     }
412     
413     
414     /** find the id of a given instruction request
415      * @param name the name of the request
416      * @return the ID of the request, or throw exception if not found */
417     
418     private int findID(String name) throws FormatException {
419         Integer i = (Integer) InstrGlobals.map.get(name);
420         if (i != null)
421             return i.intValue();
422         else
423             throw new FormatException("Unrecognized request",tokenizer);
424     }
425     
426    
427     
428 }//class