Refactored DatabasePager and related classes to introduce support for

multi-threaded paging, where the Pager manages threads of reading local
and http files via seperate threads.  This makes it possible to smoothly
browse large databases where parts of the data are locally cached while
others are on a remote server.  Previously with this type of dataset 
the pager would stall all paging while http requests were being served,
even when parts of the models are still loadable virtue of being in the 
local cache.

Also as part of the refactoring the DatabaseRequest are now stored in the
ProxyNode/PagedLOD nodes to facilitate quite updating in the cull traversal,
with the new code avoiding mutex locks and searches.  Previous on big 
databases the overhead involved in make database requests could accumulate
to a point where it'd cause the cull traversal to break frame.  The overhead
now is negligable.

Finally OSG_FILE_CACHE support has been moved from the curl plugin into
the DatabasePager.  Eventually this functionality will be moved out into
osgDB for more general usage.
This commit is contained in:
Robert Osfield 2008-05-21 21:09:45 +00:00
parent 100cc12ecb
commit 7b003b24ea
21 changed files with 1477 additions and 1017 deletions

View File

@ -268,7 +268,7 @@ class OSG_EXPORT NodeVisitor : public virtual Referenced
DatabaseRequestHandler():
Referenced(true) {}
virtual void requestNodeFile(const std::string& fileName,osg::Group* group, float priority, const FrameStamp* framestamp) = 0;
virtual void requestNodeFile(const std::string& fileName,osg::Group* group, float priority, const FrameStamp* framestamp, osg::ref_ptr<osg::Referenced>& databaseRequest) = 0;
protected:
virtual ~DatabaseRequestHandler() {}

View File

@ -58,10 +58,11 @@ class OSG_EXPORT PagedLOD : public LOD
PerRangeData(const PerRangeData& prd);
PerRangeData& operator = (const PerRangeData& prd);
std::string _filename;
float _priorityOffset;
float _priorityScale;
double _timeStamp;
std::string _filename;
float _priorityOffset;
float _priorityScale;
double _timeStamp;
osg::ref_ptr<osg::Referenced> _databaseRequest;
};
typedef std::vector<PerRangeData> PerRangeDataList;
@ -85,6 +86,16 @@ class OSG_EXPORT PagedLOD : public LOD
unsigned int getNumTimeStamps() const { return _perRangeDataList.size(); }
/** Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests
* being carried on behalf of the DatabasePager.
* Note, in normal OSG usage you should not set this value yourself, as this will be managed by
* the osgDB::DatabasePager.*/
osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) { return _perRangeDataList[childNo]._databaseRequest; }
/** Return the const DatabaseRequest object.*/
const osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) const { return _perRangeDataList[childNo]._databaseRequest; }
/** Set the frame number of the last time that this PageLOD node was traversed.
* Note, this frame number is automatically set by the traverse() method for all traversals (update, cull etc.).
*/

View File

@ -46,12 +46,20 @@ class OSG_EXPORT ProxyNode : public Group
/** Get the database path used to prepend to children's filenames.*/
inline const std::string& getDatabasePath() const { return _databasePath; }
typedef std::vector<std::string> FileNameList;
void setFileName(unsigned int childNo, const std::string& filename) { expandFileNameListTo(childNo); _filenameList[childNo]=filename; }
const std::string& getFileName(unsigned int childNo) const { return _filenameList[childNo]; }
void setFileName(unsigned int childNo, const std::string& filename) { expandFileNameListTo(childNo); _filenameList[childNo].first=filename; }
const std::string& getFileName(unsigned int childNo) const { return _filenameList[childNo].first; }
unsigned int getNumFileNames() const { return _filenameList.size(); }
/** Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests
* being carried on behalf of the DatabasePager.
* Note, in normal OSG usage you should not set this value yourself, as this will be managed by
* the osgDB::DatabasePager.*/
osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) { return _filenameList[childNo].second; }
/** Return the const DatabaseRequest object.*/
const osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) const { return _filenameList[childNo].second; }
/** Modes which control how the center of object should be determined when computed which child is active.*/
enum CenterMode
{
@ -102,14 +110,17 @@ class OSG_EXPORT ProxyNode : public Group
void expandFileNameListTo(unsigned int pos);
FileNameList _filenameList;
std::string _databasePath;
typedef std::pair< std::string, osg::ref_ptr<osg::Referenced> > FileNameDatabaseRequestPair;
typedef std::vector<FileNameDatabaseRequestPair> FileNameDatabaseRequestList;
FileNameDatabaseRequestList _filenameList;
std::string _databasePath;
LoadingExternalReferenceMode _loadingExtReference;
LoadingExternalReferenceMode _loadingExtReference;
CenterMode _centerMode;
vec_type _userDefinedCenter;
value_type _radius;
CenterMode _centerMode;
vec_type _userDefinedCenter;
value_type _radius;
};

View File

