/* This file is part of Universal Modding Engine. Universal Modding Engine is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Universal Modding Engine 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Universal Modding Engine. If not, see . */ #ifndef uMod_FIELDHANDLER_H_ #define uMod_FIELDHANDLER_H_ #include "..\uMod_GlobalDefines.h" /** * On entry hold the pointer to the fake texture data (file content) or the filename. * * An object is created for each texture to be modded from the server. */ class TextureFileContent { public: TextureFileContent(); ~TextureFileContent(); int AddRef(void) {return ++RefCounter;} int Release(void) {if (--RefCounter==0) {delete this; return 0;} else return RefCounter;} bool ForceReload; //!< to force a reload of the texture (only important, if it is already modded) wchar_t* pFileName; //!< store the texture file name (if available) char* pData; //!< store texture file as file in memory (if available) unsigned int Size; //!< size of file (\a pData) int Reference; //!< for a fast delete in the FileHandler DWORD64 Hash; //!< hash value private: int RefCounter; }; /** * One object holds a pointer to the data (\a TextureFileContent) * and a Reference to all generated fake texture. * * An object is created for each texture to be modded from the server for each client separately. */ class TextureEntry { public: TextureEntry(void); ~TextureEntry(); int AddTexture(IUnknown *tex); int RemoveTexture(IUnknown* tex); void SetContent(TextureFileContent *content); const TextureFileContent * Content() {return TexContent;} TextureFileContent *TexContent; int NumberOfTextures; //!< Number of textures loaded by the game, which match the hash and thus are switched IUnknown **Textures; //!< pointer to all texture loaded by the game, which match the hash and thus are switched; }; /** * A simple vector class for pointers. The Object or struct must have a member variable \a int \a Reference. * This class stores the entries in chunks of memory. The address of each chunk is stored in \a Content. */ template class uMod_TextureHandler { public: uMod_TextureHandler(void); ~uMod_TextureHandler(void); /** * Append an entry at the end of the vector * @param entry * @return RETURN_OK on success */ int Add( T* entry); /** * Remove this entry from the vector * @param entry * @return RETURN_OK on success */ int Remove( T* entry); /** * Returns the number of entries. * @return */ int GetNumber(void) {return (Number);} /** * Return the pointer to the \a i the object * @param i index * @return */ T *operator [] (int i) {if (i<0||i>=Number) return (NULL); else return (Content[i/FieldLength][i%FieldLength]);} private: static const int FieldLength = 1024; //!< size of one chunk of memory long Number; //!< Number of entries. int FieldCounter; //!< Number of allocated chunks. T*** Content;//!< vector of pointers, which point to the chunks }; typedef uMod_TextureHandler uMod_FileHandler; template uMod_TextureHandler::uMod_TextureHandler(void) { Message("uMod_TextureHandler(void): %p\n", this); Number = 0; FieldCounter = 0; Content = NULL; } template uMod_TextureHandler::~uMod_TextureHandler(void) { Message("~uMod_TextureHandler(void): %p\n", this); if (Content!=NULL) { for (int i=0; i int uMod_TextureHandler::Add(T* entry) { //Message("uMod_TextureHandler::Add( %p): %p\n", entry, this); if (gl_ErrorState & uMod_ERROR_FATAL) return (RETURN_FATAL_ERROR); if (entry->Reference>=0) return (RETURN_TEXTURE_ALLREADY_ADDED); if (Number/FieldLength==FieldCounter) { T*** temp = NULL; try {temp = new T**[FieldCounter+10];} catch (...) { gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_TEXTURE; return (RETURN_NO_MEMORY); } for (int i=0; iReference = Number++; return (RETURN_OK); } template int uMod_TextureHandler::Remove(T* entry) //will be called, if a texture is completely released { //Message("uMod_TextureHandler::Remove( %p): %p\n", entry, this); if (gl_ErrorState & uMod_ERROR_FATAL) return (RETURN_FATAL_ERROR); int ref = entry->Reference; if (ref<0|| ref>=Number) return (RETURN_OK); // it is not in this list if (Content[ref/FieldLength][ref%FieldLength]!=entry) return (RETURN_OK); // it is not in this list if (ref<(--Number)) { Content[ref/FieldLength][ref%FieldLength] = Content[Number/FieldLength][Number%FieldLength]; Content[ref/FieldLength][ref%FieldLength]->Reference = ref; } entry->Reference = -1; return (RETURN_OK); } #endif /* uMod_FIELDHANDLER_H_ */