Subversion Repositories gelsvn

Rev

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

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