00001 /*======================================================================= 00002 * Copyright 1991-1996, Silicon Graphics, Inc. 00003 * ALL RIGHTS RESERVED 00004 * 00005 * UNPUBLISHED -- Rights reserved under the copyright laws of the United 00006 * States. Use of a copyright notice is precautionary only and does not 00007 * imply publication or disclosure. 00008 * 00009 * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND: 00010 * Use, duplication or disclosure by the Government is subject to restrictions 00011 * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights 00012 * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or 00013 * in similar or successor clauses in the FAR, or the DOD or NASA FAR 00014 * Supplement. Contractor/manufacturer is Silicon Graphics, Inc., 00015 * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311. 00016 * 00017 * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY 00018 * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION, 00019 * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY 00020 * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON 00021 * GRAPHICS, INC. 00022 **=======================================================================*/ 00023 /*======================================================================= 00024 ** Author : Paul S. Strauss (MMM yyyy) 00025 ** Modified by : Nick Thompson (MMM yyyy) 00026 ** Modified by : Gavin Bell (MMM yyyy) 00027 **=======================================================================*/ 00028 /*======================================================================= 00029 *** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), *** 00030 *** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. *** 00031 *** *** 00032 *** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS *** 00033 *** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR *** 00034 *** WRITTEN AUTHORIZATION OF FEI S.A.S. *** 00035 *** *** 00036 *** RESTRICTED RIGHTS LEGEND *** 00037 *** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS *** 00038 *** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN *** 00039 *** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT *** 00040 *** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN *** 00041 *** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. *** 00042 *** *** 00043 *** COPYRIGHT (C) 1996-2023 BY FEI S.A.S, *** 00044 *** BORDEAUX, FRANCE *** 00045 *** ALL RIGHTS RESERVED *** 00046 **=======================================================================*/ 00047 /*======================================================================= 00048 ** Modified by : VSG (MMM YYYY) 00049 **=======================================================================*/ 00050 00051 00052 #ifndef _SO_BASE_ 00053 #define _SO_BASE_ 00054 00055 #include <Inventor/misc/SoBasic.h> 00056 #include <Inventor/misc/SoAuditorList.h> 00057 #include <Inventor/misc/SoRefCounter.h> 00058 #include <Inventor/SbString.h> 00059 #include <Inventor/SoTypedObject.h> 00060 #include <Inventor/threads/SbThreadSpinlock.h> 00061 00062 class SoBaseList; 00063 class SoInput; 00064 class SoNode; 00065 class SoNotList; 00066 class SoOutput; 00067 class SoPath; 00068 00069 #ifdef _WIN32 00070 #pragma warning(push) 00071 #pragma warning(disable:4251) 00072 #endif 00073 00075 // 00076 // Class: SoBase 00077 // 00078 // Base class for most important SO classes. All subclasses of this 00079 // class may be read and written, in the form: 00080 // NameOfClass { 00081 // <stuff inside> 00082 // } 00083 // where NameOfClass is the thing returned by getFileName(). For example, 00084 // the "FileName" of the SoPath class is "Path". 00085 // 00087 00088 00111 class SoBase: public SoRefCounter, public SoTypedObject { 00112 public: 00113 00119 virtual void touch() { startNotify(); } 00120 00124 static SoType getClassTypeId(); 00125 00131 virtual SbName getName() const; 00132 00154 virtual void setName(const SbName &name); 00155 00160 inline void setSynchronizable( const bool b ); 00161 00165 inline bool isSynchronizable() const ; 00166 00167 private: 00168 00169 // Constructor is protected - this is an abstract class 00170 SoBase(); 00171 00172 // Virtual destructor so that subclasses are deleted properly 00173 virtual ~SoBase(); 00174 00179 virtual bool notifyDelete() const; 00180 00181 // Actually deletes an instance. Allows subclasses to do other 00182 // stuff before the deletion if necessary. 00183 virtual void destroy(); 00184 00185 // Returns current write counter 00186 static uint32_t getCurrentWriteCounter(); 00187 00188 // Returns TRUE if the instance has multiple write references 00189 SbBool hasMultipleWriteRefs() const 00190 { return writeStuff.multWriteRef; } 00191 00192 // Unknown nodes and engines write a different name for themselves 00193 // than their typeId; this virtual method lets them do that (by 00194 // default the typeId name is returned) 00195 virtual const char* getFileFormatName() const; 00196 00197 // This set of enums is used when reading and writing the base. 00198 // Each enum represents a different bit in a bit field 00199 // which will be written. 00200 enum BaseFlags { 00201 IS_ENGINE = 1, 00202 IS_GROUP = 2 00203 }; 00204 00205 // Reads stuff into instance of subclass. Return FALSE on error. 00206 // If reading binary file format, the flags specify whether the 00207 // object was written as an engine or a group; unknown nodes and 00208 // groups need this information to read themselves in properly. 00209 virtual SbBool readInstance(SoInput *in, unsigned short flags) = 0; 00210 00211 private: 00212 00213 // Setup type information 00214 static void initClass(); 00215 static void exitClass(); 00216 00217 // Enable/disable ART synchronization. If false, all ART serialization is disabled. 00218 // Can be usefull to disable serialization in some part of code. 00219 // Default is true. Return previous value. 00220 static bool setSynchronizationEnabled(bool value) 00221 { 00222 bool old = s_synchronizationEnabled; 00223 s_synchronizationEnabled = value; 00224 return old; 00225 } 00226 00227 static void resetWriteCounter(); 00228 00229 // Increments the current write counter at the start of a write operation 00230 static void incrementCurrentWriteCounter(); 00231 00232 // Decrements the current write counter after a write operation, 00233 // in some rare cases 00234 static void decrementCurrentWriteCounter(); 00235 00236 // Initiates notification from an instance. The default method 00237 // does nothing, because some classes (path, sensor) never 00238 // initiate notification. This is used by touch(). 00239 virtual void startNotify(); 00240 00241 // Propagates modification notification through an instance. The 00242 // default method here does not create and add a new record. It 00243 // merely propagates the current record list to all auditors. This 00244 // method may be used by subclasses to do the propagation after 00245 // modifying the list appropriately. 00246 virtual void notify(SoNotList *list); 00247 00248 // Adds/removes an auditor to/from list 00249 void addAuditor(void *auditor, SoNotRec::Type type); 00250 void removeAuditor(void *auditor, SoNotRec::Type type); 00251 00252 // Returns auditor list-- used by SoField and SoEngineOutput to 00253 // trace forward connections 00254 const SoAuditorList &getAuditors() const { return auditors; } 00255 00256 // Internal methods used to maintain the global name dictionary 00257 static void addName(SoBase *, const char *); 00258 static void removeName(SoBase *, const char *); 00259 00260 // Helper routines used to get stuff out of nameDict 00261 static SoBase *getNamedBase(const SbName &, const SoType&); 00262 static int getNamedBases(const SbName &, SoBaseList &, const SoType&); 00263 00264 // Set the net name of an instance. 00265 virtual void setNetName( const SbName &netName); 00266 00267 // Get the net name of an instance. 00268 virtual SbName getNetName() const; 00269 00270 // Compute automatically the net name of the instance. 00271 virtual void generateNetName(); 00272 00273 // Sets this a ScaleViz synchronized object. 00274 inline void setSynchronized( const bool b ); 00275 00276 // Gets the ScaleViz synchronized state of this object. 00277 inline bool isSynchronized() const; 00278 00287 SbBool writeHeader(SoOutput* , SbBool , SbBool ) const; 00288 void writeFooter(SoOutput* ) const; 00289 00290 virtual bool isGroup() { return false; } 00291 00292 // Reads one instance of some subclass of SoBase. Returns pointer 00293 // to read-in instance in base, or NULL on EOF. Returns FALSE on 00294 // error. The last parameter is a subclass type to match. If 00295 // the returned base is not of this type, it is an error. A type 00296 // of SoBase::getClassTypeId() will match any base. 00297 static SbBool read(SoInput *in, SoBase *&base, const SoType &expectedType, SbBool createAndRead = TRUE); 00298 00299 // Adds a reference to the instance when writing. isFromField 00300 // indicates whether the reference is from a field-to-field 00301 // connection. 00302 virtual void addWriteReference(SoOutput *out, SbBool isFromField = FALSE); 00303 00304 // Returns TRUE if the instance should be written, based on the 00305 // write-reference info already accumulated 00306 SbBool shouldWrite(); 00307 00308 // This defaults to "+" and is used when naming nodes that are DEF's and USE'd. 00309 // The ivdowngrade converter needs to set it to other than "+" since that was 00310 // an illegal character for Inventor V1.0 names. 00311 static void setInstancePrefix(const SbString &c); 00312 00313 // These are all packed into one word to save space 00314 struct WriteStuff { 00315 // This contains the value of the counter the last time the 00316 // instance was written. 00317 unsigned int writeCounter : 26; 00318 00319 // This is TRUE if the object is named. 00320 unsigned int hasName : 1; 00321 unsigned int hasNetName : 1; 00322 00323 // This is TRUE if more than one reference is made to the 00324 // instance for writing, meaning that we need to DEF it 00325 unsigned int multWriteRef : 1; 00326 00327 // This is TRUE if the instance was referenced via a 00328 // field-to-field connection, which is not a "real" reference 00329 unsigned int writeRefFromField : 1; 00330 00331 // This is TRUE if the instance was already synchronized 00332 // through ScaleViz 00333 unsigned int isSynchronized : 1; 00334 00335 // This is TRUE if the instance can be synchronized 00336 // through ScaleViz 00337 unsigned int isSynchronizable : 1; 00338 00339 // Default Constructor 00340 WriteStuff(); 00341 }; 00342 00343 WriteStuff writeStuff; 00344 00345 private: 00346 00347 static SoType classTypeId; 00348 00349 static SbString instancePrefix; 00350 00351 // This is incremented once per write operation. It is used to 00352 // determine which instances to write. 00353 static uint32_t s_currentWriteCounter; 00354 static SbThreadRWMutex s_writeCounterMutex; 00355 00356 // List of auditors: objects to pass notification to 00357 SoAuditorList auditors; 00358 00359 // If false, disable all ART serialization. True by default. 00360 static bool s_synchronizationEnabled; 00361 00362 // These are used internally by writeHeader() 00363 void writeDef(SoOutput *, int) const; 00364 void writeRef(SoOutput *, int) const; 00365 void writeAnnotation(SoOutput *) const; 00366 void writeAnnotation1(SoOutput *) const; 00367 00368 static SbBool readReference(SoInput *in, SoBase *&base); 00369 static SbBool readBase(SoInput *in, SbName &className, SoBase *&base, SbBool createAndRead = TRUE); 00370 static SbBool readBaseInstance( SoInput *in, 00371 const SbName &className, const SbName &refName, 00372 const SbName &netName, SoBase *&base, SbBool createAndRead = TRUE); 00373 static SoBase* createInstance(SoInput *in, SbName className, unsigned short ioFlags); 00374 00375 static void flushInput(SoInput *in); 00376 00377 // This dictionary stores SbPLists keyed by name (the SbPLists 00378 // contain SoBases-- a BaseList isn't used because we don't want 00379 // the items on the list to be reference counted, otherwise they 00380 // will never get deleted). 00381 static SbDict *nameObjDict; 00382 00383 // And this dictionary maps the other way, from an SoBase * to a 00384 // name. 00385 static SbDict *objNameDict; 00386 00387 friend class SoVRMLDB; 00388 }; 00389 00390 #ifdef _WIN32 00391 #pragma warning(pop) 00392 #endif 00393 00398 { 00399 public: 00400 SoBaseInitializer(SoBase*); 00401 ~SoBaseInitializer(); 00402 static inline bool isActive() 00403 { 00404 s_activeMutex.lock(); 00405 bool ret = m_active; 00406 s_activeMutex.unlock(); 00407 return ret; 00408 } 00409 private: 00410 SoBase* m_base; 00411 bool m_sync; 00412 bool m_prevActive; 00413 static bool m_active; 00414 static SbThreadSpinlock s_activeMutex; 00415 }; 00416 00417 00418 void 00419 SoBase::setSynchronizable( const bool b ) 00420 { 00421 writeStuff.isSynchronizable = b; 00422 } 00423 00424 bool 00425 SoBase::isSynchronizable() const 00426 { 00427 return writeStuff.isSynchronizable && s_synchronizationEnabled; 00428 } 00429 00430 void 00431 SoBase::setSynchronized( const bool b ) 00432 { 00433 writeStuff.isSynchronized = b; 00434 } 00435 00436 bool 00437 SoBase::isSynchronized() const 00438 { 00439 return writeStuff.isSynchronized; 00440 } 00441 00442 #endif /* _SO_BASE_ */ 00443 00444