Sleeping Wombat Graphic API  1.010
swGraphicAPI
ResourceContainer.h
Go to the documentation of this file.
1 #pragma once
2 
11 //#include "swCommonLib/Common/System/Path.h"
14 
15 #include <map>
16 #include <vector>
17 #include <type_traits>
18 
19 #include "swGraphicAPI/Resources/ResourcePtr.h"
20 
21 
29 template < class TYPE >
31 {
32  friend class AssetsManager;
33  friend class ResourceManager;
34 private:
35  unsigned int count;
36 
37 protected:
38  std::map<std::wstring, TYPE*> container;
39 
40  // Kasowanie obiektów
41  int ForceRemove ( const std::wstring& name );
42  int ForceRemove ( unsigned int id );
43  void ForceRemoveAll ();
44  void ReleaseMemory ( TYPE* );
45 public:
48 
49  // Kasowanie obiektów
50  int Remove ( const std::wstring& name );
51  int Remove ( unsigned int id );
52  int RemoveUnused ();
53 
54  // Dodawanie obiektów
55  void UnsafeAdd ( const std::wstring& name, TYPE* resource );
56 
57  // Dostęp do obiektów
58  TYPE* get ( unsigned int id );
59  inline unsigned int GetNextId() { return count; }
60 
64  inline TYPE* get( const std::wstring& name )
65  {
66  auto iter = container.find( name );
67  if ( iter != container.end() )
68  return iter->second;
69  return nullptr;
70  }
71 
78  template< typename DescType >
79  TYPE* Find ( const DescType& desc );
80 
81  // Listowanie obiektów.
82  std::vector< ResourcePtr< TYPE > > List();
83 };
84 
85 template <class TYPE>
87 {
88  count = 1;
89 }
90 
92 template <class TYPE>
94 {
95  for ( auto iter = container.begin( ); iter != container.end( ); iter++ )
96  {
97  ReleaseMemory( iter->second );
98  }
99  container.clear();
100 }
101 
108 template <class TYPE>
109 TYPE* ResourceContainer<TYPE>::get ( unsigned int id )
110 {
111  for ( auto iter = container.begin(); iter != container.end(); iter++ )
112  {
113  if ( iter->second->GetID() == id )
114  return iter->second;
115  }
116  return nullptr;
117 }
118 
119 // ================================ //
120 //
121 template< class TYPE >
122 template< typename DescType >
123 inline TYPE* ResourceContainer< TYPE >::Find ( const DescType& desc )
124 {
125  static_assert( std::is_member_function_pointer< decltype( &TYPE::GetDescriptor ) >::value, "TYPE must implement GetDescriptor function." );
126 
127  for( auto& resource : container )
128  {
129  if( resource.second->GetDescriptor() == desc )
130  return resource.second;
131  }
132  return nullptr;
133 }
134 
135 
136 //-------------------------------------------------------------------------------//
137 // dodawanie obiektów
138 //-------------------------------------------------------------------------------//
139 
140 /*Dodaje element do kontanera + nadaje mu unikalny identyfikator.
141 Jeżeli element już istniał, to po prostu nie zostanie wstawiony, dlatego
142 przed uzyciem warto pobrać element o danej nazwie, żeby sprawdzić
143 czy dodawanie jest konieczne.*/
144 // Może kiedyś zrobie wstawianie ze sprawdzaniem, na razie nie wydaje się potrzebne
145 
146 
154 template <class TYPE>
155 void ResourceContainer<TYPE>::UnsafeAdd( const std::wstring& name, TYPE* resource )
156 {
157  if ( !resource )
158  return; //Nie możemy potem ustawić id
159 
160  container[name] = resource;
161 
162  resource->SetID( count );
163  ++count; // Inkrementujemy licznik
164 }
165 
166 //-------------------------------------------------------------------------------//
167 // kasowanie obiektów
168 //-------------------------------------------------------------------------------//
177 template <class TYPE>
179 {
180  // Destruktor jest prywatny, więc nie możemy kasować obiektu bezpośrednio.
181  ObjectDeleterKey<TYPE> key; // Tworzymy klucz.
182  ObjectDeleter<TYPE> model_deleter( key ); // Tworzymy obiekt kasujący i podajemy mu nasz klucz.
183  model_deleter.delete_object( object ); // Kasujemy obiekt za pośrednictwem klucza.
184 }
185 
193 template <class TYPE>
194 int ResourceContainer<TYPE>::Remove( const std::wstring& name )
195 {
196  auto iter = container.find( name );
197  if ( iter != container.end() )
198  return -1; // Nie znaleźliśmy elementu
199 
200  if ( !iter->second->CanDelete() )
201  return 1; // Nie możemy skasować, bo są odwołania
202 
203  ReleaseMemory( iter->second ); // Zwalniamy pamięć spod wskaźnika
204  container.erase( iter ); // Kasujemy element z mapy
205 
206  return 0; // Wychodzimy z powodzeniem
207 }
208 
209 
217 template <class TYPE>
218 int ResourceContainer<TYPE>::Remove( unsigned int id )
219 {
220  for ( auto iter = container.begin( ); iter != container.end( ); iter++ )
221  {
222  if ( iter->second->GetID() == id )
223  {
224  // Sprawdzamy czy nie ma jakichś odwołań do obiektu
225  if ( !iter->second->CanDelete() )
226  return 1; // Są odwołania, więc nie kasujemy
227 
228  ReleaseMemory( iter->second ); // Zwalniamy pamięć spod wskaźnika
229  container.erase( iter ); // Kasujemy element z mapy
230 
231  return 0; // Zwracamy 0 jako powodzenie operacji
232  }
233  }
234  return -1; // Nie znaleźliśmy elementu
235 }
236 
241 template <class TYPE>
243 {
244  int count = 0;
245  for ( auto iter = container.begin(); iter != container.end(); iter++ )
246  {// Iterujemy po całej mapie
247  if ( iter->second->CanDelete() )
248  {
249  // Możemy skasować obiekt, bo nikt go nie używa
250  ReleaseMemory( iter->second ); // Zwalniamy pamięć spod wskaźnika
251  container.erase( iter ); // Kasujemy element z mapy
252 
253  ++count;
254  }
255  }
256 
257  return count;
258 }
259 
260 
267 template <class TYPE>
268 int ResourceContainer<TYPE>::ForceRemove( const std::wstring& name )
269 {
270  auto iter = container.find( name );
271  if ( iter != container.end( ) )
272  return -1; // Nie znaleźliśmy elementu
273 
274  delete iter->second; // Zwalniamy pamięć spod wskaźnika
275  return 0;
276 }
277 
284 template <class TYPE>
286 {
287  for ( auto iter = container.begin( ); iter != container.end( ); iter++ )
288  {
289  if ( iter->second->GetID( ) == id )
290  {
291  delete iter->second; // Zwalniamy pamięć spod wskaźnika
292  return 0;
293  }
294  }
295  return -1; // Nie znaleziono elementu
296 }
297 
300 template <class TYPE>
302 {
303  for ( auto iter = container.begin(); iter != container.end(); iter++ )
304  {// Iterujemy po całej mapie
305  delete iter->second; // Zwalniamy pamięć spod wskaźnika
306  }
307  container.clear();
308 }
309 
311 template< class TYPE >
312 inline std::vector< ResourcePtr< TYPE > > ResourceContainer< TYPE >::List()
313 {
314  std::vector< ResourcePtr< TYPE > > resourcesList;
315  resourcesList.reserve( container.size() );
316 
317  for( auto iter = container.begin(); iter != container.end(); iter++ )
318  {
319  resourcesList.push_back( ResourcePtr< TYPE >( iter->second ) );
320  }
321 
322  return resourcesList;
323 }
324 
std::map< std::wstring, TYPE * > container
Kontener zawierający assety powiazane z ich nazwą
Definition: ResourceContainer.h:38
unsigned int count
Indentyfikator jaki zostanie przydzielony kolejnemy elementowi.
Definition: ResourceContainer.h:35
void ForceRemoveAll()
Kasuje wszystkie elementy niezależnie od tego czy były używane, a następnie czyści mapę...
Definition: ResourceContainer.h:301
Szablon klasy do przechowywania assetów.
Definition: ResourceContainer.h:30
Wrapper for low level resources and high level assets.
Definition: ResourcePtr.h:18
TYPE * get(unsigned int id)
Zwraca element na podstawie identyfikatora.
Definition: ResourceContainer.h:109
int RemoveUnused()
Kasuje wszystkie elementy w kontenerze, które nie są używane przez żaden obiekt. Kasowanie jest w peł...
Definition: ResourceContainer.h:242
void ReleaseMemory(TYPE *)
Zwalnia obiekt podany w parametrze.
Definition: ResourceContainer.h:178
int ForceRemove(const std::wstring &name)
Wymusza skasowanie podanego elementu, nawet jeżeli jest używany.
Definition: ResourceContainer.h:268
~ResourceContainer()
Destruktor zwalnia wszystkie elementy w mapie (także pamięć po nich)
Definition: ResourceContainer.h:93
int Remove(const std::wstring &name)
Usuwa element o podanej nazwie, jeżeli nie ma do niego odwołań.
Definition: ResourceContainer.h:194
TYPE * Find(const DescType &desc)
Finds resource matching given descriptor.
Definition: ResourceContainer.h:123
void UnsafeAdd(const std::wstring &name, TYPE *resource)
Dodaje element do kontanera + nadaje mu unikalny identyfikator.
Definition: ResourceContainer.h:155
std::vector< ResourcePtr< TYPE > > List()
Listuje wszystkie assety danego typu.
Definition: ResourceContainer.h:312
unsigned int GetNextId()
Zwraca identyfikator, który zostanie przydzielony kolejnemu elementowi.
Definition: ResourceContainer.h:59
Manager for low level resources.
Definition: ResourceManager.h:24