@ -37,9 +37,10 @@
namespace osgDB {
/** Database paging class which manages the loading of files in a background thread,
* and synchronizing of loaded models with the main scene graph.*/
class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandler, public OpenThreads::Thread
class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandler
{
public :
@ -62,21 +63,63 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
/** Add a request to load a node file to end the the database request list.*/
virtual void requestNodeFile(const std::string& fileName,osg::Group* group,
float priority, const osg::FrameStamp* framestamp);
float priority, const osg::FrameStamp* framestamp,
osg::ref_ptr<osg::Referenced>& databaseRequest);
virtual void requestNodeFile(const std::string& fileName,osg::Group* group,
float priority, const osg::FrameStamp* framestamp,
osg::ref_ptr<osg::Referenced>& databaseRequest,
ReaderWriter::Options* loadOptions);
/** Run does the database paging.*/
virtual void run();
/** Cancel the database pager thread.*/
/** Set the priority of the database pager thread(s).*/
int setSchedulePriority(OpenThreads::Thread::ThreadPriority priority);
/** Cancel the database pager thread(s).*/
virtual int cancel();
virtual bool isRunning() const;
/** Clear all internally cached structures.*/
virtual void clear();
class DatabaseThread : public osg::Referenced, public OpenThreads::Thread
{
public:
enum Mode
{
HANDLE_ALL_REQUESTS,
HANDLE_NON_HTTP,
HANDLE_ONLY_HTTP
};
DatabaseThread(DatabasePager* pager, Mode mode, const std::string& name);
DatabaseThread(const DatabaseThread& dt, DatabasePager* pager);
void setDone(bool done) { _done = done; }
bool getDone() const { return _done; }
virtual int cancel();
virtual void run();
protected:
virtual ~DatabaseThread();
bool _done;
DatabasePager* _pager;
Mode _mode;
std::string _name;
};
DatabaseThread* getDatabaseThread(unsigned int i) { return _databaseThreads[i].get(); }
const DatabaseThread* getDatabaseThread(unsigned int i) const { return _databaseThreads[i].get(); }
unsigned int getNumDatabaseThreads() const { return _databaseThreads.size(); }
/** Set whether the database pager thread should be paused or not.*/
void setDatabasePagerThreadPause(bool pause);
@ -232,7 +275,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
virtual void compileAllGLObjects(osg::State& state);
/** Report how many items are in the _fileRequestList queue */
unsigned int getFileRequestListSize() const { return _fileRequestList.size(); }
unsigned int getFileRequestListSize() const { return _fileRequestQueue._requestList.size() + _httpRequestQueue._requestList.size(); }
/** Report how many items are in the _dataToCompileList queue */
unsigned int getDataToCompileListSize() const { return _dataToCompileList.size(); }
@ -263,12 +306,21 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
virtual ~DatabasePager();
friend class DatabaseThread;
friend struct DatabaseRequest;
struct DatabaseRequest : public osg::Referenced
{
DatabaseRequest():
osg::Referenced(true),
_frameNumberFirstRequest(0),
_timestampFirstRequest(0.0),
_priorityFirstRequest(0.f),
_frameNumberLastRequest(0),
_timestampLastRequest(0.0),
_priorityLastRequest(0.0f),
_numOfRequests(0)
{}
@ -290,10 +342,43 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
return frameNumber - _frameNumberLastRequest <= 1;
}
};
typedef std::vector< osg::ref_ptr<DatabaseRequest> > DatabaseRequestList;
typedef std::vector< osg::ref_ptr<DatabaseThread> > DatabaseThreadList;
typedef std::list< osg::ref_ptr<DatabaseRequest> > DatabaseRequestList;
typedef std::vector< osg::ref_ptr<osg::Object> > ObjectList;
struct RequestQueue : public osg::Referenced
{
RequestQueue(DatabasePager* pager, const std::string& name);
void block() { _block->block(); }
void release() { _block->release(); }
void updateBlock()
{
_block->set((!_requestList.empty() || !_childrenToDeleteList.empty()) &&
!_pager->_databasePagerThreadPaused);
}
void clear();
void add(DatabaseRequest* databaseRequest);
void takeFirst(osg::ref_ptr<DatabaseRequest>& databaseRequest);
osg::ref_ptr<osg::RefBlock> _block;
DatabasePager* _pager;
std::string _name;
OpenThreads::Mutex _requestMutex;
DatabaseRequestList _requestList;
OpenThreads::Mutex _childrenToDeleteListMutex;
ObjectList _childrenToDeleteList;
};
// forward declare inner helper classes
class FindCompileableGLObjectsVisitor;
friend class FindCompileableGLObjectsVisitor;
@ -310,15 +395,6 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
OpenThreads::Mutex _run_mutex;
bool _startThreadCalled;
osg::ref_ptr<osg::RefBlock> _databasePagerThreadBlock;
inline void updateDatabasePagerThreadBlock()
{
_databasePagerThreadBlock->set(
(!_fileRequestList.empty() || !_childrenToDeleteList.empty()) && !_databasePagerThreadPaused);
}
// Helper functions for determining if objects need to be
// compiled.
inline static bool isCompiled(const osg::Texture* texture,
@ -410,12 +486,17 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
bool _acceptNewRequests;
bool _databasePagerThreadPaused;
DatabaseThreadList _databaseThreads;
int _numFramesActive;
mutable OpenThreads::Mutex _numFramesActiveMutex;
int _frameNumber;
DatabaseRequestList _fileRequestList;
mutable OpenThreads::Mutex _fileRequestListMutex;
RequestQueue _fileRequestQueue;
RequestQueue _httpRequestQueue;
//DatabaseRequestList _fileRequestList;
//mutable OpenThreads::Mutex _fileRequestListMutex;
DatabaseRequestList _dataToCompileList;
mutable OpenThreads::Mutex _dataToCompileListMutex;
@ -428,8 +509,8 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
float _valueAnisotropy;
bool _deleteRemovedSubgraphsInDatabaseThread;
ObjectList _childrenToDeleteList;
mutable OpenThreads::Mutex _childrenToDeleteListMutex;
//ObjectList _childrenToDeleteList;
//mutable OpenThreads::Mutex _childrenToDeleteListMutex;
DatabaseRequestList _dataToMergeList;
mutable OpenThreads::Mutex _dataToMergeListMutex;
@ -451,7 +532,6 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
double _totalTimeToMergeTiles;
unsigned int _numTilesMerges;
struct CompileOperation : public osg::GraphicsOperation
{
CompileOperation(DatabasePager* databasePager);

View File

@ -90,21 +90,18 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object
Options():
osg::Object(true),
_objectCacheHint(CACHE_ARCHIVES),
_asynchronousFileReadHint(false) {}
_objectCacheHint(CACHE_ARCHIVES) {}
Options(const std::string& str):
osg::Object(true),
_str(str),
_objectCacheHint(CACHE_ARCHIVES),
_asynchronousFileReadHint(false) {}
_objectCacheHint(CACHE_ARCHIVES) {}
Options(const Options& options,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
osg::Object(options,copyop),
_str(options._str),
_databasePaths(options._databasePaths),
_objectCacheHint(options._objectCacheHint),
_asynchronousFileReadHint(options._asynchronousFileReadHint) {}
_objectCacheHint(options._objectCacheHint) {}
META_Object(osgDB,Options);
@ -131,21 +128,6 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object
CacheHintOptions getObjectCacheHint() const { return _objectCacheHint; }
/** Set Asynchrnous file read hint.
* This hint is used by plugins like the libcurl http reader plugin to inform them that
* they should make an internal file read requests to their background threads to load files,
* with the plugin returning immediately with a ReadResult::FILE_REQUESTED status. It is
* assumed that calls will continue to be made to the plugin until the background threads
* have read or failed to read the request file, at which point the return status which change
* to FILE_LOADED and the objects will be returned.
* Note, this facility is particular useful when using DatabasePager in conjunction with
* internet based databases where file load latency is relatively high.*/
void setAsynchronousFileReadHint(bool flag) { _asynchronousFileReadHint = flag; }
/** Get Asynchrnous file read hint. */
bool getAsynchronousFileReadHint() const { return _asynchronousFileReadHint; }
/** Sets a plugindata value PluginData with a string */
void setPluginData(const std::string& s, void* v) const { _pluginData[s] = v; }
@ -169,7 +151,6 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object
std::string _str;
FilePathList _databasePaths;
CacheHintOptions _objectCacheHint;
bool _asynchronousFileReadHint;
typedef std::map<std::string,void*> PluginDataMap;
mutable PluginDataMap _pluginData;

View File

@ -28,7 +28,8 @@ PagedLOD::PerRangeData::PerRangeData(const PerRangeData& prd):
_filename(prd._filename),
_priorityOffset(prd._priorityOffset),
_priorityScale(prd._priorityScale),
_timeStamp(prd._timeStamp) {}
_timeStamp(prd._timeStamp),
_databaseRequest(prd._databaseRequest) {}
PagedLOD::PerRangeData& PagedLOD::PerRangeData::operator = (const PerRangeData& prd)
{
@ -37,6 +38,7 @@ PagedLOD::PerRangeData& PagedLOD::PerRangeData::operator = (const PerRangeData&
_priorityOffset = prd._priorityOffset;
_priorityScale = prd._priorityScale;
_timeStamp = prd._timeStamp;
_databaseRequest = prd._databaseRequest;
return *this;
}
@ -188,12 +190,12 @@ void PagedLOD::traverse(NodeVisitor& nv)
if (_databasePath.empty())
{
nv.getDatabaseRequestHandler()->requestNodeFile(_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp());
nv.getDatabaseRequestHandler()->requestNodeFile(_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp(), _perRangeDataList[numChildren]._databaseRequest);
}
else
{
// prepend the databasePath to the child's filename.
nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp());
nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp(), _perRangeDataList[numChildren]._databaseRequest);
}
}

View File

@ -62,7 +62,7 @@ void ProxyNode::traverse(NodeVisitor& nv)
{
for(unsigned int i=_children.size(); i<_filenameList.size(); ++i)
{
nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_filenameList[i], this, 1.0f, nv.getFrameStamp());
nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_filenameList[i].first, this, 1.0f, nv.getFrameStamp(), _filenameList[i].second);
}
}
else

