/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #ifndef OSGDB_IMAGEPAGER #define OSGDB_IMAGEPAGER 1 #include #include #include #include #include #include #include namespace osgDB { class OSGDB_EXPORT ImagePager : public osg::NodeVisitor::ImageRequestHandler { public: ImagePager(); class OSGDB_EXPORT ImageThread : public osg::Referenced, public OpenThreads::Thread { public: enum Mode { HANDLE_ALL_REQUESTS, HANDLE_NON_HTTP, HANDLE_ONLY_HTTP }; ImageThread(ImagePager* pager, Mode mode, const std::string& name); ImageThread(const ImageThread& dt, ImagePager* pager); void setDone(bool done) { _done = done; } bool getDone() const { return _done; } virtual int cancel(); virtual void run(); protected: virtual ~ImageThread(); bool _done; Mode _mode; ImagePager* _pager; std::string _name; }; ImageThread* getImageThread(unsigned int i) { return _imageThreads[i].get(); } const ImageThread* getImageThread(unsigned int i) const { return _imageThreads[i].get(); } unsigned int getNumImageThreads() const { return _imageThreads.size(); } void setPreLoadTime(double preLoadTime) { _preLoadTime=preLoadTime; } virtual double getPreLoadTime() const { return _preLoadTime; } virtual osg::Image* readImageFile(const std::string& fileName); virtual void requestImageFile(const std::string& fileName,osg::Object* attachmentPoint, int attachmentIndex, double timeToMergeBy, const osg::FrameStamp* framestamp); /** Return true if there are pending updates to the scene graph that require a call to updateSceneGraph(double). */ virtual bool requiresUpdateSceneGraph() const; /** Merge the changes to the scene graph. */ virtual void updateSceneGraph(const osg::FrameStamp &frameStamp); int cancel(); protected: virtual ~ImagePager(); // forward declare struct RequestQueue; struct SortFileRequestFunctor; friend struct SortFileRequestFunctor; struct ImageRequest : public osg::Referenced { ImageRequest(): osg::Referenced(true), _timeToMergeBy(0.0), _attachmentIndex(-1) {} double _timeToMergeBy; std::string _fileName; osg::ref_ptr _loadOptions; osg::observer_ptr _attachmentPoint; int _attachmentIndex; osg::ref_ptr _loadedImage; RequestQueue* _requestQueue; }; struct RequestQueue : public osg::Referenced { typedef std::vector< osg::ref_ptr > RequestList; void sort(); RequestList _requestList; OpenThreads::Mutex _requestMutex; }; struct ReadQueue : public RequestQueue { ReadQueue(ImagePager* pager, const std::string& name); void block() { _block->block(); } void release() { _block->release(); } void updateBlock() { _block->set((!_requestList.empty() || !_pager->_databasePagerThreadPaused)); } void clear(); void add(ImageRequest* imageRequest); void takeFirst(osg::ref_ptr& databaseRequest); osg::ref_ptr _block; ImagePager* _pager; std::string _name; }; OpenThreads::Mutex _run_mutex; bool _startThreadCalled; bool _done; bool _databasePagerThreadPaused; osg::ref_ptr _readQueue; typedef std::vector< osg::ref_ptr > ImageThreads; ImageThreads _imageThreads; osg::ref_ptr _completedQueue; double _preLoadTime; }; } #endif