Initial commit
This commit is contained in:
327
Torque/SDK/engine/core/resManager.h
Normal file
327
Torque/SDK/engine/core/resManager.h
Normal file
@@ -0,0 +1,327 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
//
|
||||
// Copyright (c) 2001 GarageGames.Com
|
||||
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _RESMANAGER_H_
|
||||
#define _RESMANAGER_H_
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/tVector.h"
|
||||
#endif
|
||||
#ifndef _STRINGTABLE_H_
|
||||
#include "core/stringTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FILESTREAM_H_
|
||||
#include "core/fileStream.h"
|
||||
#endif
|
||||
#ifndef _ZIPSUBSTREAM_H_
|
||||
#include "core/zipSubStream.h"
|
||||
#endif
|
||||
#ifndef _ZIPAGGREGATE_H_
|
||||
#include "core/zipAggregate.h"
|
||||
#endif
|
||||
#ifndef _ZIPHEADERS_H_
|
||||
#include "core/zipHeaders.h"
|
||||
#endif
|
||||
#ifndef _CRC_H_
|
||||
#include "core/crc.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define RES_DEFAULT_TIMEOUT (5*60*1000) //5-minutes
|
||||
|
||||
class Stream;
|
||||
class FileStream;
|
||||
class ZipSubRStream;
|
||||
class ResManager;
|
||||
class FindMatch;
|
||||
|
||||
|
||||
extern ResManager *ResourceManager;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Basic resource manager behavior
|
||||
// -set the mod path
|
||||
// ResManager scans directory tree under listed base directories
|
||||
// Any .rpk (.zip) file in the root directory of a mod is added (scanned)
|
||||
// for resources
|
||||
// Any files currently in the resource manager become memory resources
|
||||
// They can be "reattached" to the first file that matches the file name
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
// all classes which wish to be handled by the resource manager
|
||||
// need to be
|
||||
// 1) derrived from ResourceInstance
|
||||
// 2) register a creation function and file extension with the manager
|
||||
|
||||
class ResourceInstance
|
||||
{
|
||||
private:
|
||||
public:
|
||||
virtual ~ResourceInstance() {}
|
||||
};
|
||||
|
||||
|
||||
typedef ResourceInstance* (*RESOURCE_CREATE_FN)(Stream &stream);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#define InvalidCRC 0xFFFFFFFF
|
||||
|
||||
class ResourceObject
|
||||
{
|
||||
friend class ResDictionary;
|
||||
friend class ResManager;
|
||||
|
||||
ResourceObject *prev, *next; // timeout list
|
||||
ResourceObject *nextEntry; // objects are inserted by id or name
|
||||
ResourceObject *nextResource; // in linked list of all resources
|
||||
ResourceObject *prevResource;
|
||||
public:
|
||||
enum
|
||||
{
|
||||
VolumeBlock = 1 << 0,
|
||||
File = 1 << 1,
|
||||
Added = 1 << 2,
|
||||
};
|
||||
S32 flags;
|
||||
|
||||
StringTableEntry path; // resource path
|
||||
StringTableEntry name; // resource name
|
||||
|
||||
StringTableEntry zipPath; // path/name of file of volume if in Zip Volume
|
||||
StringTableEntry zipName;
|
||||
|
||||
S32 fileOffset; // offset on disk in fileName file of resource
|
||||
S32 fileSize; // size on disk of resource block
|
||||
S32 compressedFileSize; // Actual size of resource data.
|
||||
|
||||
ResourceInstance *mInstance; // ptr ot actual object instance
|
||||
S32 lockCount;
|
||||
U32 crc;
|
||||
|
||||
ResourceObject();
|
||||
~ResourceObject() { unlink(); }
|
||||
|
||||
void destruct();
|
||||
|
||||
ResourceObject* getNext() const { return next; }
|
||||
void unlink();
|
||||
void linkAfter(ResourceObject* res);
|
||||
void getFileTimes(FileTime *createTime, FileTime *modifyTime);
|
||||
};
|
||||
|
||||
|
||||
inline void ResourceObject::unlink()
|
||||
{
|
||||
if (next)
|
||||
next->prev = prev;
|
||||
if (prev)
|
||||
prev->next = next;
|
||||
next = prev = 0;
|
||||
}
|
||||
|
||||
inline void ResourceObject::linkAfter(ResourceObject* res)
|
||||
{
|
||||
unlink();
|
||||
prev = res;
|
||||
if ((next = res->next) != 0)
|
||||
next->prev = this;
|
||||
res->next = this;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class T> class Resource
|
||||
{
|
||||
private:
|
||||
ResourceObject *obj;
|
||||
// ***WARNING***
|
||||
// Using a faster lock that bypasses the resource manger.
|
||||
// void _lock() { if (obj) obj->rm->lockResource( obj ); }
|
||||
void _lock();
|
||||
void _unlock();
|
||||
|
||||
public:
|
||||
// If assigned a ResourceObject, it's assumed to already have
|
||||
// been locked, lock count is incremented only for copies or
|
||||
// assignment from another Resource.
|
||||
Resource() : obj(NULL) { ; }
|
||||
Resource(ResourceObject *p) : obj(p) { ; }
|
||||
Resource(const Resource &res) : obj(res.obj) { _lock(); }
|
||||
~Resource() { unlock(); }
|
||||
|
||||
const char *getFilePath() const { return (obj ? obj->path : NULL); }
|
||||
const char *getFileName() const { return (obj ? obj->name : NULL); }
|
||||
|
||||
Resource& operator= (ResourceObject *p) { _unlock(); obj = p; return *this; }
|
||||
Resource& operator= (const Resource &r) { _unlock(); obj = r.obj; _lock(); return *this; }
|
||||
|
||||
U32 getCRC() { return (obj ? obj->crc : 0); }
|
||||
bool isNull() const { return ((obj == NULL) || (obj->mInstance == NULL)); }
|
||||
operator bool() const { return ((obj != NULL) && (obj->mInstance != NULL)); }
|
||||
T* operator->() { return (T*)obj->mInstance; }
|
||||
T& operator*() { return *((T*)obj->mInstance); }
|
||||
operator T*() { return (obj) ? (T*)obj->mInstance : (T*)NULL; }
|
||||
const T* operator->() const { return (const T*)obj->mInstance; }
|
||||
const T& operator*() const { return *((const T*)obj->mInstance); }
|
||||
operator const T*() const { return (obj) ? (const T*)obj->mInstance : (const T*)NULL; }
|
||||
void unlock();
|
||||
void purge();
|
||||
};
|
||||
|
||||
template<class T> inline void Resource<T>::unlock()
|
||||
{
|
||||
if (obj) {
|
||||
ResourceManager->unlock( obj );
|
||||
obj=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> inline void Resource<T>::purge()
|
||||
{
|
||||
if (obj) {
|
||||
ResourceManager->unlock( obj );
|
||||
if (obj->lockCount == 0)
|
||||
ResourceManager->purge(obj);
|
||||
obj = NULL;
|
||||
}
|
||||
}
|
||||
template <class T> inline void Resource<T>::_lock()
|
||||
{
|
||||
if (obj)
|
||||
obj->lockCount++;
|
||||
}
|
||||
|
||||
template <class T> inline void Resource<T>::_unlock()
|
||||
{
|
||||
if (obj)
|
||||
ResourceManager->unlock( obj );
|
||||
}
|
||||
|
||||
#define INVALID_ID ((U32)(~0))
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Map of Names and Object IDs to objects
|
||||
// Provides fast lookup for name->object, id->object and
|
||||
// for fast removal of an object given object*
|
||||
//
|
||||
class ResDictionary
|
||||
{
|
||||
enum { DefaultTableSize = 1029 };
|
||||
|
||||
ResourceObject **hashTable;
|
||||
S32 entryCount;
|
||||
S32 hashTableSize;
|
||||
DataChunker memPool;
|
||||
S32 hash(StringTableEntry path, StringTableEntry name);
|
||||
S32 hash(ResourceObject *obj) { return hash(obj->path, obj->name); }
|
||||
public:
|
||||
ResDictionary();
|
||||
~ResDictionary();
|
||||
|
||||
void insert(ResourceObject *obj, StringTableEntry path, StringTableEntry file);
|
||||
ResourceObject* find(StringTableEntry path, StringTableEntry file);
|
||||
ResourceObject* find(StringTableEntry path, StringTableEntry file, StringTableEntry filePath, StringTableEntry fileName);
|
||||
ResourceObject* find(StringTableEntry path, StringTableEntry file, U32 flags);
|
||||
void pushBehind(ResourceObject *obj, S32 mask);
|
||||
void remove(ResourceObject *obj);
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class ResManager
|
||||
{
|
||||
private:
|
||||
char writeablePath[1024];
|
||||
char primaryPath[1024];
|
||||
char* pathList;
|
||||
|
||||
ResourceObject timeoutList;
|
||||
ResourceObject resourceList;
|
||||
|
||||
ResDictionary dictionary;
|
||||
bool echoFileNames;
|
||||
|
||||
bool scanZip(ResourceObject *zipObject);
|
||||
|
||||
ResourceObject* createResource(StringTableEntry path, StringTableEntry file);
|
||||
|
||||
ResourceObject* createZipResource(StringTableEntry path, StringTableEntry file, StringTableEntry zipPath, StringTableEntry zipFle);
|
||||
void searchPath(const char *pathStart);
|
||||
|
||||
struct RegisteredExtension
|
||||
{
|
||||
StringTableEntry mExtension;
|
||||
RESOURCE_CREATE_FN mCreateFn;
|
||||
RegisteredExtension *next;
|
||||
};
|
||||
|
||||
RegisteredExtension *registeredList;
|
||||
|
||||
ResManager();
|
||||
public:
|
||||
//Added for displaying dts files
|
||||
ResourceObject* createResource(const char *);
|
||||
|
||||
RESOURCE_CREATE_FN getCreateFunction( const char *name );
|
||||
|
||||
~ResManager();
|
||||
static void create();
|
||||
static void destroy();
|
||||
|
||||
void setFileNameEcho(bool on);
|
||||
void setModPaths(U32 numPaths, const char **dirs);
|
||||
const char* getModPaths();
|
||||
|
||||
void registerExtension(const char *extension, RESOURCE_CREATE_FN create_fn);
|
||||
|
||||
S32 getSize(const char* filename);
|
||||
const char* getFullPath(const char * filename, char * path, U32 pathLen);
|
||||
const char* getModPathOf(const char* fileName);
|
||||
const char* getPathOf(const char * filename);
|
||||
const char* getBasePath();
|
||||
|
||||
ResourceObject* load(const char * fileName, bool computeCRC = false);
|
||||
Stream* openStream(const char * fileName);
|
||||
Stream* openStream(ResourceObject *object);
|
||||
void closeStream(Stream *stream);
|
||||
|
||||
void unlock( ResourceObject* );
|
||||
bool add(const char* name, ResourceInstance *addInstance, bool extraLock = false);
|
||||
|
||||
ResourceObject* find(const char * fileName);
|
||||
ResourceInstance* loadInstance(const char *fileName, bool computeCRC = false);
|
||||
ResourceInstance* loadInstance(ResourceObject *object, bool computeCRC = false);
|
||||
|
||||
ResourceObject* find(const char * fileName, U32 flags);
|
||||
ResourceObject* findMatch(const char *expression, const char **fn, ResourceObject *start = NULL);
|
||||
|
||||
void purge();
|
||||
void purge( ResourceObject *obj );
|
||||
void freeResource(ResourceObject *resObject);
|
||||
void serialize(VectorPtr<const char *> &filenames);
|
||||
|
||||
S32 findMatches( FindMatch *pFM );
|
||||
bool findFile( const char *name );
|
||||
|
||||
bool getCrc(const char * fileName, U32 & crcVal, const U32 crcInitialVal = INITIAL_CRC_VALUE );
|
||||
|
||||
void setWriteablePath(const char *path);
|
||||
bool isValidWriteFileName(const char *fn);
|
||||
|
||||
bool openFileForWrite(FileStream &fs, const char *fileName, U32 accessMode = 1);
|
||||
|
||||
#ifdef DEBUG
|
||||
void dumpLoadedResources();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif //_RESMANAGER_H_
|
||||
Reference in New Issue
Block a user