Subversion Repositories gelsvn

Rev

Rev 448 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 448 Rev 595
-
 
1
/* ----------------------------------------------------------------------- *
-
 
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
-
 
3
 * Copyright (C) the authors and DTU Informatics
-
 
4
 * For license and list of authors, see ../../doc/intro.pdf
-
 
5
 * ----------------------------------------------------------------------- */
-
 
6
 
-
 
7
/**
-
 
8
 * @file ResourceManager.h
-
 
9
 * @brief Resource manager that is not used much in GEL but potentially useful for larger projects.
-
 
10
 */
-
 
11
 
1
#ifndef __UTIL_RESOURCE_MANAGER_H
12
#ifndef __UTIL_RESOURCE_MANAGER_H
2
#define __UTIL_RESOURCE_MANAGER_H
13
#define __UTIL_RESOURCE_MANAGER_H
3
 
14
 
4
#include <cassert>
15
#include <cassert>
5
#include <string>
16
#include <string>
6
#include <list>
17
#include <list>
7
#include <typeinfo>
18
#include <typeinfo>
8
 
19
 
9
#define CLEAN_SHUTDOWN 1
20
#define CLEAN_SHUTDOWN 1
10
 
21
 
11
namespace Util
22
namespace Util
12
{
23
{
13
 
24
 
14
	typedef unsigned char FlagByte;
25
	typedef unsigned char FlagByte;
15
	const FlagByte REMOVE_WHEN_UNUSED = 0x01;
26
	const FlagByte REMOVE_WHEN_UNUSED = 0x01;
16
	const FlagByte STATIC_RESOURCE    = 0x02;
27
	const FlagByte STATIC_RESOURCE    = 0x02;
17
 
28
 
18
	/** \brief This class template represents a resource record. 
29
	/** \brief This class template represents a resource record. 
19
 
30
 
20
	    There is a pointer to 
31
	    There is a pointer to 
21
			the actual resource (of type RES) and a usage counter which should never
32
			the actual resource (of type RES) and a usage counter which should never
22
			be less than 0. */
33
			be less than 0. */
23
	template<class RES>
34
	template<class RES>
24
	class ResourceRecord
35
	class ResourceRecord
25
	{
36
	{
26
		/// Name of the resource (const)
37
		/// Name of the resource (const)
27
    const std::string name;
38
    const std::string name;
28
 
39
 
29
		/// A pointer to the resource (the pointer not the pointee is const)
40
		/// A pointer to the resource (the pointer not the pointee is const)
30
		RES * const res;
41
		RES * const res;
31
		
42
		
32
		/// Usage counter.
43
		/// Usage counter.
33
		int usage;
44
		int usage;
34
 
45
 
35
		/// Flags
46
		/// Flags
36
		FlagByte flags;
47
		FlagByte flags;
37
 
48
 
38
	public:
49
	public:
39
	
50
	
40
		/// Construct a null record.
51
		/// Construct a null record.
41
		ResourceRecord(): res(0), usage(0), flags(0) {}
52
		ResourceRecord(): res(0), usage(0), flags(0) {}
42
 
53
 
43
		/// Construct a resource record with a name and a pointer.
54
		/// Construct a resource record with a name and a pointer.
44
		ResourceRecord(const std::string& _name, RES* _res, bool static_res=false): 
55
		ResourceRecord(const std::string& _name, RES* _res, bool static_res=false): 
45
			name(_name), 
56
			name(_name), 
46
			res(_res), 
57
			res(_res), 
47
			usage(0), 
58
			usage(0), 
48
			flags(static_res ? STATIC_RESOURCE : 0) 
59
			flags(static_res ? STATIC_RESOURCE : 0) 
49
		{
60
		{
50
			assert(res != 0);
61
			assert(res != 0);
51
		}
62
		}
52
 
63
 
53
		~ResourceRecord() 
64
		~ResourceRecord() 
54
		{
65
		{
55
#if CLEAN_SHUTDOWN
66
#if CLEAN_SHUTDOWN
56
			assert(usage==0);		
67
			assert(usage==0);		
57
#endif
68
#endif
58
		}
69
		}
59
	
70
	
60
		void erase_resource()
71
		void erase_resource()
61
		{
72
		{
62
			assert(usage==0);
73
			assert(usage==0);
63
			if(!(flags&STATIC_RESOURCE)) 
74
			if(!(flags&STATIC_RESOURCE)) 
64
				{
75
				{
65
					delete res;
76
					delete res;
66
				}
77
				}
67
		}
78
		}
68
 
79
 
69
		/// Increment the usage counter
80
		/// Increment the usage counter
70
		void increment_usage() 
81
		void increment_usage() 
71
		{
82
		{
72
			assert(usage>=0);
83
			assert(usage>=0);
73
			++usage;
84
			++usage;
74
		}
85
		}
75
 
86
 
76
		/// Decrement the usage counter. assert that counter is >0
87
		/// Decrement the usage counter. assert that counter is >0
77
		void decrement_usage() 
88
		void decrement_usage() 
78
		{
89
		{
79
			assert(usage>0);
90
			assert(usage>0);
80
			--usage;
91
			--usage;
81
		}
92
		}
82
 
93
 
83
		/// Return the usage count (mostly for debugging)
94
		/// Return the usage count (mostly for debugging)
84
		int get_usage() const { return usage; }
95
		int get_usage() const { return usage; }
85
 
96
 
86
		/// Get the name of a resource
97
		/// Get the name of a resource
87
		const std::string& get_name() const {return name;}
98
		const std::string& get_name() const {return name;}
88
 
99
 
89
		/// Get a pointer to the resource (const pointer)
100
		/// Get a pointer to the resource (const pointer)
90
		RES * const get_ptr() 
101
		RES * const get_ptr() 
91
		{
102
		{
92
			return res;
103
			return res;
93
		}
104
		}
94
 
105
 
95
		/// Get a resource pointer (const pointer and pointee)
106
		/// Get a resource pointer (const pointer and pointee)
96
		const RES * const get_ptr() const 
107
		const RES * const get_ptr() const 
97
		{
108
		{
98
			return res;
109
			return res;
99
		}
110
		}
100
 
111
 
101
		void remove_when_unused() 
112
		void remove_when_unused() 
102
		{
113
		{
103
/* 			assert(!(flags&STATIC_RESOURCE)); */
114
/* 			assert(!(flags&STATIC_RESOURCE)); */
104
/* 			if(!(flags&STATIC_RESOURCE)) */
115
/* 			if(!(flags&STATIC_RESOURCE)) */
105
				flags = flags|REMOVE_WHEN_UNUSED;
116
				flags = flags|REMOVE_WHEN_UNUSED;
106
		}
117
		}
107
 
118
 
108
		FlagByte get_flags() const { return flags;}
119
		FlagByte get_flags() const { return flags;}
109
	
120
	
110
	};
121
	};
111
 
122
 
112
 
123
 
113
	template<class RES> class ResourceManager;
124
	template<class RES> class ResourceManager;
114
 
125
 
115
 
126
 
116
	/** \brief Template for a pointer to a reference counted resource.
127
	/** \brief Template for a pointer to a reference counted resource.
117
 
128
 
118
      The ResourcePtr class template is a template for a reference
129
      The ResourcePtr class template is a template for a reference
119
			counted resource pointer. It is a smart pointer that actually points
130
			counted resource pointer. It is a smart pointer that actually points
120
			to a ResourceRecord and not to the actual resource. Since the record
131
			to a ResourceRecord and not to the actual resource. Since the record
121
			contains a reference count, we can increase the reference count when
132
			contains a reference count, we can increase the reference count when
122
			the pointer is copied and decrease it in the destructor. Only the
133
			the pointer is copied and decrease it in the destructor. Only the
123
			ResourceManager can create ResourcePtr's directly from a raw
134
			ResourceManager can create ResourcePtr's directly from a raw
124
			ResourceRecord. */
135
			ResourceRecord. */
125
	template<class RES>
136
	template<class RES>
126
	class ResourcePtr
137
	class ResourcePtr
127
	{
138
	{
128
		typedef ResourceRecord<RES> RR;
139
		typedef ResourceRecord<RES> RR;
129
		typedef std::list<RR> RRList;
140
		typedef std::list<RR> RRList;
130
		typedef typename RRList::iterator RRListIter;
141
		typedef typename RRList::iterator RRListIter;
131
 
142
 
132
		static RRListIter get_null_rrlist_iter()
143
		static RRListIter get_null_rrlist_iter()
133
		{
144
		{
134
			static RRList l;
145
			static RRList l;
135
			return l.end();
146
			return l.end();
136
		}
147
		}
137
 
148
 
138
#define NULL_RRLIST_ITER ResourcePtr<RES>::get_null_rrlist_iter() 		
149
#define NULL_RRLIST_ITER ResourcePtr<RES>::get_null_rrlist_iter() 		
139
 
150
 
140
		friend class ResourceManager<RES>;
151
		friend class ResourceManager<RES>;
141
 
152
 
142
	private:		
153
	private:		
143
		RRListIter rr;
154
		RRListIter rr;
144
		RES* res;
155
		RES* res;
145
	
156
	
146
		/** Explicit constructor with value. The constructor can only be called
157
		/** Explicit constructor with value. The constructor can only be called
147
				by a friend, i.e. the resource manager. */
158
				by a friend, i.e. the resource manager. */
148
		explicit ResourcePtr(const RRListIter& _rr): rr(_rr), res(0)
159
		explicit ResourcePtr(const RRListIter& _rr): rr(_rr), res(0)
149
		{
160
		{
150
			if(rr != NULL_RRLIST_ITER)
161
			if(rr != NULL_RRLIST_ITER)
151
				{
162
				{
152
					rr->increment_usage();
163
					rr->increment_usage();
153
					res = rr->get_ptr();
164
					res = rr->get_ptr();
154
				}
165
				}
155
		}
166
		}
156
 
167
 
157
		void decrement_usage();
168
		void decrement_usage();
158
	
169
	
159
	public:
170
	public:
160
	
171
	
161
		ResourcePtr(): rr(NULL_RRLIST_ITER), res(0) {}
172
		ResourcePtr(): rr(NULL_RRLIST_ITER), res(0) {}
162
	
173
	
163
		ResourcePtr(const ResourcePtr& r2): rr(r2.rr), res(0)
174
		ResourcePtr(const ResourcePtr& r2): rr(r2.rr), res(0)
164
		{
175
		{
165
			if(rr != NULL_RRLIST_ITER)
176
			if(rr != NULL_RRLIST_ITER)
166
				{
177
				{
167
					rr->increment_usage();
178
					rr->increment_usage();
168
					res = rr->get_ptr();
179
					res = rr->get_ptr();
169
				}
180
				}
170
		}
181
		}
171
 
182
 
172
		const ResourcePtr& operator=(const ResourcePtr& r2) 
183
		const ResourcePtr& operator=(const ResourcePtr& r2) 
173
		{
184
		{
174
			// Guard against self-assignment
185
			// Guard against self-assignment
175
			if (r2.rr != this->rr)
186
			if (r2.rr != this->rr)
176
				{
187
				{
177
					if(rr != NULL_RRLIST_ITER)	decrement_usage();
188
					if(rr != NULL_RRLIST_ITER)	decrement_usage();
178
 
189
 
179
					rr  = r2.rr;
190
					rr  = r2.rr;
180
					res = 0;
191
					res = 0;
181
 
192
 
182
					if(rr != NULL_RRLIST_ITER)
193
					if(rr != NULL_RRLIST_ITER)
183
						{
194
						{
184
							res = rr->get_ptr();
195
							res = rr->get_ptr();
185
							rr->increment_usage();
196
							rr->increment_usage();
186
						}
197
						}
187
				}
198
				}
188
			return *this;
199
			return *this;
189
		}
200
		}
190
 
201
 
191
		~ResourcePtr() {decrement_usage();}
202
		~ResourcePtr() {decrement_usage();}
192
 
203
 
193
		RES& operator*() const 
204
		RES& operator*() const 
194
		{
205
		{
195
			assert(rr != NULL_RRLIST_ITER);
206
			assert(rr != NULL_RRLIST_ITER);
196
			assert(res != 0);
207
			assert(res != 0);
197
			return *res;
208
			return *res;
198
		}
209
		}
199
 
210
 
200
		RES* const operator->() const 
211
		RES* const operator->() const 
201
		{
212
		{
202
			assert(rr != NULL_RRLIST_ITER);
213
			assert(rr != NULL_RRLIST_ITER);
203
			assert(res !=0);
214
			assert(res !=0);
204
			return res;
215
			return res;
205
		}
216
		}
206
 
217
 
207
		RES* const get_raw_ptr() const 
218
		RES* const get_raw_ptr() const 
208
		{
219
		{
209
			assert(rr != NULL_RRLIST_ITER);
220
			assert(rr != NULL_RRLIST_ITER);
210
			assert(res != 0);
221
			assert(res != 0);
211
			return res;
222
			return res;
212
		}
223
		}
213
 
224
 
214
		int usage() const
225
		int usage() const
215
		{
226
		{
216
			if(rr != NULL_RRLIST_ITER)
227
			if(rr != NULL_RRLIST_ITER)
217
				return rr->get_usage();
228
				return rr->get_usage();
218
			return -1;
229
			return -1;
219
		}
230
		}
220
 
231
 
221
		bool is_valid() const {return rr != NULL_RRLIST_ITER;}
232
		bool is_valid() const {return rr != NULL_RRLIST_ITER;}
222
 
233
 
223
		void relinquish_resource()
234
		void relinquish_resource()
224
		{
235
		{
225
			ResourcePtr p;
236
			ResourcePtr p;
226
			*this = p;
237
			*this = p;
227
		}
238
		}
228
 
239
 
229
		/** Calling this function sets the REMOVE_WHEN_UNUSED flag. If this 
240
		/** Calling this function sets the REMOVE_WHEN_UNUSED flag. If this 
230
				flag is set, the resource record is removed from the manager */
241
				flag is set, the resource record is removed from the manager */
231
		void remove_when_unused() {	rr->remove_when_unused(); }
242
		void remove_when_unused() {	rr->remove_when_unused(); }
232
	};
243
	};
233
 
244
 
234
 
245
 
235
	/** \brief Resource manager class.
246
	/** \brief Resource manager class.
236
 
247
 
237
      The ResourceManager is a singleton, and it uses Scott Meyers construct
248
      The ResourceManager is a singleton, and it uses Scott Meyers construct
238
			on first use idiom, i.e. the static function get_instance() will
249
			on first use idiom, i.e. the static function get_instance() will
239
			construct it when first called. There may be a problem with this
250
			construct it when first called. There may be a problem with this
240
			idion if resources depend on each other. However, that is only
251
			idion if resources depend on each other. However, that is only
241
			when the program shuts down.  See modern C++ design by
252
			when the program shuts down.  See modern C++ design by
242
			Alexandrescu for more information.
253
			Alexandrescu for more information.
243
 
254
 
244
			I'll try to make everything in this class private and accessed
255
			I'll try to make everything in this class private and accessed
245
			by a simple interface of friend functions.
256
			by a simple interface of friend functions.
246
 
257
 
247
	*/
258
	*/
248
 
259
 
249
	template<class RES>
260
	template<class RES>
250
	class ResourceManager
261
	class ResourceManager
251
	{
262
	{
252
		typedef ResourceRecord<RES> RR;
263
		typedef ResourceRecord<RES> RR;
253
		typedef std::list<RR> RRList;
264
		typedef std::list<RR> RRList;
254
		typedef typename RRList::iterator RRListIter;
265
		typedef typename RRList::iterator RRListIter;
255
		RRList resources;
266
		RRList resources;
256
	
267
	
257
		ResourceManager(): resources(0) {}
268
		ResourceManager(): resources(0) {}
258
		ResourceManager(const ResourceManager&);
269
		ResourceManager(const ResourceManager&);
259
		ResourceManager& operator=(const ResourceManager&);
270
		ResourceManager& operator=(const ResourceManager&);
260
 
271
 
261
	public:
272
	public:
262
 
273
 
263
 
274
 
264
		~ResourceManager()
275
		~ResourceManager()
265
		{
276
		{
266
#if CLEAN_SHUTDOWN
277
#if CLEAN_SHUTDOWN
267
			RRListIter i = resources.begin(); 
278
			RRListIter i = resources.begin(); 
268
			while(i != resources.end())
279
			while(i != resources.end())
269
				{
280
				{
270
					if(i->get_usage()==0)
281
					if(i->get_usage()==0)
271
						{
282
						{
272
							RRListIter tmp = i;
283
							RRListIter tmp = i;
273
							++i;
284
							++i;
274
							erase_resource(tmp);
285
							erase_resource(tmp);
275
						}
286
						}
276
					else
287
					else
277
						{
288
						{
278
							std::cout << "Warning, ResourceManager:\n\n"
289
							std::cout << "Warning, ResourceManager:\n\n"
279
												<< (typeid(this).name())
290
												<< (typeid(this).name())
280
												<< "\n\nis shutting down, and resource \n\n" 
291
												<< "\n\nis shutting down, and resource \n\n" 
281
												<< i->get_name() << "\n\nhas usage: " << i->get_usage()
292
												<< i->get_name() << "\n\nhas usage: " << i->get_usage()
282
												<< std::endl;
293
												<< std::endl;
283
							std::cout <<
294
							std::cout <<
284
 								"In other words, this resource is not unused at this\n"
295
 								"In other words, this resource is not unused at this\n"
285
								"point. That is unfortunate because then it cannot\n"
296
								"point. That is unfortunate because then it cannot\n"
286
								"be deleted (since it might be used by some other\n"
297
								"be deleted (since it might be used by some other\n"
287
								"part of the program during shutdown). Please ensure\n"
298
								"part of the program during shutdown). Please ensure\n"
288
								"that all resources are unused at program\n"
299
								"that all resources are unused at program\n"
289
								"termination. If you use a global ResourcePtr, this is\n"
300
								"termination. If you use a global ResourcePtr, this is\n"
290
								"done by calling relinquish_resource just before\n"
301
								"done by calling relinquish_resource just before\n"
291
								"exiting.\n"
302
								"exiting.\n"
292
												<< std::endl;
303
												<< std::endl;
293
							++i;
304
							++i;
294
						}
305
						}
295
				}
306
				}
296
#endif
307
#endif
297
		}
308
		}
298
 
309
 
299
		int get_no_resources() const
310
		int get_no_resources() const
300
		{
311
		{
301
			return resources.size();
312
			return resources.size();
302
		}
313
		}
303
 
314
 
304
		static ResourceManager& get_instance() 
315
		static ResourceManager& get_instance() 
305
		{
316
		{
306
			static ResourceManager instance;
317
			static ResourceManager instance;
307
			return instance;
318
			return instance;
308
		}
319
		}
309
 
320
 
310
		void erase_resource(RRListIter iter)
321
		void erase_resource(RRListIter iter)
311
		{
322
		{
312
			iter->erase_resource();
323
			iter->erase_resource();
313
			resources.erase(iter);
324
			resources.erase(iter);
314
		}
325
		}
315
 
326
 
316
		/** Find a resource and return a ResourcePtr to it. Returns the 
327
		/** Find a resource and return a ResourcePtr to it. Returns the 
317
				0 ResourcePtr if no string found. */
328
				0 ResourcePtr if no string found. */
318
		ResourcePtr<RES> get_resource_ptr(const std::string& str)
329
		ResourcePtr<RES> get_resource_ptr(const std::string& str)
319
		{
330
		{
320
			for(RRListIter i = resources.begin(); i != resources.end(); ++i)
331
			for(RRListIter i = resources.begin(); i != resources.end(); ++i)
321
				if((*i).get_name() == str) 
332
				if((*i).get_name() == str) 
322
					return ResourcePtr<RES>(i);
333
					return ResourcePtr<RES>(i);
323
			return ResourcePtr<RES>(NULL_RRLIST_ITER);
334
			return ResourcePtr<RES>(NULL_RRLIST_ITER);
324
		}
335
		}
325
 
336
 
326
		/** Add a resource with name passed as first argument and a pointer
337
		/** Add a resource with name passed as first argument and a pointer
327
				passed as 2nd argument. A ResourcePtr to the just inserted
338
				passed as 2nd argument. A ResourcePtr to the just inserted
328
				element is returned. */
339
				element is returned. */
329
		ResourcePtr<RES> register_resource(const std::string& str, 
340
		ResourcePtr<RES> register_resource(const std::string& str, 
330
																			 RES* res, bool static_resource)
341
																			 RES* res, bool static_resource)
331
		{
342
		{
332
			for(RRListIter i = resources.begin(); i != resources.end(); ++i)
343
			for(RRListIter i = resources.begin(); i != resources.end(); ++i)
333
				if(i->get_name() == str)
344
				if(i->get_name() == str)
334
					return (ResourcePtr<RES>(NULL_RRLIST_ITER));
345
					return (ResourcePtr<RES>(NULL_RRLIST_ITER));
335
 
346
 
336
			resources.push_front(RR(str, res, static_resource));
347
			resources.push_front(RR(str, res, static_resource));
337
			ResourcePtr<RES> ptr = ResourcePtr<RES>(resources.begin());
348
			ResourcePtr<RES> ptr = ResourcePtr<RES>(resources.begin());
338
			return ptr;
349
			return ptr;
339
		}
350
		}
340
 
351
 
341
/*		friend class ResourcePtr<RES>;
352
/*		friend class ResourcePtr<RES>;
342
		friend int get_no_resources<RES>();
353
		friend int get_no_resources<RES>();
343
		friend ResourcePtr<RES> get_resource_ptr<RES>(const std::string& str); 
354
		friend ResourcePtr<RES> get_resource_ptr<RES>(const std::string& str); 
344
		friend ResourcePtr<RES> register_static_resource<RES>(const std::string&,
355
		friend ResourcePtr<RES> register_static_resource<RES>(const std::string&,
345
																													RES*); 
356
																													RES*); 
346
		friend ResourcePtr<RES> register_dynamic_resource<RES>(const std::string&,
357
		friend ResourcePtr<RES> register_dynamic_resource<RES>(const std::string&,
347
																													 RES*);*/ 
358
																													 RES*);*/ 
348
	};
359
	};
349
 
360
 
350
	template<class RES>
361
	template<class RES>
351
	inline void ResourcePtr<RES>::decrement_usage()
362
	inline void ResourcePtr<RES>::decrement_usage()
352
	{
363
	{
353
		assert( (rr == NULL_RRLIST_ITER) || (res != 0));
364
		assert( (rr == NULL_RRLIST_ITER) || (res != 0));
354
		if(rr != NULL_RRLIST_ITER)
365
		if(rr != NULL_RRLIST_ITER)
355
			{
366
			{
356
				rr->decrement_usage();
367
				rr->decrement_usage();
357
				if(rr->get_usage() == 0 && (rr->get_flags()&REMOVE_WHEN_UNUSED))
368
				if(rr->get_usage() == 0 && (rr->get_flags()&REMOVE_WHEN_UNUSED))
358
					{
369
					{
359
						ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
370
						ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
360
						man.erase_resource(rr);
371
						man.erase_resource(rr);
361
					}
372
					}
362
			}
373
			}
363
	}
374
	}
364
 
375
 
365
	template<class RES>
376
	template<class RES>
366
	inline int get_no_resources()
377
	inline int get_no_resources()
367
	{
378
	{
368
		ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
379
		ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
369
		return man.get_no_resources();
380
		return man.get_no_resources();
370
	}
381
	}
371
 
382
 
372
	template<class RES>
383
	template<class RES>
373
	inline ResourcePtr<RES> get_resource_ptr(const std::string& str)
384
	inline ResourcePtr<RES> get_resource_ptr(const std::string& str)
374
	{
385
	{
375
		ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
386
		ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
376
		return man.get_resource_ptr(str);
387
		return man.get_resource_ptr(str);
377
	}
388
	}
378
 
389
 
379
	template<class RES>
390
	template<class RES>
380
	inline ResourcePtr<RES> register_dynamic_resource(const std::string& str,RES* res)
391
	inline ResourcePtr<RES> register_dynamic_resource(const std::string& str,RES* res)
381
	{
392
	{
382
		ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
393
		ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
383
		ResourcePtr<RES> ptr = man.register_resource(str, res, false);
394
		ResourcePtr<RES> ptr = man.register_resource(str, res, false);
384
		return ptr;
395
		return ptr;
385
	}
396
	}
386
 
397
 
387
	template<class RES>
398
	template<class RES>
388
	inline ResourcePtr<RES> register_static_resource(const std::string& str,RES* res)
399
	inline ResourcePtr<RES> register_static_resource(const std::string& str,RES* res)
389
	{
400
	{
390
		ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
401
		ResourceManager<RES>& man = ResourceManager<RES>::get_instance();
391
		ResourcePtr<RES> ptr = man.register_resource(str, res, true);
402
		ResourcePtr<RES> ptr = man.register_resource(str, res, true);
392
		return ptr;
403
		return ptr;
393
	}
404
	}
394
 
405
 
395
}
406
}
396
 
407
 
397
 
408
 
398
#endif
409
#endif
399
 
410