00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef STARK_RESOURCES_RESOURCE_H
00024 #define STARK_RESOURCES_RESOURCE_H
00025
00026 #include "common/array.h"
00027 #include "common/str.h"
00028
00029 namespace Stark {
00030
00031 namespace Formats {
00032 class XRCReadStream;
00033 }
00034 class ResourceSerializer;
00035
00036 namespace Resources {
00037
00038 class Type {
00039 public:
00040 enum ResourceType {
00041 kInvalid = 0,
00042 kRoot = 1,
00043 kLevel = 2,
00044 kLocation = 3,
00045 kLayer = 4,
00046 kCamera = 5,
00047 kFloor = 6,
00048 kFloorFace = 7,
00049 kItem = 8,
00050 kScript = 9,
00051 kAnimHierarchy = 10,
00052 kAnim = 11,
00053 kDirection = 12,
00054 kImage = 13,
00055 kAnimScript = 14,
00056 kAnimScriptItem = 15,
00057 kSoundItem = 16,
00058 kPath = 17,
00059 kFloorField = 18,
00060 kBookmark = 19,
00061 kKnowledgeSet = 20,
00062 kKnowledge = 21,
00063 kCommand = 22,
00064 kPATTable = 23,
00065 kContainer = 26,
00066 kDialog = 27,
00067 kSpeech = 29,
00068 kLight = 30,
00069 kCursor = 31,
00070 kBonesMesh = 32,
00071 kScroll = 33,
00072 kFMV = 34,
00073 kLipSync = 35,
00074 kAnimSoundTrigger = 36,
00075 kString = 37,
00076 kTextureSet = 38
00077 };
00078
00079 Type();
00080 Type(ResourceType type);
00081
00082 ResourceType get() const;
00083 const char *getName() const;
00084
00085 bool operator==(const Type &other) const {
00086 return other._type == _type;
00087 }
00088
00089 bool operator!=(const Type &other) const {
00090 return other._type != _type;
00091 }
00092
00093 bool operator==(const Type::ResourceType other) const {
00094 return other == _type;
00095 }
00096
00097 bool operator!=(const Type::ResourceType other) const {
00098 return other != _type;
00099 }
00100
00101 private:
00102 ResourceType _type;
00103 };
00104
00144 class Object {
00145 public:
00146 virtual ~Object();
00147
00149 Type getType() const { return _type; }
00150
00152 byte getSubType() const { return _subType; }
00153
00155 uint16 getIndex() const { return _index; }
00156
00158 Common::String getIndexAsString() const { return Common::String::format("%02x", _index); }
00159
00161 Common::String getName() const { return _name; }
00162
00166 virtual void readData(Formats::XRCReadStream *stream);
00167
00171 virtual void saveLoad(ResourceSerializer *serializer);
00172
00178 virtual void saveLoadCurrent(ResourceSerializer *serializer);
00179
00185 virtual void onPostRead();
00186
00192 virtual void onAllLoaded();
00193
00197 virtual void onEnterLocation();
00198
00202 virtual void onGameLoop();
00203
00207 virtual void onEnginePause(bool pause);
00208
00212 virtual void onExitLocation();
00213
00217 virtual void onPreDestroy();
00218
00222 template<class T>
00223 static T *cast(Object *resource);
00224
00226 template<class T>
00227 T *findParent();
00228
00230 Object *findChildWithIndex(Type type, uint16 index, int subType = -1) const;
00231
00233 Object *findChildWithOrder(Type type, uint16 order, int subType = -1) const;
00234
00236 Object *findChildWithName(Type type, const Common::String &name, int subType = -1) const;
00237
00239 template<class T>
00240 T *findChild(bool mustBeUnique = true) const;
00241
00243 template<class T>
00244 T *findChildWithSubtype(int subType, bool mustBeUnique = true) const;
00245
00247 template<class T>
00248 T *findChildWithIndex(uint16 index, int subType = -1) const;
00249
00251 template<class T>
00252 T *findChildWithOrder(uint16 order, int subType = -1) const;
00253
00255 template<class T>
00256 T *findChildWithName(const Common::String &name, int subType = -1) const;
00257
00259 template<class T>
00260 Common::Array<T *> listChildren(int subType = -1) const;
00261
00263 template<class T>
00264 Common::Array<T *> listChildrenRecursive(int subType = -1);
00265
00267 void addChild(Object *child);
00268
00270 virtual void print(uint depth = 0);
00271
00272 protected:
00273 Object(Object *parent, byte subType, uint16 index, const Common::String &name);
00274
00275 void printWithDepth(uint depth, const Common::String &string) const;
00276 void printDescription(uint depth) const;
00277 virtual void printData();
00278
00279 Type _type;
00280 byte _subType;
00281 uint16 _index;
00282 Common::String _name;
00283
00284 Object *_parent;
00285 Common::Array<Object *> _children;
00286 };
00287
00294 class UnimplementedResource : public Object {
00295 public:
00296 UnimplementedResource(Object *parent, Type type, byte subType, uint16 index, const Common::String &name);
00297 virtual ~UnimplementedResource();
00298
00299 protected:
00300 void readData(Formats::XRCReadStream *stream) override;
00301 void printData() override;
00302
00303 uint32 _dataLength;
00304 byte *_data;
00305 };
00306
00307 template <class T>
00308 T* Object::cast(Object *resource) {
00309 if (resource && resource->_type != T::TYPE) {
00310 error("Unexpected resource type when casting resource %s instead of %s",
00311 resource->_type.getName(), Type(T::TYPE).getName());
00312 }
00313
00314 return (T *) resource;
00315 }
00316
00317 template<>
00318 Object *Object::cast<Object>(Object *resource);
00319
00320 template<class T>
00321 T *Object::findParent() {
00322 if (getType() == T::TYPE) {
00323 return cast<T>(this);
00324 } else if (!_parent) {
00325 return nullptr;
00326 } else {
00327 return _parent->findParent<T>();
00328 }
00329 }
00330
00331 template<>
00332 Object *Object::findParent();
00333
00334 template <class T>
00335 Common::Array<T *> Object::listChildren(int subType) const {
00336 Common::Array<T *> list;
00337
00338 for (uint i = 0; i < _children.size(); i++) {
00339 if (_children[i]->getType() == T::TYPE
00340 && (_children[i]->getSubType() == subType || subType == -1)) {
00341
00342 list.push_back(Object::cast<T>(_children[i]));
00343 }
00344 }
00345
00346 return list;
00347 }
00348
00349 template<class T>
00350 Common::Array<T *> Object::listChildrenRecursive(int subType) {
00351 Common::Array<T *> list;
00352
00353 for (uint i = 0; i < _children.size(); i++) {
00354 if (_children[i]->getType() == T::TYPE
00355 && (_children[i]->getSubType() == subType || subType == -1)) {
00356
00357 list.push_back(Object::cast<T>(_children[i]));
00358 }
00359
00360
00361 list.push_back(_children[i]->listChildrenRecursive<T>(subType));
00362 }
00363
00364 return list;
00365 }
00366
00367 template<>
00368 Common::Array<Object *> Object::listChildren<Object>(int subType) const;
00369
00370 template<class T>
00371 T *Object::findChild(bool mustBeUnique) const {
00372 return findChildWithSubtype<T>(-1, mustBeUnique);
00373 }
00374
00375 template <class T>
00376 T *Object::findChildWithSubtype(int subType, bool mustBeUnique) const {
00377 Common::Array<T *> list = listChildren<T>(subType);
00378
00379 if (list.empty()) {
00380 return nullptr;
00381 }
00382
00383 if (list.size() > 1 && mustBeUnique) {
00384 error("Several children resources matching criteria type = %s, subtype = %d", Type(T::TYPE).getName(), subType);
00385 }
00386
00387 return list.front();
00388 }
00389
00390 template <class T>
00391 T *Object::findChildWithIndex(uint16 index, int subType) const {
00392 return Object::cast<T>(findChildWithIndex(T::TYPE, index, subType));
00393 }
00394
00395 template <class T>
00396 T *Object::findChildWithOrder(uint16 order, int subType) const {
00397 return Object::cast<T>(findChildWithOrder(T::TYPE, order, subType));
00398 }
00399
00400 template<class T>
00401 T *Object::findChildWithName(const Common::String &name, int subType) const {
00402 return Object::cast<T>(findChildWithName(T::TYPE, name, subType));
00403 }
00404
00405 }
00406 }
00407
00408 #endif // STARK_RESOURCES_RESOURCE_H