1 | // This file is a part of Framsticks GDK library. |
---|
2 | // Copyright (C) 2002-2006 Szymon Ulatowski. See LICENSE.txt for details. |
---|
3 | // Refer to http://www.frams.alife.pl/ for further information. |
---|
4 | |
---|
5 | #ifndef _MULTIPARAMLOAD_H_ |
---|
6 | #define _MULTIPARAMLOAD_H_ |
---|
7 | |
---|
8 | #include <stdio.h> |
---|
9 | #include "param.h" |
---|
10 | #include "virtfile.h" |
---|
11 | |
---|
12 | /** "param" file parser for loading multiple objects. |
---|
13 | The loader can be configured to recognize multiple object types from object headers |
---|
14 | and automatically call ParamInterface::load for matching class. |
---|
15 | By using MultiParamLoader::go() function you can receive status events, they can be |
---|
16 | used to handle multiple object instances or parse complex files (see loadtest.cpp sample code). |
---|
17 | A simple MultiParamLoader::run() can be used if you need any events. |
---|
18 | */ |
---|
19 | class MultiParamLoader |
---|
20 | { |
---|
21 | VirtFILE *file; |
---|
22 | SListTempl<VirtFILE*> filestack; |
---|
23 | char ownfile; |
---|
24 | SList params; |
---|
25 | int status; |
---|
26 | SString lasterror, lastcomment, lastunknown; |
---|
27 | ParamInterface *lastclass; |
---|
28 | int breakcond; |
---|
29 | Param emptyparam; |
---|
30 | |
---|
31 | void init(); |
---|
32 | void load(); |
---|
33 | |
---|
34 | int maybeBreak(int cond) |
---|
35 | { status=cond; return breakcond & cond; } |
---|
36 | |
---|
37 | VirtFILE* popstack(); |
---|
38 | void clearstack(); |
---|
39 | |
---|
40 | public: |
---|
41 | MultiParamLoader() {init();} |
---|
42 | MultiParamLoader(VirtFILE *f) {init(); load(f);} |
---|
43 | MultiParamLoader(const char* filename) {init(); load(filename);} |
---|
44 | |
---|
45 | ~MultiParamLoader() {abort();} |
---|
46 | |
---|
47 | void reset(); |
---|
48 | |
---|
49 | void load(VirtFILE *f); |
---|
50 | void load(const char* filename); |
---|
51 | |
---|
52 | /** register the object class. classes' names will be matched with object headers ("xxx:" in the file) */ |
---|
53 | void addClass(ParamInterface *pi) {params+=pi;} |
---|
54 | void removeClass(ParamInterface *pi) {params-=pi;} |
---|
55 | void clearClasses() {params.clear();} |
---|
56 | |
---|
57 | /** to be used in the main loop: while(event=loader.go()) { ... } |
---|
58 | loader.go() will return on specified events (@see breakOn(), noBreakOn()) |
---|
59 | then you can handle the event and resume loading |
---|
60 | */ |
---|
61 | virtual int go(); |
---|
62 | /** same value as 'go()' */ |
---|
63 | int getStatus() {return status;} |
---|
64 | int finished() {return (status==Finished);} |
---|
65 | |
---|
66 | VirtFILE *getFile() {return file;} |
---|
67 | |
---|
68 | /** abort immediately and close the file if needed */ |
---|
69 | void abort(); |
---|
70 | /** @param conditions can be combined bitwise, eg. MultiParamLoader::BeforeObject | MultiParamLoader::OnComment |
---|
71 | @see BreakConfitions |
---|
72 | */ |
---|
73 | void breakOn(int conditions) {breakcond|=conditions;} |
---|
74 | void noBreakOn(int conditions) {breakcond&=~conditions;} |
---|
75 | /** |
---|
76 | - BeforeObject: found an object with recognized classname |
---|
77 | - AfterObject: the object was loaded into the registered class interface |
---|
78 | - BeforeUnknown: unknown (not registered) object header detected. |
---|
79 | @see getClass(), GetClassName() |
---|
80 | */ |
---|
81 | enum BreakConditions { Finished=0, BeforeObject=1, AfterObject=2, |
---|
82 | BeforeUnknown=4, OnComment=8, OnError=16, Loading=32 }; |
---|
83 | |
---|
84 | /** can be used BeforeObject and AfterObject */ |
---|
85 | ParamInterface *getClass() {return lastclass;} |
---|
86 | /** can be used BeforeUnknown, BeforeObject, AfterObject */ |
---|
87 | const SString& getClassName() {return lastunknown;} |
---|
88 | /** unknown object will be loaded if you set its class BeforeUnknown */ |
---|
89 | void setClass(ParamInterface *pi) {lastclass=pi;} |
---|
90 | /** can be used OnComment */ |
---|
91 | const SString& getComment() {return lastcomment;} |
---|
92 | /** can be used OnError */ |
---|
93 | const SString& getError() {return lasterror;} |
---|
94 | /** can be used BeforeObject and BeforeUnknown */ |
---|
95 | int loadObjectNow(ParamInterface *pi); |
---|
96 | /** can be used BeforeObject */ |
---|
97 | int loadObjectNow() {return loadObjectNow(getClass());} |
---|
98 | /** can be used BeforeObject and BeforeUnknown. |
---|
99 | object data will not be loaded. */ |
---|
100 | int skipObject() {return loadObjectNow(&emptyparam);} |
---|
101 | /** @return 1 if no errors */ |
---|
102 | int run(); |
---|
103 | |
---|
104 | void include(SString& filename); |
---|
105 | bool returnFromIncluded(); |
---|
106 | bool alreadyIncluded(const char* filename); |
---|
107 | |
---|
108 | }; |
---|
109 | |
---|
110 | #endif |
---|