ResourcePtr.h

00001 /***************************************************************************
00002  *                                                                         *
00003  *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
00004  *       mailto: <tevs@mpi-sb.mpg.de>                                      *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU General Public License as published by  *
00008  *   the Free Software Foundation; either version 2 of the License, or     *
00009  *   (at your option) any later version.                                   *
00010  *                                                                         *
00011  ***************************************************************************/
00012 
00013 
00014 #ifndef _NR_RESOURCE_POINTER_H_
00015 #define _NR_RESOURCE_POINTER_H_
00016 
00017 
00018 
00019 //----------------------------------------------------------------------------------
00020 // Includes
00021 //----------------------------------------------------------------------------------
00022 #include "Prerequisities.h"
00023 #include "Exception.h"
00024 #include "Log.h"
00025 
00026 namespace nrEngine{
00027 
00028         //! Base untemplated class for resource pointers
00029         /**
00030         * This is a base class for resource pointers. You can use this pointers as
00031         * normal pointers, except you can not use new,delete functions.
00032         * We need this base class which is not templated to implement converting
00033         * functions in derived classes
00034         * @note We do not have any public constructors or destructors. This will prevent
00035         *                you by using the resource management system in the wrong way. You have
00036         *                to use manager before you can use the pointers to resources. This will
00037         *                give the nrEngine the safety of using its resource management system.
00038         * \ingroup resource
00039         **/
00040         class _NRExport IResourcePtr{
00041                 public:
00042 
00043                         /**
00044                         * Copy constructor
00045                         **/
00046                         IResourcePtr(const IResourcePtr& resPtr);
00047 
00048                         /**
00049                         * Create an empty resource pointer, that do not point to anywhere
00050                         **/
00051                         IResourcePtr()
00052                         {
00053                                 mHolder.reset();
00054                         }
00055 
00056                         /**
00057                         * Virtual destructor
00058                         **/
00059                         virtual ~IResourcePtr()
00060                         {
00061                                 mHolder.reset();
00062                         };
00063 
00064                         /**
00065                         * Check if the given pointer is the same as this one.
00066                         * @note Two pointers are the same, if they showing to the same resource, and
00067                         *                if their holders are the same or if
00068                         *                both pointers points to NULL. If one of the pointers is an empty pointer,
00069                         *                so also false will be returned.
00070                         **/
00071                         virtual bool operator==(IResourcePtr& res) const;
00072 
00073 
00074                         /**
00075                         * Check equality to normal pointers.
00076                         **/
00077                         virtual bool operator==(const IResource* p) const;
00078 
00079 
00080                         /**
00081                         * Check whenver two pointers are not the same.
00082                         * @see operator==
00083                         **/
00084                         virtual bool operator!=(IResourcePtr& res) const;
00085 
00086 
00087                         /**
00088                         * Check whenver two pointers are not the same.
00089                         * @see operator==
00090                         **/
00091                         virtual bool operator!=(const IResource* res) const;
00092 
00093 
00094                         /**
00095                         * Check whenever this pointer is NULL - does not contain data
00096                         **/
00097                         NR_FORCEINLINE bool isNull()const {
00098                                 return (mHolder.get() == NULL);
00099                         }
00100 
00101                         /**
00102                          * Check whenever the pointer contains valid data. The method
00103                          * if opossite to isNull()
00104                          **/
00105                         NR_FORCEINLINE bool valid()const {
00106                                 return (mHolder.get() != NULL);
00107                         }
00108 
00109                         /**
00110                         * Lock the resource to which one this pointer points, to prevent using
00111                         * of empty resource. See more information about locking of real resources
00112                         * in the documentation about ResourceManager::lockPure() or
00113                         * ResourceHolder::lockPure()
00114                         * @return either OK or:
00115                         *       - RES_PTR_IS_NULL if this pointer is null
00116                         *       - RES_LOCK_STATE_STACK_IS_FULL if we are not able to lock anymore
00117                         **/
00118                         Result lockResource();
00119 
00120 
00121                         /**
00122                         * Unlock the resource to which one this pointer points, to prevent using
00123                         * of empty resource. See more information about locking of real resources
00124                         * in the documentation about ResourceManager::unlockpure()
00125                         * @return either OK or RES_PTR_IS_NULL if this pointer is null
00126                         **/
00127                         Result unlockResource();
00128 
00129 
00130                         /**
00131                         * Lock an empty resource, so that even if resource is loaded, empty resource will
00132                         * be used.
00133                         * @see lockPure()
00134                         **/
00135                         Result lockEmpty();
00136                         
00137                         /**
00138                         * Unlock empty resource
00139                         **/
00140                         Result unlockEmpty();
00141                         
00142                         /**
00143                         * Access to the resource to which one this pointer points. This access need
00144                         * 1 static_cast, 3 function calls until it returns the resource.
00145                         * So this function is running in O(1) and is pretty efficient
00146                         **/
00147                         IResource* getBase() const;
00148 
00149 
00150                         /**
00151                         * Access to the resource to which one this pointer points. This access need
00152                         * 1 static_cast, 3 function calls until it returns the resource.
00153                         * So this function is running in O(1) and is pretty efficient
00154                         **/
00155                         //virtual IResource& operator*() const;
00156 
00157                 protected:
00158 
00159                         //! Resource Manager is a friend, so it can freely work with this pointers
00160                         friend class IResourceLoader;
00161 
00162                         //! Also resource manager is a friend
00163                         friend class ResourceManager;
00164 
00165                         //! Shared pointer holding the holder of the resource
00166                         SharedPtr<ResourceHolder> mHolder;
00167 
00168                         /**
00169                         * Get the holder to which one this pointer shows
00170                         **/
00171                         NR_FORCEINLINE SharedPtr<ResourceHolder> getResourceHolder() const
00172                         {
00173                                 return mHolder;
00174                         }
00175 
00176                         /**
00177                         * Create an instance of the resource pointer. This pointer is pointing
00178                         * to the resource stored by the holder. The constructor is private, so you
00179                         * can not use the new function to create the pointer.
00180                         **/
00181                         IResourcePtr(SharedPtr<ResourceHolder> holder)
00182                         {
00183                                 mHolder = holder;
00184                         }
00185 
00186 
00187         };
00188 
00189 
00190 
00191         //! Resource pointer is a smart pointer pointing to the resource
00192         /**
00193         * This is a smart pointer that can be used to access resources manages by the
00194         * resource manager. This pointer will automaticly be pointing to empty resource
00195         * if the resource was unloaded by the manager.
00196         *
00197         * You can create more than one resource pointer to a resource. Each access to such
00198         * a resource through the manager will create a new one for you. However the pointers
00199         * are pointing to one resource holder. Each resource holder is controlled/managed
00200         * by the manager. So if you for example unload a resource to which one you has pointers,
00201         * the manager will replace the resource holding by the holder with empty one. So if
00202         * you try to access the resource you can still access them, but they are empty.
00203         * Our systems also allows you to delete the manager from the memory, but the pointers
00204         * will stay valid. So you can also remove the manager after you loaded all resources.
00205         * However you can then do not manage the resources, so this is a way you should <b>not</b>
00206         * do it !!!
00207         *
00208         * @note We do not have any public constructors or destructors. This will prevent
00209         *                you by using the resource management system in the wrong way. You have
00210         *                to use manager before you can use the pointers to resources. This will
00211         *                give the nrEngine the safety of using its resource management system.
00212         *
00213         * \ingroup resource
00214         **/
00215         template<typename ResType>
00216         class _NRExport ResourcePtr: public IResourcePtr{
00217                 public:
00218 
00219                         /**
00220                          * Create an empty resource pointer. Such a pointer
00221                          * does not point to anything. So using of not initialized
00222                          * pointers will give you an exception
00223                          **/
00224                         ResourcePtr() : IResourcePtr() {}
00225 
00226                         /**
00227                         * Copy constructor to allow copying from base class
00228                         **/
00229                         ResourcePtr(const IResourcePtr& res) : IResourcePtr(res){}
00230                         
00231                         /**
00232                         * Access to the resource to which one this pointer points. This access need
00233                         * 1 static_cast, 3 function calls until it returns the resource.
00234                         * So this function is running in O(1) and is pretty efficient
00235                         **/
00236                         NR_FORCEINLINE ResType* operator->() const
00237                         {
00238                                 ResType* ptr = dynamic_cast<ResType*>(IResourcePtr::getBase());
00239                                 if (ptr == NULL)
00240                                 {
00241                                         NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourcePtr<%s> cannot cast from IResource", getBase()->getResourceName().c_str());
00242                                         NR_ASSERT(ptr != NULL && "The resource has wrong type");
00243                                 }
00244                                 return ptr;
00245                         }
00246 
00247 
00248                         /**
00249                         * Get the object stored by this pointer.
00250                         * NOTE: The instance is controlled by the pointer, so do not delete it
00251                         **/
00252                         NR_FORCEINLINE ResType* get()
00253                         {
00254                                 return operator->();
00255                         }
00256 
00257                         /**
00258                         * Access to the resource to which one this pointer points. This access need
00259                         * 1 static_cast, 3 function calls until it returns the resource.
00260                         * So this function is running in O(1) and is pretty efficient
00261                         **/
00262                         NR_FORCEINLINE ResType& operator*() const
00263                         {
00264                                 return *(operator->());
00265                         }
00266         };
00267 
00268 };
00269 #endif

Generated on Wed Sep 12 23:19:42 2007 for nrEngine by  doxygen 1.5.1