[5] | 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 |
---|