root/OpenSceneGraph/trunk/include/osgDB/Registry @ 10171

Revision 10171, 32.1 kB (checked in by robert, 5 years ago)

Refactored the Registry::ReadFileCallback?, WriteFileCallback? and ReaderWriter::Options to they are now defined in their own header and in the osgDB namespace.

Introduced a new FindFileCallback? to Registry to compliement the existing ReadFileCallback? and WriteFileCallback?.

Added support for assign Find, Read and WriteFileCallbacks? to osdDB::Options to enable plugins/applications to override the callbacks just for that
read/write call and any nested file operations

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSGDB_REGISTRY
15#define OSGDB_REGISTRY 1
16
17#include <OpenThreads/ReentrantMutex>
18
19#include <osg/ref_ptr>
20#include <osg/ArgumentParser>
21#include <osg/KdTree>
22
23#include <osgDB/DynamicLibrary>
24#include <osgDB/ReaderWriter>
25#include <osgDB/Options>
26#include <osgDB/DotOsgWrapper>
27#include <osgDB/DatabasePager>
28#include <osgDB/FileCache>
29
30#include <vector>
31#include <map>
32#include <string>
33
34extern "C"
35{
36    typedef void (* CPluginFunction) (void);
37}
38
39namespace osgDB {
40
41/** basic structure for custom runtime inheritance checking */
42struct basic_type_wrapper {
43    virtual ~basic_type_wrapper() {}
44    virtual bool matches(const osg::Object *proto) const = 0;
45};
46
47/** a class template that checks inheritance between a given
48    Object's class and a class defined at compile time through
49        the template parameter T.
50        This is used in conjunction with readObjectOfType() to
51        specify an abstract class as reference type.
52**/
53template<class T>
54struct type_wrapper: basic_type_wrapper {
55    bool matches(const osg::Object *proto) const
56    {
57        return dynamic_cast<const T*>(proto) != 0;
58    }
59};
60
61
62/**
63    Registry is a singleton factory which stores
64    the reader/writers which are linked in
65    at runtime for reading non-native file formats.
66
67    The RegisterDotOsgWrapperProxy can be used to automatically register
68    DotOsgWrappers, at runtime with the Registry. A DotOsgWrapper encapsulates
69    the functions that can read and write to the .osg for each osg::Object.
70
71    The RegisterReaderWriterProxy can be used to automatically
72    register at runtime a reader/writer with the Registry.
73*/
74class OSGDB_EXPORT Registry : public osg::Referenced
75{
76    public:
77
78
79
80       
81        static Registry* instance(bool erase = false);
82
83        /** read the command line arguments.*/
84        void readCommandLine(osg::ArgumentParser& commandLine);
85
86        /** register an .fileextension alias to mapExt toExt, the later
87          * should the the extension name of the readerwriter plugin library.
88          * For example to map .tif files to the tiff loader, use
89          * addExtAlias("tif","tiff") which will enable .tif to be read
90          * by the libdb_tiff readerwriter plugin.*/
91        void addFileExtensionAlias(const std::string mapExt, const std::string toExt);
92
93        /** Reads a file that configures extension mappings. File is ASCII text
94          * and each line contains the parameters to the addFileExtensionAlias
95          * method. Lines can be commented out with an initial '#' character.*/
96        bool readPluginAliasConfigurationFile( const std::string& file );
97
98        /** Registers a mapping of a mime-type to an extension. A process fetching data
99          * over HTTP can use this facility to determine the proper ReaderWriter to use
100          * when there is no filename extension to rely upon.
101          */
102        void addMimeTypeExtensionMapping(const std::string fromMimeType, const std::string toExt);
103
104        void addDotOsgWrapper(DotOsgWrapper* wrapper);
105        void removeDotOsgWrapper(DotOsgWrapper* wrapper);
106
107        void addReaderWriter(ReaderWriter* rw);
108        void removeReaderWriter(ReaderWriter* rw);
109
110        /** create the platform specific library name associated with file.*/
111        std::string createLibraryNameForFile(const std::string& fileName);
112
113        /** create the platform specific library name associated with file extension.*/
114        std::string createLibraryNameForExtension(const std::string& ext);
115
116        /** create the platform specific library name associated with nodekit library name.*/
117        std::string createLibraryNameForNodeKit(const std::string& name);
118
119
120        enum LoadStatus {
121            NOT_LOADED = 0,
122            PREVIOUSLY_LOADED,
123            LOADED
124        };
125
126        /** find the library in the OSG_LIBRARY_PATH and load it.*/
127        LoadStatus loadLibrary(const std::string& fileName);
128       
129        /** close the attached library with specified name.*/
130        bool closeLibrary(const std::string& fileName);
131       
132        /** close all libraries.*/
133        void closeAllLibraries();
134
135        typedef std::vector< osg::ref_ptr<ReaderWriter> > ReaderWriterList;
136
137        /** get a reader writer which handles specified extension.*/
138        ReaderWriter* getReaderWriterForExtension(const std::string& ext);
139
140        /** gets a reader/writer that handles the extension mapped to by one of
141          * the registered mime-types. */
142        ReaderWriter* getReaderWriterForMimeType(const std::string& mimeType);
143       
144        /** get list of all registered ReaderWriters.*/
145        ReaderWriterList& getReaderWriterList() { return _rwList; }
146
147        /** get const list of all registered ReaderWriters.*/
148        const ReaderWriterList& getReaderWriterList() const { return _rwList; }
149 
150        osg::Object*         readObjectOfType(const osg::Object& compObj,Input& fr);       
151        osg::Object*         readObjectOfType(const basic_type_wrapper &btw, Input& fr);
152
153        osg::Object*         readObject(Input& fr);
154        osg::Image*          readImage(Input& fr);
155        osg::Drawable*       readDrawable(Input& fr);
156        osg::Uniform*        readUniform(Input& fr);
157        osg::StateAttribute* readStateAttribute(Input& fr);
158        osg::Node*           readNode(Input& fr);
159        osg::Shader*         readShader(Input& fr);
160       
161        bool                 writeObject(const osg::Object& obj,Output& fw);
162
163
164        typedef class osgDB::FindFileCallback FindFileCallback;
165        typedef class osgDB::ReadFileCallback ReadFileCallback;
166        typedef class osgDB::WriteFileCallback WriteFileCallback;
167
168        /** Set the Registry callback to use in place of the default findFile calls.*/
169        void setFindFileCallback( FindFileCallback* cb) { _findFileCallback = cb; }
170
171        /** Get the findFile callback.*/
172        FindFileCallback* getFindFileCallback() { return _findFileCallback.get(); }
173
174        /** Get the const findFile callback.*/
175        const FindFileCallback* getFindFileCallback() const { return _findFileCallback.get(); }
176
177
178        std::string findDataFile(const std::string& fileName, const Options* options, CaseSensitivity caseSensitivity)
179        {
180            if (options && options->getFindFileCallback()) return options->getFindFileCallback()->findDataFile(fileName, options, caseSensitivity);
181            else if (_findFileCallback.valid()) return _findFileCallback->findDataFile(fileName, options, caseSensitivity);
182            else return findDataFileImplementation(fileName, options, caseSensitivity);
183        }
184        std::string findDataFileImplementation(const std::string& fileName, const Options* options, CaseSensitivity caseSensitivity);
185
186        std::string findLibraryFile(const std::string& fileName, const Options* options, CaseSensitivity caseSensitivity)
187        {
188            if (options && options->getFindFileCallback()) return options->getFindFileCallback()->findLibraryFile(fileName, options, caseSensitivity);
189            else if (_findFileCallback.valid()) return _findFileCallback->findLibraryFile(fileName, options, caseSensitivity);
190            else return findLibraryFileImplementation(fileName, options, caseSensitivity);
191        }
192        std::string findLibraryFileImplementation(const std::string& fileName, const Options* options, CaseSensitivity caseSensitivity);
193
194
195
196        /** Set the Registry callback to use in place of the default readFile calls.*/
197        void setReadFileCallback( ReadFileCallback* cb) { _readFileCallback = cb; }
198
199        /** Get the readFile callback.*/
200        ReadFileCallback* getReadFileCallback() { return _readFileCallback.get(); }
201       
202        /** Get the const readFile callback.*/
203        const ReadFileCallback* getReadFileCallback() const { return _readFileCallback.get(); }
204
205
206        ReaderWriter::ReadResult openArchive(const std::string& fileName,ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, const Options* options)
207        {
208            if (options && options->getReadFileCallback()) return options->getReadFileCallback()->openArchive(fileName, status, indexBlockSizeHint, options);
209            else if (_readFileCallback.valid()) return _readFileCallback->openArchive(fileName, status, indexBlockSizeHint, options);
210            else return openArchiveImplementation(fileName, status, indexBlockSizeHint, options);
211        }
212        ReaderWriter::ReadResult openArchiveImplementation(const std::string& fileName, ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, const Options* options);
213
214        ReaderWriter::ReadResult readObject(const std::string& fileName,const Options* options, bool buildKdTreeIfRequired=true)
215        {
216            ReaderWriter::ReadResult result;
217            if (options && options->getReadFileCallback()) result = options->getReadFileCallback()->readObject(fileName,options);
218            else if (_readFileCallback.valid()) result = _readFileCallback->readObject(fileName,options);
219            else result = readObjectImplementation(fileName,options);
220
221            if (buildKdTreeIfRequired) _buildKdTreeIfRequired(result, options);
222
223            return result;
224        }
225        ReaderWriter::ReadResult readObjectImplementation(const std::string& fileName,const Options* options);
226
227        ReaderWriter::ReadResult readImage(const std::string& fileName,const Options* options)
228        {
229            if (options && options->getReadFileCallback()) return options->getReadFileCallback()->readImage(fileName,options);
230            else if (_readFileCallback.valid()) return _readFileCallback->readImage(fileName,options);
231            else return readImageImplementation(fileName,options);
232        }
233        ReaderWriter::ReadResult readImageImplementation(const std::string& fileName,const Options* options);
234
235        ReaderWriter::ReadResult readHeightField(const std::string& fileName,const Options* options)
236        {
237            if (options && options->getReadFileCallback()) return options->getReadFileCallback()->readHeightField(fileName,options);
238            else if (_readFileCallback.valid()) return _readFileCallback->readHeightField(fileName,options);
239            else return readHeightFieldImplementation(fileName,options);
240        }
241        ReaderWriter::ReadResult readHeightFieldImplementation(const std::string& fileName,const Options* options);
242
243        ReaderWriter::ReadResult readNode(const std::string& fileName,const Options* options, bool buildKdTreeIfRequired=true)
244        {
245            ReaderWriter::ReadResult result;
246            if (options && options->getReadFileCallback()) result = options->getReadFileCallback()->readNode(fileName,options);
247            else if (_readFileCallback.valid()) result = _readFileCallback->readNode(fileName,options);
248            else result = readNodeImplementation(fileName,options);
249
250            if (buildKdTreeIfRequired) _buildKdTreeIfRequired(result, options);
251
252            return result;
253        }
254        ReaderWriter::ReadResult readNodeImplementation(const std::string& fileName,const Options* options);
255
256        ReaderWriter::ReadResult readShader(const std::string& fileName,const Options* options)
257        {
258            if (options && options->getReadFileCallback()) return options->getReadFileCallback()->readShader(fileName,options);
259            if (_readFileCallback.valid()) return _readFileCallback->readShader(fileName,options);
260            else return readShaderImplementation(fileName,options);
261        }
262        ReaderWriter::ReadResult readShaderImplementation(const std::string& fileName,const Options* options);
263
264
265        /** Set the Registry callback to use in place of the default writeFile calls.*/
266        void setWriteFileCallback( WriteFileCallback* cb) { _writeFileCallback = cb; }
267
268        /** Get the writeFile callback.*/
269        WriteFileCallback* getWriteFileCallback() { return _writeFileCallback.get(); }
270       
271        /** Get the const writeFile callback.*/
272        const WriteFileCallback* getWriteFileCallback() const { return _writeFileCallback.get(); }
273
274
275        ReaderWriter::WriteResult writeObject(const osg::Object& obj, const std::string& fileName,const Options* options)
276        {
277            if (options && options->getWriteFileCallback()) return options->getWriteFileCallback()->writeObject(obj,fileName,options);
278            else if (_writeFileCallback.valid()) return _writeFileCallback->writeObject(obj,fileName,options);
279            else return writeObjectImplementation(obj,fileName,options);
280        }
281        ReaderWriter::WriteResult writeObjectImplementation(const osg::Object& obj, const std::string& fileName,const Options* options);
282
283        ReaderWriter::WriteResult writeImage(const osg::Image& obj, const std::string& fileName,const Options* options)
284        {
285            if (options && options->getWriteFileCallback()) return options->getWriteFileCallback()->writeImage(obj,fileName,options);
286            else if (_writeFileCallback.valid()) return _writeFileCallback->writeImage(obj,fileName,options);
287            else return writeImageImplementation(obj,fileName,options);
288        }
289        ReaderWriter::WriteResult writeImageImplementation(const osg::Image& obj, const std::string& fileName,const Options* options);
290
291        ReaderWriter::WriteResult writeHeightField(const osg::HeightField& obj, const std::string& fileName,const Options* options)
292        {
293            if (options && options->getWriteFileCallback()) return options->getWriteFileCallback()->writeHeightField(obj,fileName,options);
294            else if (_writeFileCallback.valid()) return _writeFileCallback->writeHeightField(obj,fileName,options);
295            else return writeHeightFieldImplementation(obj,fileName,options);
296        }
297        ReaderWriter::WriteResult writeHeightFieldImplementation(const osg::HeightField& obj, const std::string& fileName,const Options* options);
298
299        ReaderWriter::WriteResult writeNode(const osg::Node& node, const std::string& fileName,const Options* options)
300        {
301            if (options && options->getWriteFileCallback()) return options->getWriteFileCallback()->writeNode(node,fileName,options);
302            else if (_writeFileCallback.valid()) return _writeFileCallback->writeNode(node,fileName,options);
303            else return writeNodeImplementation(node,fileName,options);
304        }
305        ReaderWriter::WriteResult writeNodeImplementation(const osg::Node& node, const std::string& fileName,const Options* options);
306       
307        ReaderWriter::WriteResult writeShader(const osg::Shader& obj, const std::string& fileName,const Options* options)
308        {
309            if (options && options->getWriteFileCallback()) return options->getWriteFileCallback()->writeShader(obj,fileName,options);
310            else if (_writeFileCallback.valid()) return _writeFileCallback->writeShader(obj,fileName,options);
311            else return writeShaderImplementation(obj,fileName,options);
312        }
313        ReaderWriter::WriteResult writeShaderImplementation(const osg::Shader& obj, const std::string& fileName,const Options* options);
314       
315
316        inline void _buildKdTreeIfRequired(ReaderWriter::ReadResult& result, const Options* options)
317        {
318            bool doKdTreeBuilder = (options && options->getBuildKdTreesHint()!=Options::NO_PREFERENCE) ?
319                options->getBuildKdTreesHint() == Options::BUILD_KDTREES :
320                _buildKdTreesHint == Options::BUILD_KDTREES;
321
322            if (doKdTreeBuilder && _kdTreeBuilder.valid() && result.validNode())
323            {
324                osg::ref_ptr<osg::KdTreeBuilder> builder = _kdTreeBuilder->clone();
325                result.getNode()->accept(*builder);
326            }
327        }
328
329
330        /** Set whether the KdTrees should be built for geometry in the loader model. */
331        void setBuildKdTreesHint(Options::BuildKdTreesHint hint) { _buildKdTreesHint = hint; }
332
333        /** Get whether the KdTrees should be built for geometry in the loader model. */
334        Options::BuildKdTreesHint getBuildKdTreesHint() const { return _buildKdTreesHint; }
335
336        /** Set the KdTreeBuilder visitor that is used to build KdTree on loaded models.*/
337        void setKdTreeBuilder(osg::KdTreeBuilder* builder) { _kdTreeBuilder = builder; }
338
339        /** Get the KdTreeBuilder visitor that is used to build KdTree on loaded models.*/
340        osg::KdTreeBuilder* getKdTreeBuilder() { return _kdTreeBuilder.get(); }
341
342        /** Set the FileCache that is used to manage local storage of files downloaded from the internet.*/
343        void setFileCache(FileCache* fileCache) { _fileCache = fileCache; }
344
345        /** Get the FileCache that is used to manage local storage of files downloaded from the internet.*/
346        FileCache* getFileCache() { return _fileCache.get(); }
347
348        /** Get the const FileCache that is used to manage local storage of files downloaded from the internet.*/
349        const FileCache* getFileCache() const { return _fileCache.get(); }
350
351
352        /** Set the password map to be used by plugins when access files from secure locations.*/
353        void setAuthenticationMap(AuthenticationMap* authenticationMap) { _authenticationMap = authenticationMap; }
354
355        /** Get the password map to be used by plugins when access files from secure locations.*/
356        AuthenticationMap* getAuthenticationMap() { return _authenticationMap.get(); }
357
358        /** Get the password map to be used by plugins when access files from secure locations.*/
359        const AuthenticationMap* getAuthenticationMap() const { return _authenticationMap.get(); }
360
361
362        void setCreateNodeFromImage(bool flag) { _createNodeFromImage = flag; }
363        bool getCreateNodeFromImage() const { return _createNodeFromImage; }
364       
365
366        void setOptions(Options* opt) { _options = opt; }
367        Options* getOptions() { return _options.get(); }
368        const Options*  getOptions() const { return _options.get(); }
369
370
371        /** initialize both the Data and Library FilePaths, by default called by the
372          * constructor, so it should only be required if you want to force
373          * the re-reading of environmental variables.*/
374        void initFilePathLists() { initDataFilePathList(); initLibraryFilePathList(); }
375       
376        /** initialize the Data FilePath by reading the OSG_FILE_PATH environmental variable.*/
377        void initDataFilePathList();
378
379        /** Set the data file path using a list of paths stored in a FilePath, which is used when search for data files.*/
380        void setDataFilePathList(const FilePathList& filepath) { _dataFilePath = filepath; }
381
382        /** Set the data file path using a single string delimited either with ';' (Windows) or ':' (All other platforms), which is used when search for data files.*/
383        void setDataFilePathList(const std::string& paths);
384
385        /** get the data file path which is used when search for data files.*/
386        FilePathList& getDataFilePathList() { return _dataFilePath; }
387
388        /** get the const data file path which is used when search for data files.*/
389        const FilePathList& getDataFilePathList() const { return _dataFilePath; }
390
391        /** initialize the Library FilePath by reading the OSG_LIBRARY_PATH
392          * and the appropriate system environmental variables*/
393        void initLibraryFilePathList();
394
395        /** Set the library file path using a list of paths stored in a FilePath, which is used when search for data files.*/
396        void setLibraryFilePathList(const FilePathList& filepath) { _libraryFilePath = filepath; }
397
398        /** Set the library file path using a single string delimited either with ';' (Windows) or ':' (All other platforms), which is used when search for data files.*/
399        void setLibraryFilePathList(const std::string& paths);
400
401        /** get the library file path which is used when search for library (dso/dll's) files.*/
402        FilePathList& getLibraryFilePathList() { return _libraryFilePath; }
403       
404        /** get the const library file path which is used when search for library (dso/dll's) files.*/
405        const FilePathList& getLibraryFilePathList() const { return _libraryFilePath; }
406
407        /** For each object in the cache which has an reference count greater than 1
408          * (and therefore referenced by elsewhere in the application) set the time stamp
409          * for that object in the cache to specified time.
410          * This would typically be called once per frame by applications which are doing database paging,
411          * and need to prune objects that are no longer required.
412          * Time value is time in seconds.*/
413        void updateTimeStampOfObjectsInCacheWithExternalReferences(double currentTime);
414
415        /** Removed object in the cache which have a time stamp at or before the specified expiry time.
416          * This would typically be called once per frame by applications which are doing database paging,
417          * and need to prune objects that are no longer required, and called after the a called
418          * after the call to updateTimeStampOfObjectsInCacheWithExternalReferences(currentTime).
419          * Note, the currentTime is not the expiryTime, one would typically set the expiry time
420          * to a fixed amount of time before currentTime, such as expiryTime = currentTime-10.0.
421          * Time value is time in seconds.*/
422        void removeExpiredObjectsInCache(double expiryTime);
423       
424        /** Remove all objects in the cache regardless of having external references or expiry times.*/
425        void clearObjectCache();
426
427        /** Add a filename,object,timestamp triple to the Registry::ObjectCache.*/
428        void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0);
429
430        /** Get an object from the object cache*/
431        osg::Object* getFromObjectCache(const std::string& fileName);
432       
433        /** Add archive to archive cache so that future calls reference this archive.*/
434        void addToArchiveCache(const std::string& fileName, osgDB::Archive* archive);
435
436        /** Remove archive from cache.*/
437        void removeFromArchiveCache(const std::string& fileName);
438       
439        /** Get an archive from the archive cache*/
440        osgDB::Archive* getFromArchiveCache(const std::string& fileName);
441       
442        /** Remove all archives from the archive cache.*/
443        void clearArchiveCache();
444       
445         /** If State is non-zero, this function releases OpenGL objects for
446           * the specified graphics context. Otherwise, releases OpenGL objexts
447           * for all graphics contexts. */
448        void releaseGLObjects(osg::State* state=0);
449
450        /** get the attached library with specified name.*/
451        DynamicLibrary*              getLibrary(const std::string& fileName);
452
453        /** Set the SharedStateManager.*/
454        void setSharedStateManager(SharedStateManager* SharedStateManager) { _sharedStateManager = SharedStateManager; }
455
456        /** Get the SharedStateManager, creating one if one is not already created.*/
457        SharedStateManager* getOrCreateSharedStateManager();
458       
459        /** Get the SharedStateManager. Return 0 if no SharedStateManager has been assigned.*/
460        SharedStateManager* getSharedStateManager() { return _sharedStateManager.get(); }
461
462        /** Add an Archive extension.*/
463        void addArchiveExtension(const std::string ext);
464       
465        /** registers a protocol */
466        void registerProtocol(const std::string& protocol);
467       
468        /** returns true, if named protocol is registered */
469        bool isProtocolRegistered(const std::string& protocol);
470       
471    protected:
472
473        virtual ~Registry();
474
475        typedef std::map< std::string, osg::ref_ptr<DotOsgWrapper> >    DotOsgWrapperMap;
476        typedef std::vector< osg::ref_ptr<DynamicLibrary> >             DynamicLibraryList;
477        typedef std::map< std::string, std::string>                     ExtensionAliasMap;
478        typedef std::map< std::string, std::string>                     MimeTypeExtensionMap;
479        typedef std::vector< std::string>                               ArchiveExtensionList;
480       
481        typedef std::pair<osg::ref_ptr<osg::Object>, double >           ObjectTimeStampPair;
482        typedef std::map<std::string, ObjectTimeStampPair >             ObjectCache;
483        typedef std::map<std::string, osg::ref_ptr<osgDB::Archive> >    ArchiveCache;
484       
485        typedef std::set<std::string>                                   RegisteredProtocolsSet;
486
487        /** constructor is private, as its a singleton, preventing
488            construction other than via the instance() method and
489            therefore ensuring only one copy is ever constructed*/
490        Registry();
491       
492        /** get the attached library with specified name.*/
493        DynamicLibraryList::iterator getLibraryItr(const std::string& fileName);
494
495        Options::BuildKdTreesHint     _buildKdTreesHint;
496        osg::ref_ptr<osg::KdTreeBuilder>            _kdTreeBuilder;
497       
498        osg::ref_ptr<FileCache>                     _fileCache;
499       
500        osg::ref_ptr<AuthenticationMap>             _authenticationMap;
501       
502        bool                                        _createNodeFromImage;
503       
504        RegisteredProtocolsSet                      _registeredProtocols;
505
506        osg::Object*       readObject(DotOsgWrapperMap& dowMap,Input& fr);
507
508        void eraseWrapper(DotOsgWrapperMap& wrappermap,DotOsgWrapper* wrapper);
509
510    public:
511        /** Functor used in internal implementations.*/
512        struct ReadFunctor
513        {
514            ReadFunctor(const std::string& filename, const Options* options):
515                _filename(filename),
516                _options(options) {}
517
518            virtual ~ReadFunctor() {}
519            virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw) const = 0;
520            virtual bool isValid(ReaderWriter::ReadResult& readResult) const = 0;
521            virtual bool isValid(osg::Object* object) const = 0;
522
523            std::string _filename;
524            const Options* _options;
525        };
526
527   protected:
528   
529        void destruct();
530   
531        // forward declare helper classes
532        struct ReadObjectFunctor;
533        struct ReadImageFunctor;
534        struct ReadHeightFieldFunctor;
535        struct ReadNodeFunctor;
536        struct ReadArchiveFunctor;
537        struct ReadShaderFunctor;
538       
539        // make helper classes friends to get round VS6.0 "issues"
540        friend struct ReadFunctor;
541        friend struct ReadObjectFunctor;
542        friend struct ReadImageFunctor;
543        friend struct ReadHeightFieldFunctor;
544        friend struct ReadNodeFunctor;
545        friend struct ReadArchiveFunctor;
546        friend struct ReadShaderFunctor;
547
548        ReaderWriter::ReadResult read(const ReadFunctor& readFunctor);
549        ReaderWriter::ReadResult readImplementation(const ReadFunctor& readFunctor,Options::CacheHintOptions cacheHint);
550
551
552        // forward declare helper class
553        class AvailableReaderWriterIterator;
554        friend class AvailableReaderWriterIterator;
555
556
557        osg::ref_ptr<FindFileCallback>      _findFileCallback;
558        osg::ref_ptr<ReadFileCallback>      _readFileCallback;
559        osg::ref_ptr<WriteFileCallback>     _writeFileCallback;
560
561        DotOsgWrapperMap   _objectWrapperMap;
562        DotOsgWrapperMap   _imageWrapperMap;
563        DotOsgWrapperMap   _drawableWrapperMap;
564        DotOsgWrapperMap   _stateAttrWrapperMap;
565        DotOsgWrapperMap   _uniformWrapperMap;
566        DotOsgWrapperMap   _nodeWrapperMap;
567        DotOsgWrapperMap   _shaderWrapperMap;
568       
569        DotOsgWrapperMap   _classNameWrapperMap;
570
571        OpenThreads::ReentrantMutex _pluginMutex;
572        ReaderWriterList            _rwList;
573        DynamicLibraryList          _dlList;
574
575        bool _openingLibrary;
576   
577        // map to alias to extensions to plugins.
578        ExtensionAliasMap  _extAliasMap;
579
580        // maps mime-types to extensions.
581        MimeTypeExtensionMap _mimeTypeExtMap;
582
583        // Utility: Removes whitespace from both ends of a string.
584        static std::string trim( const std::string& str );
585       
586        // options to pass to reader writers.
587        osg::ref_ptr<Options>     _options;
588       
589        FilePathList                            _dataFilePath;
590        FilePathList                            _libraryFilePath;
591
592        ObjectCache                             _objectCache;
593        OpenThreads::Mutex                      _objectCacheMutex;
594       
595        ArchiveCache                            _archiveCache;
596        OpenThreads::Mutex                      _archiveCacheMutex;
597
598        ArchiveExtensionList                    _archiveExtList;
599       
600        osg::ref_ptr<SharedStateManager>        _sharedStateManager;
601
602};
603
604/** read the command line arguments.*/
605inline void readCommandLine(osg::ArgumentParser& parser)
606{
607    Registry::instance()->readCommandLine(parser);
608}
609
610/**  Proxy class for automatic registration of DotOsgWrappers with the Registry.*/
611class RegisterDotOsgWrapperProxy
612{
613    public:
614   
615        RegisterDotOsgWrapperProxy(osg::Object* proto,
616                                   const std::string& name,
617                                   const std::string& associates,
618                                   DotOsgWrapper::ReadFunc readFunc,
619                                   DotOsgWrapper::WriteFunc writeFunc,
620                                   DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE)
621        {
622            if (Registry::instance())
623            {
624                _wrapper = new DotOsgWrapper(proto,name,associates,readFunc,writeFunc,readWriteMode);
625                Registry::instance()->addDotOsgWrapper(_wrapper.get());
626            }
627        }
628       
629        ~RegisterDotOsgWrapperProxy()
630        {
631            if (Registry::instance())
632            {
633                Registry::instance()->removeDotOsgWrapper(_wrapper.get());
634            }
635        }
636       
637    protected:
638        osg::ref_ptr<DotOsgWrapper> _wrapper;
639};
640
641template<class T>
642class TemplateRegisterDotOsgWrapperProxy : public RegisterDotOsgWrapperProxy, public T
643{
644    public:
645   
646        TemplateRegisterDotOsgWrapperProxy(osg::Object* proto,
647                                   const std::string& name,
648                                   const std::string& associates,
649                                   DotOsgWrapper::ReadFunc readFunc,
650                                   DotOsgWrapper::WriteFunc writeFunc,
651                                   DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE):
652            RegisterDotOsgWrapperProxy(proto, name, associates, readFunc, writeFunc, readWriteMode) {}
653       
654};
655
656/** Proxy class for automatic registration of reader/writers with the Registry.*/
657template<class T>
658class RegisterReaderWriterProxy
659{
660    public:
661        RegisterReaderWriterProxy()
662        {
663            if (Registry::instance())
664            {
665                _rw = new T;
666                Registry::instance()->addReaderWriter(_rw.get());
667            }
668        }
669
670        ~RegisterReaderWriterProxy()
671        {
672            if (Registry::instance())
673            {
674                Registry::instance()->removeReaderWriter(_rw.get());
675            }
676        }
677       
678        T* get() { return _rw.get(); }
679       
680    protected:
681        osg::ref_ptr<T> _rw;
682};
683
684
685struct PluginFunctionProxy
686{
687    PluginFunctionProxy(CPluginFunction function) { (function)(); }
688};
689
690#define USE_OSGPLUGIN(ext) \
691    extern "C" void osgdb_##ext(void); \
692    static osgDB::PluginFunctionProxy proxy_##ext(osgdb_##ext);
693
694#define REGISTER_OSGPLUGIN(ext, classname) \
695    extern "C" void osgdb_##ext(void) {} \
696    static osgDB::RegisterReaderWriterProxy<classname> g_proxy_##classname;
697
698
699#define USE_DOTOSGWRAPPER(classname) \
700    extern "C" void dotosgwrapper_##classname(void); \
701    static osgDB::PluginFunctionProxy proxy_dotosgwrapper_##classname(dotosgwrapper_##classname);
702
703#define REGISTER_DOTOSGWRAPPER(classname) \
704    extern "C" void dotosgwrapper_##classname(void) {} \
705    static osgDB::RegisterDotOsgWrapperProxy dotosgwrapper_proxy_##classname
706
707}
708
709#endif
Note: See TracBrowser for help on using the browser.