File diff suppressed because it is too large Load Diff

View File

@ -277,6 +277,8 @@ Registry::~Registry()
void Registry::destruct()
{
// osg::notify(osg::NOTICE)<<"Registry::destruct()"<<std::endl;
// switch off the pager and its associated thread before we clean up
// rest of the Registry.
_databasePager = 0;
@ -670,6 +672,8 @@ bool Registry::closeLibrary(const std::string& fileName)
void Registry::closeAllLibraries()
{
// osg::notify(osg::NOTICE)<<"Registry::closeAllLibraries()"<<std::endl;
_dlList.clear();
}

View File

@ -13,7 +13,13 @@ ENDIF(WIN32)
INCLUDE_DIRECTORIES( ${CURL_INCLUDE_DIRS} )
SET(TARGET_SRC ReaderWriterCURL.cpp )
SET(TARGET_SRC
ReaderWriterCURL.cpp
)
SET(TARGET_H
ReaderWriterCURL.h
)
SET(TARGET_LIBRARIES_VARS CURL_LIBRARY )

View File

@ -1,20 +1,20 @@
/* -*-c++-*- VirtualPlanetBuilder - Copyright (C) 1998-2007 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commericial and non commericial applications,
* as long as this copyright notice is maintained.
* 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 application is distributed in the hope that it will be useful,
* 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.
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <iostream>
#include <sstream>
@ -23,353 +23,298 @@
#include <curl/curl.h>
#include <curl/types.h>
class EasyCurl : public osg::Referenced
#include "ReaderWriterCURL.h"
using namespace osg_curl;
//
// StreamObject
//
EasyCurl::StreamObject::StreamObject(std::ostream* stream1, const std::string& cacheFileName):
_stream1(stream1),
_cacheFileName(cacheFileName)
{
public:
_foutOpened = false;
}
void EasyCurl::StreamObject::write(const char* ptr, size_t realsize)
{
if (_stream1) _stream1->write(ptr, realsize);
if (!_cacheFileName.empty())
{
if (!_foutOpened)
{
osg::notify(osg::INFO)<<"Writing to cache: "<<_cacheFileName<<std::endl;
_fout.open(_cacheFileName.c_str(), std::ios::out | std::ios::binary);
_foutOpened = true;
}
if (_fout)
{
_fout.write(ptr, realsize);
}
}
}
struct StreamObject
{
StreamObject(std::ostream* stream1, const std::string& cacheFileName):
_stream1(stream1),
_cacheFileName(cacheFileName)
{
_foutOpened = false;
}
void write(const char* ptr, size_t realsize)
{
if (_stream1) _stream1->write(ptr, realsize);
if (!_cacheFileName.empty())
{
if (!_foutOpened)
{
osg::notify(osg::INFO)<<"Writing to cache: "<<_cacheFileName<<std::endl;
_fout.open(_cacheFileName.c_str(), std::ios::out | std::ios::binary);
_foutOpened = true;
}
if (_fout)
{
_fout.write(ptr, realsize);
}
}
}
std::ostream* _stream1;
bool _foutOpened;
std::string _cacheFileName;
std::ofstream _fout;
};
static size_t StreamMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
StreamObject* sp = (StreamObject*)data;
size_t EasyCurl::StreamMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
StreamObject* sp = (StreamObject*)data;
sp->write((const char*)ptr, realsize);
sp->write((const char*)ptr, realsize);
return realsize;
return realsize;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// EasyCurl
//
EasyCurl::EasyCurl()
{
osg::notify(osg::INFO)<<"EasyCurl::EasyCurl()"<<std::endl;
_curl = curl_easy_init();
curl_easy_setopt(_curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, StreamMemoryCallback);
}
EasyCurl::~EasyCurl()
{
osg::notify(osg::INFO)<<"EasyCurl::~EasyCurl()"<<std::endl;
if (_curl) curl_easy_cleanup(_curl);
_curl = 0;
}
osgDB::ReaderWriter::ReadResult EasyCurl::read(const std::string& proxyAddress, const std::string& fileName, StreamObject& sp)
{
if(!proxyAddress.empty())
{
osg::notify(osg::NOTICE)<<"Setting proxy: "<<proxyAddress<<std::endl;
curl_easy_setopt(_curl, CURLOPT_PROXY, proxyAddress.c_str()); //Sets proxy address and port on libcurl
}
curl_easy_setopt(_curl, CURLOPT_URL, fileName.c_str());
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)&sp);
CURLcode res = curl_easy_perform(_curl);
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)0);
if (res==0)
{
long code;
if(!proxyAddress.empty())
{
curl_easy_getinfo(_curl, CURLINFO_HTTP_CONNECTCODE, &code);
}
else
{
curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &code);
}
EasyCurl()
if (code>=400)
{
osg::notify(osg::INFO)<<"EasyCurl::EasyCurl()"<<std::endl;
_curl = curl_easy_init();
curl_easy_setopt(_curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, StreamMemoryCallback);
osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<", error code = "<<code<<std::endl;
return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
}
~EasyCurl()
{
osg::notify(osg::INFO)<<"EasyCurl::~EasyCurl()"<<std::endl;
return osgDB::ReaderWriter::ReadResult::FILE_LOADED;
if (_curl) curl_easy_cleanup(_curl);
_curl = 0;
}
else
{
osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<" error = "<<curl_easy_strerror(res)<<std::endl;
return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// ReaderWriterCURL
//
ReaderWriterCURL::ReaderWriterCURL()
{
//osg::notify(osg::NOTICE)<<"ReaderWriterCURL::ReaderWriterCURL()"<<std::endl;
}
ReaderWriterCURL::~ReaderWriterCURL()
{
//osg::notify(osg::NOTICE)<<"ReaderWriterCURL::~ReaderWriterCURL()"<<std::endl;
}
osgDB::ReaderWriter::ReadResult ReaderWriterCURL::readFile(ObjectType objectType, osgDB::ReaderWriter* rw, std::istream& fin, const osgDB::ReaderWriter::Options *options) const
{
switch(objectType)
{
case(OBJECT): return rw->readObject(fin,options);
case(ARCHIVE): return rw->openArchive(fin,options);
case(IMAGE): return rw->readImage(fin,options);
case(HEIGHTFIELD): return rw->readHeightField(fin,options);
case(NODE): return rw->readNode(fin,options);
default: break;
}
return ReadResult::FILE_NOT_HANDLED;
}
osgDB::ReaderWriter::ReadResult ReaderWriterCURL::readFile(ObjectType objectType, const std::string& fullFileName, const osgDB::ReaderWriter::Options *options) const
{
if (!osgDB::containsServerAddress(fullFileName))
{
if (options && !options->getDatabasePathList().empty())
{
if (osgDB::containsServerAddress(options->getDatabasePathList().front()))
{
std::string newFileName = options->getDatabasePathList().front() + "/" + fullFileName;
return readFile(objectType, newFileName,options);
}
}
return ReadResult::FILE_NOT_HANDLED;
}
osgDB::ReaderWriter::ReadResult read(const std::string& proxyAddress, const std::string& fileName, StreamObject& sp)
osg::notify(osg::INFO)<<"ReaderWriterCURL::readFile("<<fullFileName<<")"<<std::endl;
std::string cacheFilePath, cacheFileName;
std::string proxyAddress, optProxy, optProxyPort;
if (options)
{
std::istringstream iss(options->getOptionString());
std::string opt;
while (iss >> opt)
{
if(!proxyAddress.empty())
{
osg::notify(osg::NOTICE)<<"Setting proxy: "<<proxyAddress<<std::endl;
curl_easy_setopt(_curl, CURLOPT_PROXY, proxyAddress.c_str()); //Sets proxy address and port on libcurl
}
curl_easy_setopt(_curl, CURLOPT_URL, fileName.c_str());
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)&sp);
int index = opt.find( "=" );
if( opt.substr( 0, index ) == "OSG_FILE_CACHE" )
cacheFilePath = opt.substr( index+1 ); //Setting Cache Directory by OSG Options
else if( opt.substr( 0, index ) == "OSG_CURL_PROXY" )
optProxy = opt.substr( index+1 );
else if( opt.substr( 0, index ) == "OSG_CURL_PROXYPORT" )
optProxyPort = opt.substr( index+1 );
}
CURLcode res = curl_easy_perform(_curl);
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)0);
if (res==0)
{
long code;
if(!proxyAddress.empty())
{
curl_easy_getinfo(_curl, CURLINFO_HTTP_CONNECTCODE, &code);
}
else
{
curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &code);
}
if (code>=400)
{
osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<", error code = "<<code<<std::endl;
return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
}
return osgDB::ReaderWriter::ReadResult::FILE_LOADED;
}
//Setting Proxy by OSG Options
if(!optProxy.empty())
if(!optProxyPort.empty())
proxyAddress = optProxy + ":" + optProxyPort;
else
{
osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<" error = "<<curl_easy_strerror(res)<<std::endl;
return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
}
proxyAddress = optProxy + ":8080"; //Port not found, using default
}
std::string fileName;
std::string ext = osgDB::getFileExtension(fullFileName);
if (ext=="curl")
{
fileName = osgDB::getNameLessExtension(fullFileName);
}
else
{
fileName = fullFileName;
}
//Getting CURL Environment Variables (If found rewrite OSG Options)
const char* fileCachePath = getenv("OSG_FILE_CACHE");
if (fileCachePath) //Env Cache Directory
cacheFilePath = std::string(fileCachePath);
if (!cacheFilePath.empty())
{
cacheFileName = cacheFilePath + "/" +
osgDB::getServerAddress(fileName) + "/" +
osgDB::getServerFileName(fileName);
std::string path = osgDB::getFilePath(cacheFileName);
if (!osgDB::fileExists(path) && !osgDB::makeDirectory(path))
{
cacheFileName.clear();
}
}
protected:
// disallow copying
EasyCurl(const EasyCurl& rhs):_curl(rhs._curl) {}
EasyCurl& operator = (const EasyCurl&) { return *this; }
#if 0
if (!cacheFilePath.empty() && osgDB::fileExists(cacheFileName))
{
osg::notify(osg::NOTICE) << "Reading cache file " << cacheFileName <<", previous path "<<osgDB::getFilePath(fileName)<<std::endl;
ReadResult result = osgDB::Registry::instance()->readObject(cacheFileName,options);
CURL* _curl;
};
return result;
}
#endif
osgDB::ReaderWriter *reader =
osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName));
class ReaderWriterCURL : public osgDB::ReaderWriter
{
public:
if (!reader)
{
osg::notify(osg::NOTICE)<<"Error: No ReaderWriter for file "<<fileName<<std::endl;
return ReadResult::FILE_NOT_HANDLED;
}
const char* proxyEnvAddress = getenv("OSG_CURL_PROXY");
if (proxyEnvAddress) //Env Proxy Settings
{
const char* proxyEnvPort = getenv("OSG_CURL_PROXYPORT"); //Searching Proxy Port on Env
if(proxyEnvPort)
proxyAddress = std::string(proxyEnvAddress) + ":" + std::string(proxyEnvPort);
else
proxyAddress = std::string(proxyEnvAddress) + ":8080"; //Default
}
ReaderWriterCURL()
{
}
~ReaderWriterCURL()
{
}
std::stringstream buffer;
virtual const char* className() const { return "HTTP Protocol Model Reader"; }
virtual bool acceptsExtension(const std::string& extension) const
{
return osgDB::equalCaseInsensitive(extension,"curl");
}
#if 0
EasyCurl::StreamObject sp(&buffer, cacheFileName);
#else
EasyCurl::StreamObject sp(&buffer, std::string());
#endif
enum ObjectType
{
OBJECT,
ARCHIVE,
IMAGE,
HEIGHTFIELD,
NODE
};
virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const
{
if (status!=READ) return ReadResult(ReadResult::FILE_NOT_HANDLED);
else return readFile(ARCHIVE,fileName,options);
}
ReadResult curlResult = getEasyCurl().read(proxyAddress, fileName, sp);
virtual ReadResult readObject(const std::string& fileName, const Options* options) const
{
return readFile(OBJECT,fileName,options);
}
virtual ReadResult readImage(const std::string& fileName, const Options *options) const
{
return readFile(IMAGE,fileName,options);
}
if (curlResult.status()==ReadResult::FILE_LOADED)
{
osg::ref_ptr<Options> local_opt = const_cast<Options*>(options);
if (!local_opt) local_opt = new Options;
virtual ReadResult readHeightField(const std::string& fileName, const Options *options) const
{
return readFile(HEIGHTFIELD,fileName,options);
}
local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
virtual ReadResult readNode(const std::string& fileName, const Options *options) const
{
return readFile(NODE,fileName,options);
}
ReadResult readResult = readFile(objectType, reader, buffer, local_opt.get() );
ReadResult readFile(ObjectType objectType, osgDB::ReaderWriter* rw, std::istream& fin, const Options *options) const
#if 0
if (!cacheFileName.empty() && readResult.success())
{
switch(objectType)
{
case(OBJECT): return rw->readObject(fin,options);
case(ARCHIVE): return rw->openArchive(fin,options);
case(IMAGE): return rw->readImage(fin,options);
case(HEIGHTFIELD): return rw->readHeightField(fin,options);
case(NODE): return rw->readNode(fin,options);
default: break;
}
return ReadResult::FILE_NOT_HANDLED;
}
virtual ReadResult readFile(ObjectType objectType, const std::string& fullFileName, const Options *options) const
{
std::string cacheFilePath, cacheFileName;
std::string proxyAddress, optProxy, optProxyPort;
if (options)
{
std::istringstream iss(options->getOptionString());
std::string opt;
while (iss >> opt)
{
int index = opt.find( "=" );
if( opt.substr( 0, index ) == "OSG_FILE_CACHE" )
cacheFilePath = opt.substr( index+1 ); //Setting Cache Directory by OSG Options
else if( opt.substr( 0, index ) == "OSG_CURL_PROXY" )
optProxy = opt.substr( index+1 );
else if( opt.substr( 0, index ) == "OSG_CURL_PROXYPORT" )
optProxyPort = opt.substr( index+1 );
}
//Setting Proxy by OSG Options
if(!optProxy.empty())
if(!optProxyPort.empty())
proxyAddress = optProxy + ":" + optProxyPort;
else
proxyAddress = optProxy + ":8080"; //Port not found, using default
}
if (!osgDB::containsServerAddress(fullFileName))
{
if (options && !(options->getDatabasePathList().empty()))
{
if (osgDB::containsServerAddress(options->getDatabasePathList().front()))
{
std::string newFileName = options->getDatabasePathList().front() + "/" + fullFileName;
return readFile(objectType, newFileName,options);
}
}
return ReadResult::FILE_NOT_HANDLED;
}
std::string fileName;
std::string ext = osgDB::getFileExtension(fullFileName);
if (ext=="curl")
{
fileName = osgDB::getNameLessExtension(fullFileName);
}
else
{
fileName = fullFileName;
}
//Getting CURL Environment Variables (If found rewrite OSG Options)
const char* fileCachePath = getenv("OSG_FILE_CACHE");
if (fileCachePath) //Env Cache Directory
cacheFilePath = std::string(fileCachePath);
if (!cacheFilePath.empty())
{
cacheFileName = cacheFilePath + "/" +
osgDB::getServerAddress(fileName) + "/" +
osgDB::getServerFileName(fileName);
std::string path = osgDB::getFilePath(cacheFileName);
if (!osgDB::fileExists(path) && !osgDB::makeDirectory(path))
{
cacheFileName.clear();
}
}
if (!cacheFilePath.empty() && osgDB::fileExists(cacheFileName))
{
osg::notify(osg::INFO) << "Reading cache file " << cacheFileName << std::endl;
ReadResult result = osgDB::Registry::instance()->readObject(cacheFileName,options);
return result;
}
osgDB::ReaderWriter *reader =
osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName));
if (!reader)
{
osg::notify(osg::NOTICE)<<"Error: No ReaderWriter for file "<<fileName<<std::endl;
return ReadResult::FILE_NOT_HANDLED;
}
const char* proxyEnvAddress = getenv("OSG_CURL_PROXY");
if (proxyEnvAddress) //Env Proxy Settings
{
const char* proxyEnvPort = getenv("OSG_CURL_PROXYPORT"); //Searching Proxy Port on Env
if(proxyEnvPort)
proxyAddress = std::string(proxyEnvAddress) + ":" + std::string(proxyEnvPort);
else
proxyAddress = std::string(proxyEnvAddress) + ":8080"; //Default
}
bool asyncFileRead = options ? options->getAsynchronousFileReadHint() : false;
osg::notify(osg::INFO)<<"AsynchronousFileReadHint= "<<asyncFileRead<<std::endl;
// if (asyncFileRead) return ReadResult::FILE_REQUESTED;
std::stringstream buffer;
ReadResult curlResult;
EasyCurl::StreamObject sp(&buffer, cacheFileName);
//ReadResult result = _easyCurl.read(proxyAddress, fileName, sp);
curlResult = getEasyCurl().read(proxyAddress, fileName, sp);
if (curlResult.status()==ReadResult::FILE_LOADED)
{
osg::ref_ptr<Options> local_opt = const_cast<Options*>(options);
if (!local_opt) local_opt = new Options;
local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
ReadResult readResult = readFile(objectType, reader, buffer, local_opt.get() );
local_opt->getDatabasePathList().pop_front();
return readResult;
}
else
{
return curlResult;
case(NODE):
osg::notify(osg::NOTICE)<<"Write to cache "<<cacheFileName<<std::endl;
reader->writeNode(*readResult.getNode(), cacheFileName, local_opt.get());
break;
default:
osg::notify(osg::NOTICE)<<"Curl plugin write to cache not implemented yet"<<std::endl;
}
}
protected:
typedef std::map<OpenThreads::Thread*, osg::ref_ptr<EasyCurl> > ThreadCurlMap;
EasyCurl& getEasyCurl() const
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_threadCurlMapMutex);
osg::ref_ptr<EasyCurl>& ec = _threadCurlMap[OpenThreads::Thread::CurrentThread()];
if (!ec) ec = new EasyCurl;
return *ec;
}
mutable OpenThreads::Mutex _threadCurlMapMutex;
mutable ThreadCurlMap _threadCurlMap;
};
#endif
local_opt->getDatabasePathList().pop_front();
return readResult;
}
else
{
return curlResult;
}
}
// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(rgb, ReaderWriterCURL)
REGISTER_OSGPLUGIN(curl, ReaderWriterCURL)

View File

@ -28,15 +28,23 @@ bool PagedLOD_readLocalData(Object& obj, Input& fr)
PagedLOD& lod = static_cast<PagedLOD&>(obj);
if (lod.getDatabasePath().empty() && fr.getOptions() && !fr.getOptions()->getDatabasePathList().empty())
std::string path;
if (!fr.read("DatabasePath",path))
{
const std::string& path = fr.getOptions()->getDatabasePathList().front();
if (!path.empty())
lod.setDatabasePath(path);
}
else
{
if (lod.getDatabasePath().empty() && fr.getOptions() && !fr.getOptions()->getDatabasePathList().empty())
{
lod.setDatabasePath(path);
}
}
const std::string& path = fr.getOptions()->getDatabasePathList().front();
if (!path.empty())
{
lod.setDatabasePath(path);
}
}
}
unsigned int num;
if (fr[0].matchWord("NumChildrenThatCannotBeExpired") && fr[1].getUInt(num))
{
@ -106,6 +114,12 @@ bool PagedLOD_writeLocalData(const Object& obj, Output& fw)
{
const PagedLOD& lod = static_cast<const PagedLOD&>(obj);
if (!lod.getDatabasePath().empty())
{
fw.indent() << "DatabasePath "<<lod.getDatabasePath()<<std::endl;
}
fw.indent() << "NumChildrenThatCannotBeExpired "<<lod.getNumChildrenThatCannotBeExpired()<<std::endl;
fw.indent() << "FileNameList "<<lod.getNumFileNames()<<" {"<< std::endl;

View File

@ -88,7 +88,7 @@ void TXPPagedLOD::traverse(osg::NodeVisitor& nv)
priority = _perRangeDataList[numChildren]._priorityOffset + priority * _perRangeDataList[numChildren]._priorityScale;
//std::cout<<" requesting child "<<_fileNameList[numChildren]<<" priotity = "<<priority<<std::endl;
nv.getDatabaseRequestHandler()->requestNodeFile(_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp());
nv.getDatabaseRequestHandler()->requestNodeFile(_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp(),_perRangeDataList[numChildren]._databaseRequest);
}

View File

@ -373,10 +373,17 @@ void CompositeViewer::getAllThreads(Threads& threads, bool onlyActive)
++sitr)
{
Scene* scene = *sitr;
if (scene->getDatabasePager() &&
(!onlyActive || scene->getDatabasePager()->isRunning()))
osgDB::DatabasePager* dp = scene->getDatabasePager();
if (dp)
{
threads.push_back(scene->getDatabasePager());
for(unsigned int i=0; i<dp->getNumDatabaseThreads(); ++i)
{
osgDB::DatabasePager::DatabaseThread* dt = dp->getDatabaseThread(i);
if (!onlyActive || dt->isRunning())
{
threads.push_back(dt);
}
}
}
}
}

View File

@ -971,11 +971,21 @@ void Viewer::getAllThreads(Threads& threads, bool onlyActive)
threads.push_back(*itr);
}
if (_scene.valid() &&
_scene->getDatabasePager() &&
(!onlyActive || _scene->getDatabasePager()->isRunning()))
if (_scene.valid())
{
threads.push_back(_scene->getDatabasePager());
osgDB::DatabasePager* dp = _scene->getDatabasePager();
if (dp)
{
for(unsigned int i=0; i<dp->getNumDatabaseThreads(); ++i)
{
osgDB::DatabasePager::DatabaseThread* dt = dp->getDatabaseThread(i);
if (!onlyActive || dt->isRunning())
{
threads.push_back(dt);
}
}
}
}
}

View File

@ -142,9 +142,14 @@ void ViewerBase::setUpThreading()
++itr)
{
Scene* scene = *itr;
if (scene && scene->getDatabasePager())
osgDB::DatabasePager* dp = scene->getDatabasePager();
if (dp)
{
scene->getDatabasePager()->setProcessorAffinity(1);
for(unsigned int i=0; i<dp->getNumDatabaseThreads(); ++i)
{
osgDB::DatabasePager::DatabaseThread* dt = dp->getDatabaseThread(i);
dt->setProcessorAffinity(1);
}
}
}

View File

@ -384,10 +384,50 @@ BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::NodeVisitor::DatabaseRequestHandler)
I_Constructor0(____DatabaseRequestHandler,
"",
"");
I_Method4(void, requestNodeFile, IN, const std::string &, fileName, IN, osg::Group *, group, IN, float, priority, IN, const osg::FrameStamp *, framestamp,
I_Method5(void, requestNodeFile, IN, const std::string &, fileName, IN, osg::Group *, group, IN, float, priority, IN, const osg::FrameStamp *, framestamp, IN, osg::ref_ptr< osg::Referenced > &, databaseRequest,
Properties::PURE_VIRTUAL,
__void__requestNodeFile__C5_std_string_R1__osg_Group_P1__float__C5_FrameStamp_P1,
__void__requestNodeFile__C5_std_string_R1__osg_Group_P1__float__C5_FrameStamp_P1__osg_ref_ptrT1_osg_Referenced__R1,
"",
"");
END_REFLECTOR
BEGIN_VALUE_REFLECTOR(osg::ref_ptr< osg::Referenced >)
I_DeclaringFile("osg/ref_ptr");
I_Constructor0(____ref_ptr,
"",
"");
I_Constructor1(IN, osg::Referenced *, ptr,
Properties::NON_EXPLICIT,
____ref_ptr__T_P1,
"",
"");
I_Constructor1(IN, const osg::ref_ptr< osg::Referenced > &, rp,
Properties::NON_EXPLICIT,
____ref_ptr__C5_ref_ptr_R1,
"",
"");
I_Method0(osg::Referenced *, get,
Properties::NON_VIRTUAL,
__T_P1__get,
"",
"");
I_Method0(bool, valid,
Properties::NON_VIRTUAL,
__bool__valid,
"",
"");
I_Method0(osg::Referenced *, release,
Properties::NON_VIRTUAL,
__T_P1__release,
"",
"");
I_Method1(void, swap, IN, osg::ref_ptr< osg::Referenced > &, rp,
Properties::NON_VIRTUAL,
__void__swap__ref_ptr_R1,
"",
"");
I_SimpleProperty(osg::Referenced *, ,
__T_P1__get,
0);
END_REFLECTOR

View File

@ -16,6 +16,7 @@
#include <osg/NodeVisitor>
#include <osg/Object>
#include <osg/PagedLOD>
#include <osg/Referenced>
// Must undefine IN and OUT macros defined in Windows headers
#ifdef IN
@ -162,6 +163,16 @@ BEGIN_OBJECT_REFLECTOR(osg::PagedLOD)
__unsigned_int__getNumTimeStamps,
"",
"");
I_Method1(osg::ref_ptr< osg::Referenced > &, getDatabaseRequest, IN, unsigned int, childNo,
Properties::NON_VIRTUAL,
__osg_ref_ptrT1_osg_Referenced__R1__getDatabaseRequest__unsigned_int,
"Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests being carried on behalf of the DatabasePager. ",
"Note, in normal OSG usage you should not set this value yourself, as this will be managed by the osgDB::DatabasePager. ");
I_Method1(const osg::ref_ptr< osg::Referenced > &, getDatabaseRequest, IN, unsigned int, childNo,
Properties::NON_VIRTUAL,
__C5_osg_ref_ptrT1_osg_Referenced__R1__getDatabaseRequest__unsigned_int,
"Return the const DatabaseRequest object. ",
"");
I_Method1(void, setFrameNumberOfLastTraversal, IN, int, frameNumber,
Properties::NON_VIRTUAL,
__void__setFrameNumberOfLastTraversal__int,
@ -246,6 +257,7 @@ BEGIN_VALUE_REFLECTOR(osg::PagedLOD::PerRangeData)
I_PublicMemberProperty(float, _priorityOffset);
I_PublicMemberProperty(float, _priorityScale);
I_PublicMemberProperty(double, _timeStamp);
I_PublicMemberProperty(osg::ref_ptr< osg::Referenced >, _databaseRequest);
END_REFLECTOR
STD_VECTOR_REFLECTOR(std::vector< osg::PagedLOD::PerRangeData >)

View File

@ -16,6 +16,7 @@
#include <osg/NodeVisitor>
#include <osg/Object>
#include <osg/ProxyNode>
#include <osg/Referenced>
#include <osg/Vec3>
// Must undefine IN and OUT macros defined in Windows headers
@ -30,8 +31,6 @@ TYPE_NAME_ALIAS(osg::BoundingSphere::vec_type, osg::ProxyNode::vec_type)
TYPE_NAME_ALIAS(osg::BoundingSphere::value_type, osg::ProxyNode::value_type)
TYPE_NAME_ALIAS(std::vector< std::string >, osg::ProxyNode::FileNameList)
BEGIN_ENUM_REFLECTOR(osg::ProxyNode::CenterMode)
I_DeclaringFile("osg/ProxyNode");
I_EnumLabel(osg::ProxyNode::USE_BOUNDING_SPHERE_CENTER);
@ -130,6 +129,16 @@ BEGIN_OBJECT_REFLECTOR(osg::ProxyNode)
__unsigned_int__getNumFileNames,
"",
"");
I_Method1(osg::ref_ptr< osg::Referenced > &, getDatabaseRequest, IN, unsigned int, childNo,
Properties::NON_VIRTUAL,
__osg_ref_ptrT1_osg_Referenced__R1__getDatabaseRequest__unsigned_int,
"Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests being carried on behalf of the DatabasePager. ",
"Note, in normal OSG usage you should not set this value yourself, as this will be managed by the osgDB::DatabasePager. ");
I_Method1(const osg::ref_ptr< osg::Referenced > &, getDatabaseRequest, IN, unsigned int, childNo,
Properties::NON_VIRTUAL,
__C5_osg_ref_ptrT1_osg_Referenced__R1__getDatabaseRequest__unsigned_int,
"Return the const DatabaseRequest object. ",
"");
I_Method1(void, setCenterMode, IN, osg::ProxyNode::CenterMode, mode,
Properties::NON_VIRTUAL,
__void__setCenterMode__CenterMode,

View File

@ -10,11 +10,13 @@
#include <osgIntrospection/StaticMethodInfo>
#include <osgIntrospection/Attributes>
#include <OpenThreads/Thread>
#include <osg/FrameStamp>
#include <osg/GraphicsContext>
#include <osg/Group>
#include <osg/Node>
#include <osg/PagedLOD>
#include <osg/Referenced>
#include <osg/State>
#include <osgDB/DatabasePager>
#include <osgDB/ReaderWriter>
@ -54,7 +56,6 @@ END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
I_DeclaringFile("osgDB/DatabasePager");
I_BaseType(osg::NodeVisitor::DatabaseRequestHandler);
I_BaseType(OpenThreads::Thread);
I_Constructor0(____DatabasePager,
"",
"");
@ -68,31 +69,51 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
__DatabasePager_P1__clone,
"Create a shallow copy on the DatabasePager. ",
"");
I_Method4(void, requestNodeFile, IN, const std::string &, fileName, IN, osg::Group *, group, IN, float, priority, IN, const osg::FrameStamp *, framestamp,
I_Method5(void, requestNodeFile, IN, const std::string &, fileName, IN, osg::Group *, group, IN, float, priority, IN, const osg::FrameStamp *, framestamp, IN, osg::ref_ptr< osg::Referenced > &, databaseRequest,
Properties::VIRTUAL,
__void__requestNodeFile__C5_std_string_R1__osg_Group_P1__float__C5_osg_FrameStamp_P1,
__void__requestNodeFile__C5_std_string_R1__osg_Group_P1__float__C5_osg_FrameStamp_P1__osg_ref_ptrT1_osg_Referenced__R1,
"Add a request to load a node file to end the the database request list. ",
"");
I_Method5(void, requestNodeFile, IN, const std::string &, fileName, IN, osg::Group *, group, IN, float, priority, IN, const osg::FrameStamp *, framestamp, IN, osgDB::ReaderWriter::Options *, loadOptions,
I_Method6(void, requestNodeFile, IN, const std::string &, fileName, IN, osg::Group *, group, IN, float, priority, IN, const osg::FrameStamp *, framestamp, IN, osg::ref_ptr< osg::Referenced > &, databaseRequest, IN, osgDB::ReaderWriter::Options *, loadOptions,
Properties::VIRTUAL,
__void__requestNodeFile__C5_std_string_R1__osg_Group_P1__float__C5_osg_FrameStamp_P1__ReaderWriter_Options_P1,
__void__requestNodeFile__C5_std_string_R1__osg_Group_P1__float__C5_osg_FrameStamp_P1__osg_ref_ptrT1_osg_Referenced__R1__ReaderWriter_Options_P1,
"",
"");
I_Method0(void, run,
Properties::VIRTUAL,
__void__run,
"Run does the database paging. ",
I_Method1(int, setSchedulePriority, IN, OpenThreads::Thread::ThreadPriority, priority,
Properties::NON_VIRTUAL,
__int__setSchedulePriority__OpenThreads_Thread_ThreadPriority,
"Set the priority of the database pager thread(s). ",
"");
I_Method0(int, cancel,
Properties::VIRTUAL,
__int__cancel,
"Cancel the database pager thread. ",
"Cancel the database pager thread(s). ",
"");
I_Method0(bool, isRunning,
Properties::VIRTUAL,
__bool__isRunning,
"",
"");
I_Method0(void, clear,
Properties::VIRTUAL,
__void__clear,
"Clear all internally cached structures. ",
"");
I_Method1(osgDB::DatabasePager::DatabaseThread *, getDatabaseThread, IN, unsigned int, i,
Properties::NON_VIRTUAL,
__DatabaseThread_P1__getDatabaseThread__unsigned_int,
"",
"");
I_Method1(const osgDB::DatabasePager::DatabaseThread *, getDatabaseThread, IN, unsigned int, i,
Properties::NON_VIRTUAL,
__C5_DatabaseThread_P1__getDatabaseThread__unsigned_int,
"",
"");
I_Method0(unsigned int, getNumDatabaseThreads,
Properties::NON_VIRTUAL,
__unsigned_int__getNumDatabaseThreads,
"",
"");
I_Method1(void, setDatabasePagerThreadPause, IN, bool, pause,
Properties::NON_VIRTUAL,
__void__setDatabasePagerThreadPause__bool,
@ -301,12 +322,6 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
__DatabasePager_P1__create_S,
"create a DatabasePager by cloning DatabasePager::prototype(). ",
"");
I_ProtectedMethod0(void, updateDatabasePagerThreadBlock,
Properties::NON_VIRTUAL,
Properties::NON_CONST,
__void__updateDatabasePagerThreadBlock,
"",
"");
I_ProtectedMethod1(bool, isCompiled, IN, osg::Texture *, texture,
Properties::NON_VIRTUAL,
Properties::CONST,
@ -353,6 +368,13 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
I_SimpleProperty(bool, DatabasePagerThreadPause,
__bool__getDatabasePagerThreadPause,
__void__setDatabasePagerThreadPause__bool);
I_ArrayProperty(osgDB::DatabasePager::DatabaseThread *, DatabaseThread,
__DatabaseThread_P1__getDatabaseThread__unsigned_int,
0,
__unsigned_int__getNumDatabaseThreads,
0,
0,
0);
I_SimpleProperty(bool, DeleteRemovedSubgraphsInDatabaseThread,
__bool__getDeleteRemovedSubgraphsInDatabaseThread,
__void__setDeleteRemovedSubgraphsInDatabaseThread__bool);
@ -380,11 +402,58 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
I_SimpleProperty(double, MinimumTimeToMergeTile,
__double__getMinimumTimeToMergeTile,
0);
I_SimpleProperty(OpenThreads::Thread::ThreadPriority, SchedulePriority,
0,
__int__setSchedulePriority__OpenThreads_Thread_ThreadPriority);
I_SimpleProperty(double, TargetFrameRate,
__double__getTargetFrameRate,
__void__setTargetFrameRate__double);
END_REFLECTOR
BEGIN_ENUM_REFLECTOR(osgDB::DatabasePager::DatabaseThread::Mode)
I_DeclaringFile("osgDB/DatabasePager");
I_EnumLabel(osgDB::DatabasePager::DatabaseThread::HANDLE_ALL_REQUESTS);
I_EnumLabel(osgDB::DatabasePager::DatabaseThread::HANDLE_NON_HTTP);
I_EnumLabel(osgDB::DatabasePager::DatabaseThread::HANDLE_ONLY_HTTP);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager::DatabaseThread)
I_DeclaringFile("osgDB/DatabasePager");
I_BaseType(osg::Referenced);
I_BaseType(OpenThreads::Thread);
I_Constructor3(IN, osgDB::DatabasePager *, pager, IN, osgDB::DatabasePager::DatabaseThread::Mode, mode, IN, const std::string &, name,
____DatabaseThread__DatabasePager_P1__Mode__C5_std_string_R1,
"",
"");
I_Constructor2(IN, const osgDB::DatabasePager::DatabaseThread &, dt, IN, osgDB::DatabasePager *, pager,
____DatabaseThread__C5_DatabaseThread_R1__DatabasePager_P1,
"",
"");
I_Method1(void, setDone, IN, bool, done,
Properties::NON_VIRTUAL,
__void__setDone__bool,
"",
"");
I_Method0(bool, getDone,
Properties::NON_VIRTUAL,
__bool__getDone,
"",
"");
I_Method0(int, cancel,
Properties::VIRTUAL,
__int__cancel,
"Cancel the thread. ",
"Equivalent to SIGKILL.0 if normal, -1 if errno set, errno code otherwise. ");
I_Method0(void, run,
Properties::VIRTUAL,
__void__run,
"Thread's run method. ",
"Must be implemented by derived classes. This is where the action happens. ");
I_SimpleProperty(bool, Done,
__bool__getDone,
__void__setDone__bool);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osg::observer_ptr< osg::GraphicsContext >)
I_DeclaringFile("osg/observer_ptr");
I_BaseType(osg::Observer);

View File

@ -273,16 +273,6 @@ BEGIN_OBJECT_REFLECTOR(osgDB::ReaderWriter::Options)
__CacheHintOptions__getObjectCacheHint,
"Get whether the Registry::ObjectCache should be used by default. ",
"");
I_Method1(void, setAsynchronousFileReadHint, IN, bool, flag,
Properties::NON_VIRTUAL,
__void__setAsynchronousFileReadHint__bool,
"Set Asynchrnous file read hint. ",
"This hint is used by plugins like the libcurl http reader plugin to inform them that they should make an internal file read requests to their background threads to load files, with the plugin returning immediately with a ReadResult::FILE_REQUESTED status. It is assumed that calls will continue to be made to the plugin until the background threads have read or failed to read the request file, at which point the return status which change to FILE_LOADED and the objects will be returned. Note, this facility is particular useful when using DatabasePager in conjunction with internet based databases where file load latency is relatively high. ");
I_Method0(bool, getAsynchronousFileReadHint,
Properties::NON_VIRTUAL,
__bool__getAsynchronousFileReadHint,
"Get Asynchrnous file read hint. ",
"");
I_Method2(void, setPluginData, IN, const std::string &, s, IN, void *, v,
Properties::NON_VIRTUAL,
__void__setPluginData__C5_std_string_R1__void_P1,
@ -303,9 +293,6 @@ BEGIN_OBJECT_REFLECTOR(osgDB::ReaderWriter::Options)
__void__removePluginData__C5_std_string_R1,
"Remove a value from the PluginData. ",
"");
I_SimpleProperty(bool, AsynchronousFileReadHint,
__bool__getAsynchronousFileReadHint,
__void__setAsynchronousFileReadHint__bool);
I_SimpleProperty(const std::string &, DatabasePath,
0,
__void__setDatabasePath__C5_std_string_R1);