00001 #ifndef MERCURYTEXTUREMANAGER_H
00002 #define MERCURYTEXTUREMANAGER_H
00003
00004 #include "MercuryString.h"
00005 #include "MercuryTexture.h"
00006 #include "MercuryUtil.h"
00007 #include "MercuryFiles.h"
00008 #include "MercuryThreads.h"
00009 #include "MercuryCallback.h"
00010 #include "MercuryMessages.h"
00011 #include "MercuryTexture.h"
00012
00013 using namespace std;
00014
00016 class TextureID
00017 {
00018 public:
00019 ~TextureID();
00020 TextureID(const MString& path, bool loadPending = false);
00021 bool RemoveTexturePtr(const MercuryTexture* texture);
00022 void UpdateTextureData(MercuryTexture* texture);
00023 void CreateCache(MercuryTexture* texture);
00024
00025 unsigned int m_ID;
00026 MVector<const MercuryTexture*> m_textures;
00027
00028 ImageAttrs m_attrs;
00029 MString m_path;
00030 bool m_loadPending;
00031 };
00032
00034 class MercuryTextureManager : public MercuryMessageHandler
00035 {
00036 struct ThreadLoadData
00037 {
00038 ThreadLoadData(const MString& p, const MercuryTexture* t, RawImageData* data = NULL)
00039 :path(p), texture(t), d(data)
00040 {}
00041 MString path;
00042 const MercuryTexture* texture;
00043 RawImageData* d;
00044 };
00045 public:
00046 MercuryTextureManager();
00047 virtual ~MercuryTextureManager();
00048
00049 static MercuryTexture* CreateTexture(const MString& path);
00050
00051 virtual void Message( int Message, PStack & data, const MString & name );
00052
00053 void CreateThread();
00054 void ThreadLoop();
00055
00056 void UpdateTexture(MercuryTexture* texture);
00057 void Remove(MercuryTexture* texture);
00058 void Update( const float dTime );
00059 bool IsTexture(const MercuryTexture* texture);
00060
00061 inline unsigned int TextureCount() const { return m_textureCount; }
00062 inline unsigned int UniqueTextureCount() const { return MLockPtr< map<MString, TextureID*> >(m_textureMap, m_mtxMap)->size(); }
00063 TextureID* FindTexture(const MString& path) const;
00064 TextureID* FindTexture(const MercuryTexture* texture) { return FindTexture(texture->GetPath()); }
00065 private:
00066 void Remove(const MString& path, const MercuryTexture* texture);
00067 void ProcessLoadQueue();
00068 void ProcessFinalizeQueue();
00069
00070 bool TryFromExisting(ThreadLoadData* tld);
00071
00072 TextureID* RegisterNewTexture(const MercuryTexture* t, RawImageData* d, const MString& path);
00073 RawImageData * LoadDyn( const MString & sFullName, MString & sShortName );
00074 RawImageData * LoadCube( const MString & sFullName, MString & sShortName );
00075 RawImageData * LoadDynShadow( const MString & sFullName, MString & sShortName );
00076 RawImageData * LoadDynCube( const MString & sFullName, MString & sShortName );
00077
00078 RawImageData* ImageLoader(const MString& path);
00079
00080 unsigned int m_textureCount;
00081 volatile map<MString, TextureID*> m_textureMap;
00082
00083 volatile MDeque<ThreadLoadData*> m_loadQueue;
00084 volatile MDeque<ThreadLoadData*> m_finalizeLoadQueue;
00085
00086 MercuryThread m_thread;
00087
00088 MercuryMutex m_mtxLoadQueue;
00089 MercuryMutex m_mtxMap;
00090 MercuryMutex m_mtxFinalize;
00091 };
00092
00093
00094 extern MercuryTextureManager* TEXTMAN;
00095
00096 typedef RawImageData * (*ImageDecoder)( MercuryFile * );
00097
00098 class MercuryImageReaderRegister
00099 {
00100 public:
00101 void CheckInit();
00102 void AddDecoder( ImageDecoder, const char * sFingerPrint );
00103 RawImageData * Decode( MercuryFile * f );
00104 private:
00105 bool bInit;
00106 MHash< ImageDecoder > * m_hDecoders;
00107 };
00108
00109 extern MercuryImageReaderRegister IMAGEREADERREGISTER;
00110
00111 #endif
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139