zenilib: zenilib/jni/external/zenilib/zeni/Zeni/Database.hxx Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Database.hxx
Go to the documentation of this file.
1 /* This file is part of the Zenipex Library (zenilib).
2 * Copyright (C) 2011 Mitchell Keith Bloch (bazald).
3 *
4 * zenilib is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * zenilib is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with zenilib. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef ZENI_DATABASE_HXX
19 #define ZENI_DATABASE_HXX
20
21 // HXXed below
22 #include <Zeni/Resource.h>
23
24 #include <Zeni/Database.h>
25
26 #include <Zeni/XML.h>
27
28 #include <algorithm>
29 #include <iostream>
30
31 namespace Zeni {
32 template <class TYPE>
33 Database<TYPE>::Lookup::Handle::Handle()
34 : ptr(0),
35 lent(false)
36 {
37 }
38
39 template <class TYPE>
40 Database<TYPE>::Lookup::Handle::Handle(const String &filename_)
41 : ptr(0),
42 filename(filename_),
43 lent(false)
44 {
45 }
46
47 template <class TYPE>
48 Database<TYPE>::Lookup::Handle::Handle(TYPE * const &ptr_,
49 const String &filename_,
50 const bool &lent_,
51 const bool &keep_)
52 : ptr(ptr_),
53 filename(filename_),
54 lent(lent_),
55 keep(keep_)
56 {
57 }
58
59 template <class TYPE>
60 bool Database<TYPE>::Lookup::Handle::operator==(const Handle &rhs) const {
61 return filename == rhs.filename;
62 }
63
64 template <class TYPE>
65 Database<TYPE>::Lookup::Lookup()
66 : id(0)
67 {
68 }
69
70 template <class TYPE>
71 Database<TYPE>::Lookup::Lookup(const unsigned long &id_, const Handle &handle_)
72 : id(id_)
73 {
74 handles.push_front(handle_);
75 }
76
77 template <class TYPE>
78 Database<TYPE>::Database(const String &filename, const String &xml_identifier)
79 : m_xml_identifier(xml_identifier),
80 m_lost(true)
81 {
82 m_filenames.push_front(filename);
83 }
84
85 template <class TYPE>
86 Database<TYPE>::~Database() {
87 uninit();
88 }
89
90 template <class TYPE>
91 unsigned long Database<TYPE>::give(const String &name, TYPE * const &type, const bool &keep, const String &filename) {
92 if(!type)
93 throw Null_Database_Entry_Set();
94
95 Lookup *&lr = m_lookups[name];
96 if(!lr)
97 lr = new Lookup();
98
99 if(!lr->id)
100 lr->id = get_Resource().assign();
101
102 typename Lookup::Handles::iterator it = std::find(lr->handles.begin(), lr->handles.end(), typename Lookup::Handle(filename));
103
104 if(it != lr->handles.end()) {
105 if(!it->lent)
106 delete it->ptr;
107 lr->handles.erase(it);
108 }
109
110 lr->handles.push_front(typename Lookup::Handle(type, filename, false, keep));
111
112 m_entries[lr->id] = type;
113
114 return lr->id;
115 }
116
117 template <class TYPE>
118 unsigned long Database<TYPE>::lend(const String &name, TYPE * const &type, const bool &keep) {
119 if(!type)
120 throw Null_Database_Entry_Set();
121
122 Lookup *&lr = m_lookups[name];
123 if(!lr)
124 lr = new Lookup();
125
126 if(!lr->id)
127 lr->id = get_Resource().assign();
128
129 typename Lookup::Handles::iterator it = std::find(lr->handles.begin(), lr->handles.end(), typename Lookup::Handle(""));
130
131 if(it != lr->handles.end()) {
132 if(!it->lent)
133 delete it->ptr;
134 lr->handles.erase(it);
135 }
136
137 lr->handles.push_front(typename Lookup::Handle(type, "", true, keep));
138
139 m_entries[lr->id] = type;
140
141 return lr->id;
142 }
143
144 template <class TYPE>
145 void Database<TYPE>::clear(const String &name, const String &filename) {
146 typename Lookups::iterator it = m_lookups.find(name);
147
148 if(it == m_lookups.end())
149 throw Database_Entry_Not_Found("*::" + name);
150
151 Lookup &lr = *it->second;
152 typename Lookup::Handles::iterator jt = std::find(lr.handles.begin(), lr.handles.end(), typename Lookup::Handle(filename));
153
154 if(jt == lr.handles.end())
155 throw Database_Entry_Not_Found(filename + "::" + name);
156
157 if(!jt->lent)
158 delete jt->ptr;
159
160 lr.handles.erase(jt);
161
162 if(lr.handles.empty()) {
163 m_entries.erase(lr.id);
164 delete it->second;
165 m_lookups.erase(it);
166 }
167 else
168 m_entries[lr.id] = lr.handles.begin()->ptr;
169 }
170
171 template <class TYPE>
172 unsigned long Database<TYPE>::get_id(const String &name) const {
173 typename Lookups::const_iterator it = m_lookups.find(name);
174
175 if(it == m_lookups.end() || !it->second->id)
176 throw Database_Entry_Not_Found(name);
177
178 return it->second->id;
179 }
180
181 template <class TYPE>
182 unsigned long Database<TYPE>::find(const String &name) const {
183 typename Lookups::const_iterator it = m_lookups.find(name);
184
185 if(it != m_lookups.end() && it->second->id && find(it->second->id))
186 return it->second->id;
187
188 return 0;
189 }
190
191 template <class TYPE>
192 bool Database<TYPE>::find(const unsigned long &id) const {
193 return m_entries.find(id) != m_entries.end();
194 }
195
196 template <class TYPE>
197 TYPE & Database<TYPE>::operator[](const unsigned long &id) const {
198 typename Entries::const_iterator it = m_entries.find(id);
199
200 if(it == m_entries.end() || !it->second) {
201 char buf[64];
202 #ifdef _WINDOWS
203 sprintf_s
204 #else
205 sprintf
206 #endif
207 (buf, "ID = %u", static_cast<unsigned int>(id));
208 throw Database_Entry_Not_Found(buf);
209 }
210
211 return *it->second;
212 }
213
214 template <class TYPE>
215 TYPE & Database<TYPE>::operator[](const String &name) const {
216 return (*this)[get_id(name)];
217 }
218
219 template <class TYPE>
220 void Database<TYPE>::clear() {
221 uninit();
222 }
223
224 template <class TYPE>
225 void Database<TYPE>::load_file(const String &filename) {
226 Filenames::iterator it = std::find(m_filenames.begin(), m_filenames.end(), filename);
227 if(it != m_filenames.end())
228 m_filenames.erase(it);
229 m_filenames.push_front(filename);
230
231 #ifdef ANDROID
232 XML_Document types_xml;
233 {
234 String memory;
235 types_xml.load_mem(File_Ops::load_asset(memory, filename));
236 }
237 #else
238 XML_Document types_xml(filename.c_str());
239 #endif
240
241 XML_Element_c types = types_xml[m_xml_identifier];
242 String name;
243
244 try {
245 for(XML_Element_c it = types.first(); it.good(); it = it.next()) {
246 name = it.value();
247
248 if(!give_priority(name, false, false, filename)) {
249 TYPE * const type = load(it, name, filename);
250 if(!type)
251 throw Database_Load_Entry_Failed(name);
252
253 give(name, type, false, filename);
254 }
255 }
256 }
257 catch(...)
258 {
259 const String error = "Error loading '" + m_xml_identifier + "' entry '" + name + "'";
260 std::cerr << error << std::endl;
261 message_box(error);
262 throw;
263 }
264
265 on_load();
266 }
267
268 template <class TYPE>
269 void Database<TYPE>::unload_file(const String &filename) {
270 Filenames::iterator it = std::find(m_filenames.begin(), m_filenames.end(), filename);
271 if(it == m_filenames.end())
272 throw Database_File_Not_Loaded(filename);
273
274 for(typename Lookups::iterator it = m_lookups.begin();
275 it != m_lookups.end();
276 ++it)
277 {
278 for(typename Lookup::Handles::iterator jt = it->second->handles.begin();
279 jt != it->second->handles.end();)
280 {
281 if(jt->filename != filename)
282 ++jt;
283 else {
284 if(!jt->lent)
285 delete jt->ptr;
286 jt = it->second->handles.erase(jt);
287 }
288 }
289
290 if(!it->second->handles.empty()) {
291 m_entries[it->second->id] = it->second->handles.begin()->ptr;
292 // ++it;
293 }
294 else {
295 m_entries.erase(it->second->id);
296 // delete it->second;
297 // it = m_lookups.erase(it);
298 }
299 }
300
301 m_filenames.erase(it);
302
303 if(m_filenames.empty())
304 on_clear();
305 }
306
307 template <class TYPE>
308 void Database<TYPE>::reload() {
309 lose_resources();
310 init();
311 }
312
313 template <class TYPE>
314 void Database<TYPE>::init() {
315 const Filenames old = m_filenames;
316
317 for(Filenames::const_reverse_iterator it = old.rbegin();
318 it != old.rend();
319 ++it)
320 {
321 ZENI_LOGD((String("Loading ") + *it).c_str());
322 load_file(*it);
323 ZENI_LOGD((String("Loaded ") + *it).c_str());
324 }
325
326 m_lost = false;
327 }
328
329 template <class TYPE>
330 void Database<TYPE>::uninit() {
331 on_clear();
332
333 m_entries.clear();
334
335 for(typename Lookups::iterator it = m_lookups.begin();
336 it != m_lookups.end();
337 ++it)
338 {
339 for(typename Lookup::Handles::iterator jt = it->second->handles.begin();
340 jt != it->second->handles.end();
341 ++jt)
342 {
343 if(!jt->lent)
344 delete jt->ptr;
345 }
346
347 delete it->second;
348 }
349
350 m_lookups.clear();
351 }
352
353 template <class TYPE>
354 bool Database<TYPE>::give_priority(const String &name,
355 const bool &lent,
356 const bool &keep,
357 const String &filename)
358 {
359 const typename Lookups::const_iterator it = m_lookups.find(name);
360 if(it == m_lookups.end())
361 return false;
362
363 typename Lookup::Handles &lhr = it->second->handles;
364 typename Lookup::Handles::iterator jt = std::find(lhr.begin(), lhr.end(), typename Lookup::Handle(filename));
365 if(jt == lhr.end())
366 return false;
367
368 if(jt->lent != lent || jt->keep != keep)
369 return false;
370
371 const typename Lookup::Handle handle = *jt;
372 lhr.erase(jt);
373 lhr.push_front(handle);
374
375 m_entries[it->second->id] = handle.ptr;
376
377 return true;
378 }
379
380 template <class TYPE>
381 const bool & Database<TYPE>::lost_resources() {
382 return m_lost;
383 }
384
385 template <class TYPE>
386 void Database<TYPE>::lose_resources() {
387 on_lose();
388
389 for(typename Lookups::iterator it = m_lookups.begin();
390 it != m_lookups.end();
391 ++it)
392 {
393 for(typename Lookup::Handles::iterator jt = it->second->handles.begin();
394 jt != it->second->handles.end();)
395 {
396 if(jt->keep)
397 ++jt;
398 else {
399 if(!jt->lent)
400 delete jt->ptr;
401 jt = it->second->handles.erase(jt);
402 }
403 }
404
405 if(!it->second->handles.empty())
406 m_entries[it->second->id] = it->second->handles.begin()->ptr;
407 else
408 m_entries.erase(it->second->id);
409 }
410
411 m_lost = true;
412 }
413
414 template <class TYPE>
415 void Database<TYPE>::unlose_resources() {
416 if(m_lost)
417 init();
418 }
419
420 }
421
422 #include <Zeni/Resource.hxx>
423
424 #endif
Zeni::Null_Database_Entry_Set
Definition: Database.h:150
Zeni::Database::lose_resources
void lose_resources()
Wipe losable resources and prepare to reload them when they are next needed.
Definition: Database.hxx:386
Zeni::Database::Lookup::Handle::filename
String filename
Definition: Database.h:56
Zeni::File_Ops::load_asset
static String & load_asset(String &memory, const String &filename)
Load a file into memory.
Definition: File_Ops.cpp:190
types
GLsizei GLenum GLenum * types
Definition: glew.h:3769
Zeni::Database_Entry_Not_Found
Definition: Database.h:142
Zeni::Database::give
unsigned long give(const String &name, TYPE *const &type, const bool &keep, const String &filename="")
Add an entry (which it will later delete)
Definition: Database.hxx:91
Zeni::Database::lend
unsigned long lend(const String &name, TYPE *const &type, const bool &keep)
Add an entry (which it will NEVER delete)
Definition: Database.hxx:118
type
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
Zeni::Database_Load_Entry_Failed
Definition: Database.h:146
init
static void init(struct bs2b *bs2b)
Definition: bs2b.c:46
Zeni::Database::get_id
unsigned long get_id(const String &name) const
Get an id by name, possibly throwing an Error.
Definition: Database.hxx:172
Zeni::String::c_str
const char * c_str() const
Definition: String.cpp:467
name
EGLImageKHR EGLint * name
Definition: eglext.h:284
Zeni::XML_Document::load_mem
void load_mem(const String &data)
Definition: XML.cpp:262
Zeni::Resource::assign
unsigned long assign()
Get a value, unique within this run of the program.
Definition: Resource.hxx:25
Zeni::Database::reload
void reload()
lose_resources + init
Definition: Database.hxx:308
id
GLuint id
Definition: gl2ext.h:1142
Zeni::Database::load_file
void load_file(const String &filename)
Load all resources from a given file, giving them highest priority.
Definition: Database.hxx:225
Zeni::Database_File_Not_Loaded
Definition: Database.h:138
Zeni::String
Definition: String.h:29
Zeni::Database
A Texture Database Singleton.
Definition: Database.h:46
Zeni::Database::clear
void clear()
Permanently clear all resources.
Definition: Database.hxx:220
Zeni::Database::Lookup::Handle::Handle
Handle()
Definition: Database.hxx:33
XML.h
Zeni::Database::~Database
virtual ~Database()
Definition: Database.hxx:86
error
FT_Error error
Definition: cffdrivr.c:407
true
#define true
Definition: ftrandom.c:49
sort_controllers.filename
string filename
Definition: sort_controllers.py:8
ZENI_LOGD
void ZENI_LOGD(const Zeni::String &str)
Definition: Android.h:50
Zeni::XML_Document
A class to open an XML file and manage the root node.
Definition: XML.h:111
Zeni::Database::operator[]
TYPE & operator[](const String &name) const
Get a TYPE by name.
Definition: Database.hxx:215
Zeni::get_Resource
Resource & get_Resource()
Get access to the singleton.
Definition: Resource.cpp:35
Zeni::message_box
void message_box(const char *const &msg)
Definition: Error.h:60
Resource.h
Database.h
Zeni::Database::Lookup::Handle::operator==
bool operator==(const Handle &rhs) const
Definition: Database.hxx:60
Zeni::Database::find
unsigned long find(const String &name) const
Get an id by name, without throwing an Error.
Definition: Database.hxx:182
Zeni::Database::Lookup::Handle
Definition: Database.h:48
Zeni::Database::unlose_resources
void unlose_resources()
If resources have been lost, then reload them.
Definition: Database.hxx:415
buf
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2539
Zeni::Database::init
void init()
Definition: Database.hxx:314
Zeni::Database::lost_resources
const bool & lost_resources()
Check to see if resources have been lost.
Definition: Database.hxx:381
Zeni::XML_Element_c
Definition: XML.h:53
Resource.hxx
Zeni::Database::give_priority
bool give_priority(const String &name, const bool &lent, const bool &keep, const String &filename="")
If &#39;lent&#39;, &#39;keep&#39;, and &#39;filename&#39; match, give priority over other &#39;name&#39; entries. ...
Definition: Database.hxx:354
Zeni::Database::Lookup::Handle::ptr
TYPE * ptr
Definition: Database.h:55
handle
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:284
TYPE
Definition: infutil.h:15
Zeni::XML_Element_c::first
XML_Element_c first() const
Get the first subelement.
Definition: XML.cpp:44
false
#define false
Definition: ftrandom.c:50
Zeni::Database::unload_file
void unload_file(const String &filename)
Unload all resources from a given file, reloading lower priority resources.
Definition: Database.hxx:269
Zeni::Database::uninit
void uninit()
Definition: Database.hxx:330
Zeni::XML_Element_c::good
bool good() const
Test to see if the Element is valid.
Definition: XML.cpp:64