ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

resourcereference.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/resourcereference.h"
00024 
00025 #include "engines/stark/debug.h"
00026 #include "engines/stark/resources/level.h"
00027 #include "engines/stark/resources/location.h"
00028 #include "engines/stark/services/global.h"
00029 #include "engines/stark/services/resourceprovider.h"
00030 #include "engines/stark/services/staticprovider.h"
00031 #include "engines/stark/services/services.h"
00032 
00033 namespace Stark {
00034 
00035 
00036 ResourceReference::PathElement::PathElement(Resources::Type type, uint16 index) :
00037         _type(type), _index(index) {
00038 }
00039 
00040 Common::String ResourceReference::PathElement::describe() const {
00041     return  Common::String::format("(%s idx %d)", _type.getName(), _index);
00042 }
00043 
00044 ResourceReference::ResourceReference() {
00045 }
00046 
00047 void ResourceReference::addPathElement(Resources::Type type, uint16 index) {
00048     _path.push_back(PathElement(type, index));
00049 }
00050 
00051 Resources::Object *ResourceReference::resolve() const {
00052     Resources::Object *level = nullptr;
00053     Resources::Object *resource = nullptr;
00054     for (uint i = 0; i < _path.size(); i++) {
00055         const PathElement &element = _path[i];
00056 
00057         switch (element.getType().get()) {
00058         case Resources::Type::kLevel:
00059             if (StarkStaticProvider->isStaticLocation()) {
00060                 resource = level = StarkStaticProvider->getLevel();
00061                 assert(resource->getIndex() == element.getIndex());
00062             } else if (element.getIndex()) {
00063                 resource = level = StarkResourceProvider->getLevel(element.getIndex());
00064             } else {
00065                 resource = level = StarkGlobal->getLevel();
00066             }
00067 
00068             if (!level) {
00069                 error("Level '%d' not found", element.getIndex());
00070             }
00071 
00072             break;
00073         case Resources::Type::kLocation:
00074             if (!level) {
00075                 error("Cannot resolve location '%d' without resolving a level first", element.getIndex());
00076             }
00077 
00078             if (StarkStaticProvider->isStaticLocation()) {
00079                 resource = StarkStaticProvider->getLocation();
00080                 assert(resource->getIndex() == element.getIndex());
00081             } else {
00082                 resource = StarkResourceProvider->getLocation(level->getIndex(), element.getIndex());
00083             }
00084 
00085             if (!resource) {
00086                 error("Location '%d' not found in level '%d'", element.getIndex(), level->getIndex());
00087             }
00088 
00089             break;
00090         default:
00091             assert(resource);
00092             resource = resource->findChildWithIndex(element.getType(), element.getIndex());
00093             break;
00094         }
00095     }
00096 
00097     return resource;
00098 }
00099 
00100 bool ResourceReference::canResolve() const {
00101     if (empty()) {
00102         return false;
00103     }
00104 
00105     Resources::Object *level = nullptr;
00106     for (uint i = 0; i < _path.size(); i++) {
00107         const PathElement &element = _path[i];
00108 
00109         switch (element.getType().get()) {
00110             case Resources::Type::kLevel:
00111                 if (element.getIndex()) {
00112                     level = StarkResourceProvider->getLevel(element.getIndex());
00113                 } else {
00114                     level = StarkGlobal->getLevel();
00115                 }
00116 
00117                 if (!level) {
00118                     return false;
00119                 }
00120 
00121                 break;
00122             case Resources::Type::kLocation: {
00123                 if (!level) {
00124                     return false;
00125                 }
00126 
00127                 Resources::Object *location = StarkResourceProvider->getLocation(level->getIndex(), element.getIndex());
00128 
00129                 if (!location) {
00130                     return false;
00131                 }
00132 
00133                 break;
00134             }
00135             default:
00136                 return true;
00137         }
00138     }
00139 
00140     return true;
00141 }
00142 
00143 bool ResourceReference::empty() const {
00144     return _path.empty();
00145 }
00146 
00147 Common::String ResourceReference::describe() const {
00148     Common::String desc;
00149 
00150     for (uint i = 0; i < _path.size(); i++) {
00151         desc += _path[i].describe();
00152 
00153         if (i != _path.size() - 1) {
00154             desc += " ";
00155         }
00156     }
00157 
00158     return desc;
00159 }
00160 
00161 void ResourceReference::buildFromResource(Resources::Object *resource) {
00162     Common::Array<PathElement> reversePath;
00163     while (resource && resource->getType() != Resources::Type::kRoot) {
00164         reversePath.push_back(PathElement(resource->getType(), resource->getIndex()));
00165 
00166         switch (resource->getType().get()) {
00167             case Resources::Type::kLocation: {
00168                 Resources::Location *location = Resources::Object::cast<Resources::Location>(resource);
00169                 resource = StarkResourceProvider->getLevelFromLocation(location);
00170                 break;
00171             }
00172             default:
00173                 resource = resource->findParent<Resources::Object>();
00174                 break;
00175         }
00176     }
00177 
00178     _path.clear();
00179     for (int i = reversePath.size() - 1; i >= 0; i--) {
00180         _path.push_back(reversePath[i]);
00181     }
00182 }
00183 
00184 void ResourceReference::loadFromStream(Common::ReadStream *stream) {
00185     _path.clear();
00186 
00187     uint32 pathSize = stream->readUint32LE();
00188     for (uint i = 0; i < pathSize; i++) {
00189         byte rawType = stream->readByte();
00190         Resources::Type type = Resources::Type((Resources::Type::ResourceType) (rawType));
00191         uint16 index = stream->readUint16LE();
00192 
00193         addPathElement(type, index);
00194     }
00195 }
00196 
00197 void ResourceReference::saveToStream(Common::WriteStream *stream) {
00198     stream->writeUint32LE(_path.size());
00199     for (uint i = 0; i < _path.size(); i++) {
00200         byte rawType = _path[i].getType().get();
00201         uint16 index = _path[i].getIndex();
00202 
00203         stream->writeByte(rawType);
00204         stream->writeUint16LE(index);
00205     }
00206 }
00207 
00208 } // End of namespace Stark


Generated on Sat Jul 20 2019 05:00:57 for ResidualVM by doxygen 1.7.1
curved edge   curved edge