// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef NL_SHAPE_BANK_H #define NL_SHAPE_BANK_H #include "nel/3d/shape.h" #include "nel/misc/smart_ptr.h" #include #include #include "nel/3d/async_file_manager_3d.h" namespace NLMISC { class IProgressCallback; } namespace NL3D { class IDriver; class ITexture; // *************************************************************************** /** * A CShapeBank handle all the instance of the shapes and the cache management * system. * There is a default cache. If the shape is not linked explicitly to any cache * it is linked to the default cache. The comportement of this cache is to not * do any cache. When the release is called on the last reference to a shape * linked to this cache, the shape is removed instantly. This is the behavior * of all newly created cache before we call the setShapeCacheSize method. * * NB: ShapeCacheName is case-sensitive but shapeName are not (all entry are lwrcased) * * \author Matthieu Besson * \author Nevrax France * \date 2000 */ class CShapeBank { public: /// \name State of a shape //@{ /** NotPresent : Not present in the bank * Present : Present in the bank and ready to be used * AsyncLoad_Error : Asynchronous loading failed * AsyncLoad_Shape : Asynchronous loading is currently loading the .shape file, textures and lightmaps * AsyncLoad_Texture : Asynchronous loading is currently uploading textures and lightmaps to VRAM */ enum TShapeState { NotPresent, Present, AsyncLoad_Error, AsyncLoad_Shape, AsyncLoad_Texture, AsyncLoad_Ready, AsyncLoad_Delete }; //@} CShapeBank(); ~CShapeBank(); /// \name Instance Management //@{ /// Add a reference to a shape and return the instance created. NB: getPresentState()==Present must be tested first. IShape* addRef (const std::string &shapeName); /** * Release a reference to a shape by its instance. If the shape has no more reference it is added to * its own shape cache. When the shape cache is full the last entry is deleted. */ void release (IShape* pShp); /// Return the shape state. Process the waiting shapes. TShapeState getPresentState (const std::string &shapeName); /** Return the IShape from the bank. Unlike addRef, no reference is added. * Thus the returning shape sould be used temporarily * \return NULL if shape not found or not loaded (if being async loaded still return NULL) */ IShape *getShape (const std::string &shapeName); /// Load the corresponding file from disk and add it to the bank. void load (const std::string &shapeName); /** Load the corresponding file from disk asynchronously and add it to the bank. * The driver passed to this function is used to know if we have to load the textures. */ void loadAsync (const std::string &shapeName, IDriver *pDriver, const NLMISC::CVector &position, bool *bSignal, uint selectedTexture); void cancelLoadAsync (const std::string &shapeName); bool isShapeWaiting (); /// processWaitingShapes must be done one time per frame void processWaitingShapes (); /// Setup the maximum number of bytes to upload for a frame (texture upload from RAM to VRAM) void setMaxBytesToUpload (uint32 MaxUploadPerFrame); /// Add directly a shape to the bank. If the shape name is already used do nothing. void add (const std::string &shapeName, IShape* shape); //@} /// \name Shape cache management //@{ /// Add a new ShapeCache. If already exist do nothing. void addShapeCache (const std::string &shapeCacheName); /** * Remove a ShapeCache. All shapes in the shape cache are deleted. All links are redirected to * the default ShapeCache */ void removeShapeCache (const std::string &shapeCacheName); /// true if the shape cache exist bool isShapeCache(const std::string &shapeCacheName) const; /** * Remove all ShapeCache and suppress all links (even the link to the default cache are removed) */ void reset (); /// Set the shapeCache shapeCacheName the new size.(delete shapes if maxsize &listFile, const std::string &wildCardNotLwr, NLMISC::IProgressCallback *progress = NULL, bool flushTextures = false, IDriver *drv = NULL); /** Mark this shape name as needing a buildSystemGeometry() (typically used for selection) * NB: this will take effect only for shapes on a subsequent add(), load() or loadAsync() */ void buildSystemGeometryForshape(const std::string &shapeName); // @} // get the shape Name from the shape Ptr. return NULL if not found const std::string* getShapeNameFromShapePtr(IShape* pShp) const; private: /// \name Shape/Instances. //@{ typedef NLMISC::CSmartPtr PShape; typedef std::map TShapeMap; TShapeMap ShapeMap; struct CWaitingShape { IShape *ShapePtr; // Do not work with this value that is shared between threads uint32 RefCnt; // Counter if multiple instance wants the same shape TShapeState State; // State of the waiting shape (shape in loading mode) std::set Signal; // To signal when all is done // Upload piece by piece part uint32 UpTextProgress; // Upload Texture progress current texture or lightmap uint8 UpTextMipMap; // Upload Texture progress current mipmap uint32 UpTextLine; // Upload Texture progress current line in mipmap // --------------------------------- CWaitingShape () { State = AsyncLoad_Shape; RefCnt = 0; ShapePtr = NULL; UpTextProgress = 0; UpTextMipMap = 0; UpTextLine = 0; } }; typedef std::map< std::string, CWaitingShape > TWaitingShapesMap; TWaitingShapesMap WaitingShapes; uint32 _MaxUploadPerFrame; private: /// return true if the texture is entirely uploaded bool processWSUploadTexture (CWaitingShape &rWS, uint32 &nTotalUploaded, ITexture *pText); private: IDriver *_pDriver; //@} /// \name Shape/Caches. //@{ struct CShapeCache { std::list Elements; sint32 MaxSize; CShapeCache() { MaxSize = 0; } }; struct CShapeInfo { CShapeCache* pShpCache; std::string sShpName; bool isAdded; CShapeInfo() { isAdded = false; pShpCache = NULL; } }; private: IShape* getShapePtrFromShapeName(const std::string &pShpName); CShapeCache* getShapeCachePtrFromShapePtr(IShape* pShp); CShapeCache* getShapeCachePtrFromShapeCacheName(const std::string &shapeCacheName); CShapeCache* getShapeCachePtrFromShapeName(const std::string &shapeName); void checkShapeCache(CShapeCache* pShpCache); typedef std::map TShapeCacheNameMap; typedef std::map TShapeCacheMap; typedef std::map TShapeInfoMap; TShapeCacheNameMap ShapeNameToShapeCacheName; TShapeCacheMap ShapeCacheNameToShapeCache; TShapeInfoMap ShapePtrToShapeInfo; // Special for buildSystemGeometryForshape std::set _ShapeNeedingSystemGeometryCopy; //@} }; } #endif // NL_SHAPE_BANK_H /* End of shape_bank.h */