00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FIFE_RESOURE_PTR_H
00023 #define FIFE_RESOURE_PTR_H
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "resource.h"
00034 #include "pool.h"
00035
00036 namespace FIFE {
00037
00040 class ResourcePtr {
00041 public:
00042 ResourcePtr(IResource* ptr = 0) : m_ptr(ptr),m_pool(0),m_index(Pool::INVALID_ID) {
00043 if( m_ptr )
00044 m_ptr->addRef();
00045 }
00046
00047 ResourcePtr(Pool* pool,int index) : m_ptr(0),m_pool(pool),m_index(index) {
00048 }
00049
00050 ResourcePtr(const ResourcePtr& r)
00051 : m_ptr(r.m_ptr),m_pool(r.m_pool),m_index(r.m_index) {
00052 if(m_ptr) {
00053 m_ptr->addRef();
00054 }
00055 }
00056
00057 ResourcePtr& operator=(const ResourcePtr& r) {
00058 if( this == &r )
00059 return *this;
00060 release();
00061 m_ptr = r.m_ptr;
00062 m_pool = r.m_pool;
00063 m_index = r.m_index;
00064 if(m_ptr) {
00065 m_ptr->addRef();
00066 }
00067 return *this;
00068 }
00069
00070 ~ResourcePtr() {
00071 release();
00072 }
00073
00074 IResource& operator->() {
00075 load();
00076 return *m_ptr;
00077 }
00078
00079 const IResource& operator->() const {
00080 constLoad();
00081 return *m_ptr;
00082 }
00083
00084 operator bool() const {
00085 return isValid();
00086 }
00087
00088 bool isValid() const {
00089 return m_ptr || isLoadable();
00090 }
00091
00092 bool isLoadable() const {
00093 return m_pool && m_index != Pool::INVALID_ID;
00094 }
00095
00096 bool operator==(const ResourcePtr& r) const {
00097 if( isLoadable() && r.isLoadable() )
00098 return m_index == r.m_index && m_pool == r.m_pool;
00099 if( !isLoadable() && !r.isLoadable() )
00100 return m_ptr == r.m_ptr;
00101 return false;
00102 }
00103
00104 bool operator<(const ResourcePtr& r) const {
00105 if( isLoadable() && r.isLoadable() )
00106 {
00107 if( m_pool == r.m_pool )
00108 return m_index < r.m_index;
00109 return m_pool < r.m_pool;
00110 }
00111 if( !isLoadable() && !r.isLoadable() )
00112 return m_ptr < r.m_ptr;
00113 return isLoadable() < r.isLoadable();
00114 }
00115
00116 void release() {
00117 if(m_ptr) {
00118 m_ptr->decRef();
00119 }
00120 m_ptr = 0;
00121 }
00122
00123 void load() {
00124 constLoad();
00125 }
00126
00127 void unload() {
00128 release();
00129 if( isLoadable() ) {
00130 m_pool->release(m_index);
00131 }
00132 }
00133
00134 template<class T>
00135 T* get() {
00136 if( isValid() )
00137 load();
00138 return dynamic_cast<T*>(m_ptr);
00139 }
00140
00141 private:
00142 void constLoad() const {
00143 if( m_ptr )
00144 return;
00145 m_ptr = &m_pool->get(m_index);
00146 m_ptr->addRef();
00147 }
00148 mutable IResource* m_ptr;
00149 Pool* m_pool;
00150 int m_index;
00151 };
00152 }
00153 #endif
00154