#ifndef _CacheReader_h_
#define _CacheReader_h_
#include "gpuCacheGeometry.h"
#include "gpuCacheMaterial.h"
#include <maya/MFileObject.h>
#include <maya/MString.h>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp>
class CacheReader;
class CacheFileEntry;
class GlobalReaderCache
{
public:
static GlobalReaderCache& theCache();
static int maxNumOpenFiles();
class CacheReaderProxy
{
public:
typedef boost::shared_ptr<CacheReaderProxy> Ptr;
~CacheReaderProxy();
private:
GPUCACHE_DECLARE_MAKE_SHARED_FRIEND_1;
};
class CacheReaderHolder
{
public:
CacheReaderHolder(boost::shared_ptr<CacheReaderProxy> proxy);
~CacheReaderHolder();
boost::shared_ptr<CacheReader> getCacheReader();
private:
boost::shared_ptr<CacheReaderProxy> fProxy;
boost::shared_ptr<CacheReader> fReader;
};
boost::shared_ptr<CacheReaderProxy> getCacheReaderProxy(
const MFileObject& file);
bool scheduleRead(const CacheFileEntry* entry,
CacheReaderProxy::Ptr& proxy);
bool pullHierarchy(const CacheFileEntry* entry,
GPUCache::SubNode::Ptr& geometry,
GPUCache::MaterialGraphMap::Ptr& materials);
bool pullShape(const CacheFileEntry* entry,
GPUCache::SubNode::Ptr& geometry);
void hintShapeReadOrder(const GPUCache::SubNode& subNode);
void cancelRead(const CacheFileEntry* entry);
void waitForRead(const CacheFileEntry* entry);
bool isInterrupted();
void pauseRead();
void resumeRead();
bool isPaused();
void pauseUntilNotified();
private:
friend class CacheReader;
friend class CacheReaderProxy;
class Impl;
class Scheduler;
GlobalReaderCache(const GlobalReaderCache&);
const GlobalReaderCache& operator= (const GlobalReaderCache&);
boost::shared_ptr<CacheReader> acquireOwnership(
const MFileObject& file);
GlobalReaderCache();
~GlobalReaderCache();
boost::shared_ptr<Impl> fImpl;
boost::shared_ptr<Scheduler> fScheduler;
};
class CacheReader
{
public:
typedef boost::shared_ptr<CacheReader> CreateFunction(
const MFileObject& file);
static void registerReader(
const MString& impl, CreateFunction* func);
virtual bool valid() const = 0;
virtual bool validateGeomPath(
virtual GPUCache::SubNode::Ptr readScene(
const MString& geomPath,
bool needUVs) = 0;
virtual GPUCache::SubNode::Ptr readHierarchy(
const MString& geomPath,
bool needUVs) = 0;
virtual GPUCache::SubNode::Ptr readShape(
const MString& geomPath,
bool needUVs) = 0;
virtual GPUCache::MaterialGraphMap::Ptr readMaterials() = 0;
virtual bool readAnimTimeRange(GPUCache::TimeInterval& range) = 0;
protected:
CacheReader() {}
virtual ~CacheReader() {}
private:
friend class GlobalReaderCache::Impl;
static boost::shared_ptr<CacheReader> create(
const MString& impl,
CacheReader(const CacheReader&);
const CacheReader& operator=(const CacheReader&);
static std::map<std::string,CreateFunction*> fsRegistry;
};
class CacheReaderInterruptException : public std::exception
{
public:
CacheReaderInterruptException(const std::string& str) throw()
: fWhat(str)
{}
virtual ~CacheReaderInterruptException() throw()
{}
virtual const char* what() const throw()
{ return fWhat.c_str(); }
private:
std::string fWhat;
};
class CacheFileEntry
{
public:
typedef boost::shared_ptr<CacheFileEntry> MPtr;
enum BackgroundReadingState {
kReadingHierarchyInProgress,
kReadingShapesInProgress,
kReadingDone
};
~CacheFileEntry();
static MPtr create(
const MString& fileName )
{
return boost::make_shared<CacheFileEntry>(fileName);
}
CacheFileEntry& operator=( const CacheFileEntry& rhs );
GPUCache::SubNode::Ptr fCachedGeometry;
GPUCache::MaterialGraphMap::Ptr fCachedMaterial;
GlobalReaderCache::CacheReaderProxy::Ptr fCacheReaderProxy;
BackgroundReadingState fReadState;
private:
template<class T> friend void boost::checked_delete(T * x);
GPUCACHE_DECLARE_MAKE_SHARED_FRIEND_1;
CacheFileEntry();
CacheFileEntry( const CacheFileEntry& rhs );
CacheFileEntry(
const MString& fileName );
};
class CacheFileRegistry
{
public:
typedef boost::unordered_map<MString, CacheFileEntry::MPtr, GPUCache::MStringHash> Map;
~CacheFileRegistry();
static CacheFileRegistry& theCache();
void getAll(std::vector<CacheFileEntry::MPtr>& entries) const;
CacheFileEntry::MPtr find(
const MString& key);
bool insert(
const MString& key,
const CacheFileEntry::MPtr& file);
size_t size() const;
void clear();
private:
CacheFileRegistry();
static CacheFileRegistry fsSingleton;
static Map fMap;
};
#endif