00001 #ifndef FIDOCSCENE_H
00002 #define FIDOCSCENE_H
00003 #include "FIDocNode.h"
00004 #include "FIFileDoc.h"
00005 #include "FITypeDesc.h"
00006 #include <SceneGraph/SGScene.h>
00007
00008
00009 namespace Spr{;
00010
00011
00012 class SPR_DLL FIBaseLoader:public UTRefCount{
00013 public:
00014
00015 virtual UTString GetNodeType() const =0;
00016
00017 virtual void Load(class FILoadScene* context)=0;
00018
00019 virtual void Loaded(class FILoadScene* context){}
00020 };
00021 template <class T, bool bAdd=true, bool bCont=true> class FIObjectLoader: public FIBaseLoader{
00022 public:
00023 typedef T TLoaded;
00024 void Create(class FILoadScene* context, UTRef<TLoaded>& t){
00025 t = new TLoaded;
00026 t->SetName(context->docs.Top()->GetName().c_str(), context->scene);
00027 }
00028
00029 virtual UTString GetNodeType() const{
00030 return TLoaded::GetTypeInfoStatic()->ClassName()+2;
00031 }
00032
00033 virtual void Load(class FILoadScene* context){
00034 UTRef<TLoaded> t=NULL;
00035 Create(context, t);
00036 t->doc = context->docs.Top();
00037 t->SetName(t->doc->GetName().c_str(), context->scene);
00038 if (bAdd) context->AddObject(t);
00039 if (bCont) context->AddContainer(t);
00040 if (!LoadData(context, t)){
00041 if (bAdd){
00042 context->CancelAddObject();
00043 }
00044 }
00045 }
00046
00047 virtual bool LoadData(class FILoadScene* context, TLoaded* t)=0;
00048 };
00049
00050 template <class P=SGFrame> class FIOtherLoader: public FIBaseLoader{
00051 public:
00052
00053 virtual void Load(class FILoadScene* context){
00054 P* p=NULL;
00055 context->objects.Find(p);
00056 Load(context, p);
00057 }
00058 virtual void Load(class FILoadScene* context, P* p)=0;
00059
00060 };
00061
00062 inline bool operator < (const FIBaseLoader& t1, const FIBaseLoader& t2){
00063 return t1.GetNodeType().compare(t2.GetNodeType()) < 0;
00064 }
00065
00066 class SPR_DLL FILoders:public std::multiset<FIBaseLoader*, UTContentsLess<FIBaseLoader*> >{
00067 public:
00068 class FITypeLoaderKey:public FIBaseLoader{
00069 UTString* key;
00070 public:
00071 FITypeLoaderKey(UTString& k):key(&k){}
00072 virtual UTString GetNodeType() const{ return *key; }
00073 virtual void Load(FILoadScene* context){}
00074 };
00075 iterator LowerBound(UTString s){
00076 return lower_bound(&FITypeLoaderKey(s));
00077 }
00078 iterator UpperBound(UTString s){
00079 return upper_bound(&FITypeLoaderKey(s));
00080 }
00081 std::pair<iterator, iterator> EqualRange(UTString s){
00082 return equal_range(&FITypeLoaderKey(s));
00083 }
00084 void Erase(UTString s){
00085 std::pair<iterator, iterator> r = EqualRange(s);
00086 erase(r.first, r.second);
00087 }
00088 };
00089
00090 class SPR_DLL FIReferenceBase:public UTRefCount{
00091 protected:
00092 SGObject* Find(SGScene* s);
00093
00094 UTString name;
00095 public:
00096 virtual ~FIReferenceBase(){}
00097
00098 virtual void SolveReference(SGScene* s)=0;
00099 };
00100 class SPR_DLL FIReferences:public std::vector< UTRef<FIReferenceBase> >{
00101 };
00102
00103 template <class T>
00104 class SPR_DLL FIReference:public FIReferenceBase{
00105
00106 UTRef<T>* reference;
00107
00108 public:
00109 FIReference(UTRef<T>& t, UTString n): reference(&t) { name=n; }
00110
00111 virtual void SolveReference(SGScene* s){
00112 T* t = (T*)Find(s);
00113 *reference = t;
00114
00115
00116 }
00117 };
00118 template <class CT>
00119 class SPR_DLL FIReferenceVector:public FIReferenceBase{
00120
00121 CT* container;
00122 typedef TYPENAME CT::value_type T;
00123 int pos;
00124 public:
00125 FIReferenceVector(CT& c, int p, UTString n): container(&c), pos(p) { name=n; }
00126
00127 virtual void SolveReference(SGScene* s){
00128 T t = T(UTRef<SGObject>(Find(s)));
00129 (*container)[pos] = t;
00130 }
00131 };
00132 template <class T>
00133 FIReference<T>* createFIReference(UTRef<T>& t, UTString n){
00134 return new FIReference<T>(t, n);
00135 }
00136 template <class CT>
00137 FIReferenceVector<CT>* createFIReference(CT& ct, int p, UTString n){
00138 return new FIReferenceVector<CT>(ct, p, n);
00139 }
00140
00141 class SPR_DLL FILink: public SGObject{
00142 public:
00143 SGOBJECTDEF(FILink);
00144 UTString linkName;
00145 };
00146 class SGObject;
00147 class SPR_DLL FIObjectAdder{
00148 public:
00149
00150 SGObjects containers;
00151
00152 SGObjects objects;
00153
00154 void Link(SGScene* scene);
00155 void Add(SGObject* obj);
00156 void Add(UTString name);
00157 };
00158 class SPR_DLL FIObjectAdders:public UTStack<FIObjectAdder>{
00159 public:
00160 };
00161
00162
00163
00164
00165
00166
00167 class SPR_DLL FILoadScene:public UTRefCount{
00168
00169 FILoders loaders;
00170
00171
00172
00173 FIObjectAdders adders;
00174
00175
00176
00177
00178 FIObjectAdders adderStack;
00179
00180 SGObjects containers;
00181 public:
00182
00183
00184
00185 UTString fileName;
00186
00187 FIDocNodes docs;
00188
00189 UTRef<SGScene> scene;
00190
00191 SGObjects objects;
00192
00193 void AddObject(SGObject* obj);
00194
00195 void AddObject(UTString name);
00196
00197 void CancelAddObject();
00198
00199 void AddContainer(SGObject* cont){
00200 containers.Push(cont);
00201 }
00202
00203 bool PushContainer();
00204
00205 void PopContainer();
00206
00207
00208
00209
00210
00211 virtual void Load(SGScene* s, SGObject* obj, FIFileDoc* fileDoc);
00212 virtual void Load(SGScene* s, FIFileDoc* fileDoc);
00213 virtual void Load(SGScene* s, SGObject* obj, FIDocNodes& docs);
00214 virtual void Load(SGScene* s, FIDocNodes& docs);
00215
00216 void Register(FIBaseLoader* l){ loaders.insert(l); }
00217
00218 void Erase(UTString k){ loaders.Erase(k); }
00219
00220 virtual void LoadRecursive();
00221
00222
00223
00224 protected:
00225
00226 void SolveReferences();
00227
00228 void AddObjects();
00229 };
00230
00231
00232 class FIBaseSaver:public UTRefCount{
00233 public:
00234 virtual UTString GetType() const =0;
00235 virtual UTString GetNodeType() const { return GetType().substr(2); }
00236 virtual void Save(class FISaveScene* ctx, SGObject* target){}
00237 };
00238 inline bool operator < (const FIBaseSaver& t1, const FIBaseSaver& t2){
00239 return t1.GetType().compare(t2.GetType()) < 0;
00240 }
00241
00242 template <class T, bool bAdd=true, bool bCont=true> class FIObjectSaver: public FIBaseSaver{
00243 public:
00244 typedef T TSaved;
00245
00246 virtual UTString GetType() const {
00247 return TSaved::GetTypeInfoStatic()->ClassName();
00248 }
00249
00250 virtual void SaveData(class FISaveScene* ctx, FIDocNodeBase* doc, TSaved* target)=0;
00251
00252 virtual void Save(class FISaveScene* ctx, SGObject* target){
00253 TSaved* t = (TSaved*) target;
00254 UTRef<FIDocNodeBase> doc = t->doc;
00255 if (!doc) doc = ctx->CreateDocNode(GetNodeType(), t);
00256 doc->SetName(target->GetName());
00257 doc->ClearChildren();
00258 SaveData(ctx, doc, t);
00259 ctx->AddSavedObject(target);
00260 if (bAdd) ctx->docs.Top()->AddChild(doc);
00261 if (bCont){
00262 ctx->docs.Push(doc);
00263 for(unsigned i=0; i<t->NChildObjects(); ++i){
00264 if(ctx->IsSavedObject(t->ChildObject(i))){
00265 ctx->SaveReference(t->ChildObject(i));
00266 }else{
00267 ctx->SaveRecursive(t->ChildObject(i));
00268 }
00269 }
00270 for(unsigned i=0; i<t->NReferenceObjects(); ++i){
00271 ctx->SaveReference(t->ReferenceObject(i));
00272 }
00273 ctx->docs.Pop();
00274 }
00275 }
00276 };
00277
00278
00279 class FISavers:public std::set<FIBaseSaver*, UTContentsLess<FIBaseSaver*> >{
00280 public:
00281 class FITypeSaverKey:public FIBaseSaver{
00282 UTString* key;
00283 public:
00284 FITypeSaverKey(UTString& k):key(&k){}
00285 virtual UTString GetType() const{ return *key; }
00286 virtual void Save(FISaveScene* context, SGObject* target){}
00287 };
00288 iterator Find(UTString s){
00289 return find(&FITypeSaverKey(s));
00290 }
00291 };
00292
00293
00294 class SPR_DLL FISaveScene:public UTRefCount{
00295 protected:
00296
00297 FISavers savers;
00298
00299 virtual UTRef<FIDocNodeBase> CreateDocNodeImp(UTString type)=0;
00300 public:
00301
00302 UTRef<SGScene> scene;
00303
00304 FIDocNodes docs;
00305
00306 std::set<SGObject*> savedObjects;
00307
00308 virtual UTRef<FIDocNodeBase> CreateDocNode(UTString type, SGObject* o=NULL){
00309 UTRef<FIDocNodeBase> doc = CreateDocNodeImp(type);
00310 if (o){
00311 doc->SetName(o->GetName());
00312 if (type.compare("REF")!=0) o->doc = doc;
00313 }
00314 return doc;
00315 }
00316
00317 virtual void Save(FIDocNodeBase* doc, SGScene* s, SGObject* obj=NULL);
00318
00319 virtual void SaveRecursive(SGObject* obj);
00320
00321 virtual void SaveReference(SGObject* obj);
00322
00323
00324 void Register(FIBaseSaver* s){ savers.insert(s); }
00325
00326 void AddSavedObject(SGObject * o){
00327 if (!savedObjects.insert(o).second){
00328 DSTR << "Fail to insert " << o->GetTypeInfo()->ClassName() << ":" << o->GetName() << std::endl;
00329 }
00330 }
00331
00332 bool IsSavedObject(SGObject * o){
00333 return savedObjects.find(o) != savedObjects.end();
00334 }
00335 };
00336
00337 #define DEF_REGISTER_LOADER(cls) \
00338 void RegisterLoaderFor##cls(FILoadScene* l){ \
00339 static cls##Loader load_##cls; \
00340 l->Register(&load_##cls); \
00341 }
00342
00343 #define DEF_REGISTER_SAVER(cls) \
00344 void RegisterSaverFor##cls(FISaveScene* s){ \
00345 static cls##Saver save_##cls; \
00346 s->Register(&save_##cls); \
00347 }
00348
00349 #define DEF_REGISTER_BOTH(cls) DEF_REGISTER_SAVER(cls) DEF_REGISTER_LOADER(cls)
00350
00351 #define REGISTER_LOADER(l, cls) \
00352 extern void RegisterLoaderFor##cls(FILoadScene* ld); \
00353 RegisterLoaderFor##cls(l); \
00354
00355 #define REGISTER_SAVER(s, cls) \
00356 extern void RegisterSaverFor##cls(FISaveScene* sv); \
00357 RegisterSaverFor##cls(s); \
00358
00359 }
00360 #endif