Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/chris/src/data_tank.cc @ 2665

Last change on this file since 2665 was 2665, checked in by chris, 20 years ago

orxonox/branches/chris: forgot we used .cc as postfix of source files and not .cpp

File size: 9.3 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software Foundation,
18   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
19
20
21   ### File Specific:
22   main-programmer: Christian Meyer
23   co-programmer: ...
24*/
25
26#include "datatank.h"
27
28using namespace std;
29
30//////////////////
31// DataTank
32//////////////////
33
34DataTank::DataTank()
35{
36        loader = new DataLoader;
37        tree = NULL;
38}
39
40DataTank::~DataTank()
41{
42        // free DataTree
43        tree_delete();
44        // free DataLoader
45        if( loader) delete loader;
46}
47
48void DataTank::tree_add( void* r, char* filename, int type)
49{
50        DataTree *act;
51       
52        if( tree == NULL)
53        {
54                tree = (DataTree*) malloc( sizeof( DataTree));
55                tree->type = type;
56                memset( tree->filename, 0, MAX_FILENAME_LENGHT);
57                strncpy( tree->filename, filename, MAX_FILENAME_LENGHT-1);
58                tree->parent = NULL;
59                tree->up = NULL;
60                tree->down = NULL;
61                tree->resource = r;
62                return;
63        }
64       
65        act = tree;
66        while( act != NULL)
67        {
68                if( strcmp( act->filename, filename) > 0)
69                {
70                        if( act->up != NULL) act = act->up;
71                        else
72                        {
73                                act->up = (DataTree*) malloc( sizeof( DataTree));
74                                act->up->type = type;
75                                memset( act->up->filename, 0, MAX_FILENAME_LENGHT);
76                                strncpy( act->up->filename, filename, MAX_FILENAME_LENGHT-1);
77                                act->up->parent = act;
78                                act->up->up = NULL;
79                                act->up->down = NULL;
80                                act->up->resource = r;
81                                break;
82                        }
83                }
84                else
85                {
86                        if( act->down != NULL) act = act->down;
87                        else
88                        {
89                                act->down = (DataTree*) malloc( sizeof( DataTree));
90                                act->down->type = type;
91                                memset( act->down->filename, 0, MAX_FILENAME_LENGHT);
92                                strncpy( act->down->filename, filename, MAX_FILENAME_LENGHT-1);
93                                act->down->parent = act;
94                                act->down->up = NULL;
95                                act->down->down = NULL;
96                                act->down->resource = r;
97                                break;
98                        }
99                }
100        }
101}
102
103DataTree* DataTank::tree_find( char* file)
104{
105        DataTree *act;
106       
107        if( tree == NULL) return NULL;
108       
109        act = tree;
110       
111        while( act != NULL)
112        {
113                if( strcmp( act->filename, file) == 0) break;
114                else if( strcmp( act->filename, file) > 0)
115                        act = act->up;
116                else
117                        act = act->down;
118        }
119       
120        return act;
121}
122
123DataTree* DataTank::tree_highest( DataTree* t)
124{
125        DataTree* act;
126       
127        if( t == NULL) return NULL;
128       
129        act = t;
130       
131        while( act != NULL)
132        {
133                if( act->up == NULL) break;
134                act = act->up;
135        }
136       
137        return act;
138}
139
140DataTree* DataTank::tree_lowest( DataTree* t)
141{
142        DataTree* act;
143       
144        if( t == NULL) return NULL;
145       
146        act = t;
147       
148        while( act != NULL)
149        {
150                if( act->down == NULL) break;
151                act = act->down;
152        }
153       
154        return act;
155}
156
157void DataTank::tree_remove( DataTree* rem)
158{
159        DataTree *rep;
160        void* tempv;
161        int tempi;
162        char tempn[MAX_FILENAME_LENGHT];
163       
164        if( rem != NULL)
165        {
166                if( rem->up == NULL && rem->down == NULL)
167                {
168                                // leaf
169                        if( rem->parent == NULL) tree = NULL;
170                        else
171                        {
172                                if( rem->parent->up == rem) rem->parent->up = NULL;
173                                else rem->parent->down = NULL;
174                        }
175                        loader->free_file( rem->resource, rem->type);
176                        free( rem);
177                }
178                else if( rem->up != NULL && rem->down == NULL)
179                {
180                                // branch up
181                        if( rem->parent == NULL)
182                        {
183                                tree = rem->up;
184                                rem->up->parent = NULL;
185                        }
186                        else
187                        {
188                                if( rem->parent->up == rem) rem->parent->up = rem->up;
189                                else rem->parent->down = rem->up;
190                                rem->up->parent = rem->parent;
191                        }
192                        loader->free_file( rem->resource, rem->type);
193                        free( rem);                     
194                }
195                else if( rem->up == NULL && rem->down != NULL)
196                {
197                                // branch down
198                        if( rem->parent == NULL)
199                        {
200                                tree = rem->down;
201                                rem->down->parent = NULL;
202                        }
203                        else
204                        {
205                                if( rem->parent->up == rem) rem->parent->up = rem->down;
206                                else rem->parent->down = rem->down;
207                                rem->down->parent = rem->parent;
208                        }
209                        loader->free_file( rem->resource, rem->type);
210                        free( rem);                     
211                }
212                else
213                {
214                                // fork
215                        // get highest from down tree
216                        rep = tree_highest( rem->down);
217                       
218                        // swap contents
219                        tempv = rep->resource;
220                        tempi = rep->type;
221                        strcpy( tempn, rep->filename);
222                       
223                        rep->resource = rem->resource;
224                        rep->type = rem->type;
225                        strcpy( rep->filename, rem->filename);
226                       
227                        rem->resource = tempv;
228                        rem->type = tempi;
229                        strcpy( rem->filename, tempn);
230                       
231                        // remove rep
232                        tree_remove( rep);
233                }
234        }
235}
236
237void DataTank::tree_delete()
238{
239        DataTree *act, *kil;
240       
241        if( tree != NULL)
242        {
243                act = tree;
244                while( act != NULL)
245                {
246                        if( act->up != NULL)
247                        {
248                                act = act->up;
249                                continue;
250                        }
251                        if( act->down != NULL)
252                        {
253                                act = act->down;
254                                continue;
255                        }
256                        kil = act;
257                        act = act->parent;
258                        if( act != NULL)
259                        {
260                                if( kil == act->up)     act->up = NULL;
261                                if( kil == act->down) act->down = NULL;
262                        }
263                        loader->free_file( kil->resource, kil->type);
264                        free( kil);
265                }
266        }
267}
268
269void* DataTank::get( char* file)
270{
271        DataTree* t;
272        void* new_res;
273        int type;
274       
275        t = tree_find( file);
276       
277        if( t == NULL)
278        {
279                type = loader->get_type( file);
280                if( type == -1) return NULL;
281                new_res = loader->load_file( file, type);
282                if( new_res == NULL)
283                {
284                        // return placeholder
285                }
286                else
287                {
288                        tree_add( new_res, file, type);
289                        return new_res;
290                }
291        }
292        else
293        {
294                return t->resource;
295        }
296}
297
298void DataTank::unload( char* file)
299{
300        DataTree* rem;
301       
302        rem = tree_find( file);
303       
304        tree_remove( rem);
305}
306
307void DataTank::precache( char* resfile, void(*pfunc)(int, float, char*, char*))
308{
309}
310
311void DataTank::save_precache( char* filename)
312{
313        FILE* out;
314        DataTree* act;
315       
316        out = fopen( filename, "w");
317        if( out == NULL) return;
318       
319        if( tree != NULL) save_node( tree, out);
320       
321        fclose( out);
322}
323
324void DataTank::save_node( DataTree* act, FILE* out)
325{
326        fprintf(out, "%s\n", act->filename);
327       
328        if( act->down) save_node( act->down, out);
329        if( act->up) save_node( act->up, out);
330       
331        return;
332}
333
334int DataTank::add_filetype( char* postfix, void*(*lfunc)(char*), void(*ffunc)(void*), char* placeholderfile)
335{
336        return loader->add_filetype( postfix, lfunc, ffunc, placeholderfile);
337}
338
339////////////////
340// DataLoader
341////////////////
342
343DataLoader::DataLoader()
344{
345        ntypes = 0;
346        load_funcs = NULL;
347        free_funcs = NULL;
348        postfixes = NULL;
349        placeholders = NULL;
350}
351
352DataLoader::~DataLoader()
353{
354        int i;
355       
356        for( i = 0; i < ntypes; i++)
357        {
358                if( placeholders[i] != NULL) free_funcs[i]( placeholders[i]);
359                if( postfixes[i] != NULL) free( postfixes[i]);
360        }
361       
362        if( postfixes) free( postfixes);
363        if( placeholders) free( placeholders);
364        if( free_funcs) free( free_funcs);
365        if( load_funcs) free( load_funcs);
366}
367
368int DataLoader::add_filetype( char* postfix, void*(*lfunc)(char*), void(*ffunc)(void*), char* placeholderfile)
369{
370        int type = 0;
371        char testfile[MAX_FILENAME_LENGHT];
372       
373        if( !postfix || !lfunc || !ffunc || !placeholderfile) return -1;
374       
375        sprintf( testfile, "blabla.%s", postfix);
376        if( (type = get_type( testfile)) != -1)
377        {
378                load_funcs[type] = lfunc;
379                free_funcs[type] = ffunc;
380                placeholders[type] = lfunc( placeholderfile);
381                return type;
382        }
383       
384        // backup
385        void*(**old_load_funcs)(char*) = load_funcs;
386        void(**old_free_funcs)(void*) = free_funcs;
387        char** old_postfixes = postfixes;
388        void** old_placeholders = placeholders;
389       
390        // realloc
391        load_funcs = (void*(**)(char*)) malloc( sizeof( void*(*)(char*)) * (ntypes + 1));
392        free_funcs = (void(**)(void*)) malloc( sizeof( void(*)(void*)) * (ntypes + 1));
393        postfixes = (char**) malloc( sizeof( char*) * POSTFIX_LENGHT * (ntypes + 1));
394        placeholders = (void**) malloc( sizeof( void*) * (ntypes + 1));
395       
396        // copy
397        memcpy( load_funcs, old_load_funcs, sizeof( void*(*)(char*)) * ntypes);
398        memcpy( free_funcs, old_free_funcs, sizeof( void*(*)(void*)) * ntypes);
399        memcpy( postfixes, old_postfixes, sizeof( char*) * POSTFIX_LENGHT * ntypes);
400        memcpy( placeholders, old_placeholders, sizeof( void*) * ntypes);
401       
402        // add
403        type = ntypes;
404        ntypes++;
405       
406        load_funcs[type] = lfunc;
407        free_funcs[type] = ffunc;
408        memset( postfixes[type], 0, 5);
409        strncpy( postfixes[type], postfix, 5);
410        placeholders[type] = lfunc( placeholderfile);
411       
412        return type;
413}
414
415void* DataLoader::load_file( char* file, int type)
416{
417        if( type <= ntypes && type >= 0) return load_funcs[type]( file);
418        else return NULL;
419}
420
421int DataLoader::get_type( char* file)
422{
423        int i, n;
424        char* posterior;
425       
426        if( file == NULL) return -1;
427       
428        i = 0;
429        n = -1;
430        while( file[i] != 0)
431        {
432                if( file[i] == '.') n = i;
433                i++;
434        }
435       
436        if( n == -1) return -1;
437       
438        posterior = &(file[n]);
439       
440        for( i = 0; i < ntypes; i++)
441        {
442                if( strcmp( posterior, postfixes[i]) == 0) return i;
443        }
444       
445        return -1;
446}
447
448void DataLoader::free_file( void* resource, int type)
449{
450        if( type <= ntypes && type >= 0) free_funcs[type]( resource);
451}
452
453void* DataLoader::get_placeholder( int type)
454{
455        if( type <= ntypes && type >= 0) return placeholders[type];
456        else return NULL;
457}
Note: See TracBrowser for help on using the repository browser.