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-2019 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/SbThreadLocalStorage.h> 00061 #include <Inventor/threads/SbThreadSpinlock.h> 00062 00063 class SoBaseList; 00064 class SoInput; 00065 class SoNode; 00066 class SoNotList; 00067 class SoOutput; 00068 class SoPath; 00069 00070 #ifdef _WIN32 00071 #pragma warning(push) 00072 #pragma warning(disable:4251) 00073 #endif 00074 00076 // 00077 // Class: SoBase 00078 // 00079 // Base class for most important SO classes. All subclasses of this 00080 // class may be read and written, in the form: 00081 // NameOfClass { 00082 // <stuff inside> 00083 // } 00084 // where NameOfClass is the thing returned by getFileName(). For example, 00085 // the "FileName" of the SoPath class is "Path". 00086 // 00088 00089 00112 class SoBase: public SoRefCounter, public SoTypedObject { 00113 public: 00114 00120 virtual void touch() { startNotify(); } 00121 00125 static SoType getClassTypeId(); 00126 00132 virtual SbName getName() const; 00133 00155 virtual void setName(const SbName &name); 00156 00161 inline void setSynchronizable( const bool b ); 00162 00166 inline bool isSynchronizable() const ; 00167 00168 private: 00169 00170 // Constructor is protected - this is an abstract class 00171 SoBase(); 00172 00173 // Virtual destructor so that subclasses are deleted properly 00174 virtual ~SoBase(); 00175 00180 virtual bool notifyDelete() const; 00181 00182 // Actually deletes an instance. Allows subclasses to do other 00183 // stuff before the deletion if necessary. 00184 virtual void destroy(); 00185 00186 // Returns current write counter 00187 static uint32_t getCurrentWriteCounter(); 00188 00189 // Returns TRUE if the instance has multiple write references 00190 SbBool hasMultipleWriteRefs() const 00191 { return writeStuff.multWriteRef; } 00192 00193 // Unknown nodes and engines write a different name for themselves 00194 // than their typeId; this virtual method lets them do that (by 00195 // default the typeId name is returned) 00196 virtual const char* getFileFormatName() const; 00197 00198 // This set of enums is used when reading and writing the base. 00199 // Each enum represents a different bit in a bit field 00200 // which will be written. 00201 enum BaseFlags { 00202 IS_ENGINE = 1, 00203 IS_GROUP = 2 00204 }; 00205 00206 // Reads stuff into instance of subclass. Return FALSE on error. 00207 // If reading binary file format, the flags specify whether the 00208 // object was written as an engine or a group; unknown nodes and 00209 // groups need this information to read themselves in properly. 00210 virtual SbBool readInstance(SoInput *in, unsigned short flags) = 0; 00211 00212 private: 00213 00214 // Setup type information 00215 static void initClass(); 00216 static void exitClass(); 00217 00218 SB_THREAD_TLS_HEADER(); 00219 00220 // Enable/disable ART synchronization. If false, all ART serialization is disabled. 00221 // Can be usefull to disable serialization in some part of code. 00222 // Default is true. Return previous value. 00223 static bool setSynchronizationEnabled(bool value) 00224 { 00225 bool old = s_synchronizationEnabled; 00226 s_synchronizationEnabled = value; 00227 return old; 00228 } 00229 00230 static void resetWriteCounter(); 00231 00232 // Increments the current write counter at the start of a write operation 00233 static void incrementCurrentWriteCounter(); 00234 00235 // Decrements the current write counter after a write operation, 00236 // in some rare cases 00237 static void decrementCurrentWriteCounter(); 00238 00239 // Initiates notification from an instance. The default method 00240 // does nothing, because some classes (path, sensor) never 00241 // initiate notification. This is used by touch(). 00242 virtual void startNotify(); 00243 00244 // Propagates modification notification through an instance. The 00245 // default method here does not create and add a new record. It 00246 // merely propagates the current record list to all auditors. This 00247 // method may be used by subclasses to do the propagation after 00248 // modifying the list appropriately. 00249 virtual void notify(SoNotList *list); 00250 00251 // Adds/removes an auditor to/from list 00252 void addAuditor(void *auditor, SoNotRec::Type type); 00253 void removeAuditor(void *auditor, SoNotRec::Type type); 00254 00255 // Returns auditor list-- used by SoField and SoEngineOutput to 00256 // trace forward connections 00257 const SoAuditorList &getAuditors() const { return auditors; } 00258 00259 // Internal methods used to maintain the global name dictionary 00260 static void addName(SoBase *, const char *); 00261 static void removeName(SoBase *, const char *); 00262 00263 // Helper routines used to get stuff out of nameDict 00264 static SoBase *getNamedBase(const SbName &, const SoType&); 00265 static int getNamedBases(const SbName &, SoBaseList &, const SoType&); 00266 00267 // Set the net name of an instance. 00268 virtual void setNetName( const SbName &netName); 00269 00270 // Get the net name of an instance. 00271 virtual SbName getNetName() const; 00272 00273 // Compute automatically the net name of the instance. 00274 virtual void generateNetName(); 00275 00276 // Sets this a ScaleViz synchronized object. 00277 inline void setSynchronized( const bool b ); 00278 00279 // Gets the ScaleViz synchronized state of this object. 00280 inline bool isSynchronized() const; 00281 00290 SbBool writeHeader(SoOutput* , SbBool , SbBool ) const; 00291 void writeFooter(SoOutput* ) const; 00292 00293 virtual bool isGroup() { return false; } 00294 00295 // Reads one instance of some subclass of SoBase. Returns pointer 00296 // to read-in instance in base, or NULL on EOF. Returns FALSE on 00297 // error. The last parameter is a subclass type to match. If 00298 // the returned base is not of this type, it is an error. A type 00299 // of SoBase::getClassTypeId() will match any base. 00300 static SbBool read(SoInput *in, SoBase *&base, const SoType &expectedType, SbBool createAndRead = TRUE); 00301 00302 // Adds a reference to the instance when writing. isFromField 00303 // indicates whether the reference is from a field-to-field 00304 // connection. 00305 virtual void addWriteReference(SoOutput *out, SbBool isFromField = FALSE); 00306 00307 // Returns TRUE if the instance should be written, based on the 00308 // write-reference info already accumulated 00309 SbBool shouldWrite(); 00310 00311 // This defaults to "+" and is used when naming nodes that are DEF's and USE'd. 00312 // The ivdowngrade converter needs to set it to other than "+" since that was 00313 // an illegal character for Inventor V1.0 names. 00314 static void setInstancePrefix(const SbString &c); 00315 00316 // These are all packed into one word to save space 00317 struct WriteStuff { 00318 // This contains the value of the counter the last time the 00319 // instance was written. 00320 unsigned int writeCounter : 26; 00321 00322 // This is TRUE if the object is named. 00323 unsigned int hasName : 1; 00324 unsigned int hasNetName : 1; 00325 00326 // This is TRUE if more than one reference is made to the 00327 // instance for writing, meaning that we need to DEF it 00328 unsigned int multWriteRef : 1; 00329 00330 // This is TRUE if the instance was referenced via a 00331 // field-to-field connection, which is not a "real" reference 00332 unsigned int writeRefFromField : 1; 00333 00334 // This is TRUE if the instance was already synchronized 00335 // through ScaleViz 00336 unsigned int isSynchronized : 1; 00337 00338 // This is TRUE if the instance can be synchronized 00339 // through ScaleViz 00340 unsigned int isSynchronizable : 1; 00341 00342 // Default Constructor 00343 WriteStuff(); 00344 }; 00345 00346 WriteStuff writeStuff; 00347 00348 private: 00349 00350 static SoType classTypeId; 00351 00352 static SbString instancePrefix; 00353 00354 struct MTstruct 00355 { 00356 // This is incremented once per write operation. It is used to 00357 // determine which instances to write. 00358 uint32_t currentWriteCounter; 00359 }; 00360 00361 // List of auditors: objects to pass notification to 00362 SoAuditorList auditors; 00363 00364 // If false, disable all ART serialization. True by default. 00365 static bool s_synchronizationEnabled; 00366 00367 // These are used internally by writeHeader() 00368 void writeDef(SoOutput *, int) const; 00369 void writeRef(SoOutput *, int) const; 00370 void writeAnnotation(SoOutput *) const; 00371 void writeAnnotation1(SoOutput *) const; 00372 00373 static SbBool readReference(SoInput *in, SoBase *&base); 00374 static SbBool readBase(SoInput *in, SbName &className, SoBase *&base, SbBool createAndRead = TRUE); 00375 static SbBool readBaseInstance( SoInput *in, 00376 const SbName &className, const SbName &refName, 00377 const SbName &netName, SoBase *&base, SbBool createAndRead = TRUE); 00378 static SoBase* createInstance(SoInput *in, SbName className, unsigned short ioFlags); 00379 00380 static void flushInput(SoInput *in); 00381 00382 // This dictionary stores SbPLists keyed by name (the SbPLists 00383 // contain SoBases-- a BaseList isn't used because we don't want 00384 // the items on the list to be reference counted, otherwise they 00385 // will never get deleted). 00386 static SbDict *nameObjDict; 00387 00388 // And this dictionary maps the other way, from an SoBase * to a 00389 // name. 00390 static SbDict *objNameDict; 00391 00392 static SbThreadMutex s_classMutex; 00393 00394 friend class SoVRMLDB; 00395 }; 00396 00397 #ifdef _WIN32 00398 #pragma warning(pop) 00399 #endif 00400 00405 { 00406 public: 00407 SoBaseInitializer(SoBase*); 00408 ~SoBaseInitializer(); 00409 static inline bool isActive() 00410 { 00411 s_activeMutex.lock(); 00412 bool ret = m_active; 00413 s_activeMutex.unlock(); 00414 return ret; 00415 } 00416 private: 00417 SoBase* m_base; 00418 bool m_sync; 00419 bool m_prevActive; 00420 static bool m_active; 00421 static SbThreadSpinlock s_activeMutex; 00422 }; 00423 00424 00425 void 00426 SoBase::setSynchronizable( const bool b ) 00427 { 00428 writeStuff.isSynchronizable = b; 00429 } 00430 00431 bool 00432 SoBase::isSynchronizable() const 00433 { 00434 return writeStuff.isSynchronizable && s_synchronizationEnabled; 00435 } 00436 00437 void 00438 SoBase::setSynchronized( const bool b ) 00439 { 00440 writeStuff.isSynchronized = b; 00441 } 00442 00443 bool 00444 SoBase::isSynchronized() const 00445 { 00446 return writeStuff.isSynchronized; 00447 } 00448 00449 #endif /* _SO_BASE_ */ 00450 00451