STARK: Allow resolving resource references

This commit is contained in:
Bastien Bouclet
2015-01-01 21:25:51 +01:00
parent 51730689c1
commit 5331b52226
9 changed files with 128 additions and 15 deletions
-3
View File
@@ -35,9 +35,6 @@ ArchiveLoader::LoadedArchive::LoadedArchive(const Common::String& archiveName) :
}
_root = importResources();
// Resource lifecycle update
_root->onAllLoaded();
}
ArchiveLoader::LoadedArchive::~LoadedArchive() {
+29 -2
View File
@@ -46,6 +46,9 @@ void ResourceProvider::initGlobal() {
Root *root = _archiveLoader->useRoot<Root>("x.xarc");
_global->setRoot(root);
// Resource lifecycle update
root->onAllLoaded();
// Find the global level node
Level *global = root->findChildWithSubtype<Level>(1);
@@ -58,6 +61,9 @@ void ResourceProvider::initGlobal() {
_stateProvider->restoreLevelState(global);
_global->setLevel(global);
// Resource lifecycle update
global->onAllLoaded();
//TODO: Retrieve the inventory and April from the global tree
}
@@ -82,8 +88,29 @@ Current *ResourceProvider::findLocation(uint16 level, uint16 location) {
return nullptr;
}
Level *ResourceProvider::getLevel(uint16 level) {
Current *current = findLevel(level);
if (current) {
return current->getLevel();
}
return nullptr;
}
Location *ResourceProvider::getLocation(uint16 level, uint16 location) {
Current *current = findLocation(level, location);
if (current) {
return current->getLocation();
}
return nullptr;
}
void ResourceProvider::requestLocationChange(uint16 level, uint16 location) {
Current *currentLocation = new Current();
_locations.push_back(currentLocation);
// Retrieve the level archive name
Root *root = _global->getRoot();
@@ -97,6 +124,7 @@ void ResourceProvider::requestLocationChange(uint16 level, uint16 location) {
// If we just loaded a resource tree, restore its state
if (newlyLoaded) {
_stateProvider->restoreLevelState(currentLocation->getLevel());
currentLocation->getLevel()->onAllLoaded();
}
// Retrieve the location archive name
@@ -111,10 +139,9 @@ void ResourceProvider::requestLocationChange(uint16 level, uint16 location) {
// If we just loaded a resource tree, restore its state
if (newlyLoaded) {
_stateProvider->restoreLocationState(currentLocation->getLevel(), currentLocation->getLocation());
currentLocation->getLocation()->onAllLoaded();
}
_locations.push_back(currentLocation);
_locationChangeRequest = true;
}
+6
View File
@@ -131,6 +131,12 @@ public:
/** Release the global and current resources */
void shutdown();
/** Obtain the root resource for a loaded level */
Level *getLevel(uint16 level);
/** Obtain the root resource for a loaded location */
Location *getLocation(uint16 level, uint16 location);
private:
typedef Common::List<Current *> CurrentList;
+33
View File
@@ -21,7 +21,12 @@
*/
#include "engines/stark/resourcereference.h"
#include "engines/stark/debug.h"
#include "engines/stark/resources/level.h"
#include "engines/stark/resources/location.h"
#include "engines/stark/resourceprovider.h"
#include "engines/stark/stark.h"
namespace Stark {
@@ -41,6 +46,34 @@ void ResourceReference::addPathElement(ResourceType type, uint16 index) {
_path.push_back(PathElement(type, index));
}
Resource *ResourceReference::resolve() {
ResourceProvider *resourceProvider = StarkServices::instance().resourceProvider;
Global *global = StarkServices::instance().global;
Resource *resource = nullptr;
for (uint i = 0; i < _path.size(); i++) {
PathElement element = _path[i];
switch (element.getType().get()) {
case ResourceType::kLevel:
if (element.getIndex()) {
resource = resourceProvider->getLevel(element.getIndex());
} else {
resource = global->getLevel();
}
break;
case ResourceType::kLocation:
resource = resourceProvider->getLocation(resource->getIndex(), element.getIndex());
break;
default:
resource = resource->findChildWithIndex(element.getType(), element.getIndex());
break;
}
}
return resource;
}
Common::String ResourceReference::describe() {
Common::String desc;
+16
View File
@@ -44,6 +44,19 @@ public:
Common::String describe();
void addPathElement(ResourceType type, uint16 index);
Resource *resolve();
template <class T>
T* resolve() {
Resource *resource = resolve();
if (resource && resource->getType() != T::TYPE) {
error("Unexpected resource type when resolving reference %s instad of %s",
resource->getType().getName(), ResourceType(T::TYPE).getName());
}
return (T *) resource;
}
private:
class PathElement {
@@ -51,6 +64,9 @@ private:
PathElement(ResourceType type, uint16 index);
Common::String describe();
ResourceType getType() const { return _type; }
uint16 getIndex() const { return _index; }
private:
ResourceType _type;
uint16 _index;
+13
View File
@@ -188,6 +188,19 @@ void Resource::print(uint depth) {
}
}
Resource *Resource::findChildWithIndex(ResourceType type, uint16 index, int subType) {
for (uint i = 0; i < _children.size(); i++) {
if (_children[i]->getType() == type
&& (_children[i]->getSubType() == subType || subType == -1)
&& _children[i]->getIndex() == index) {
// Found a matching child
return _children[i];
}
}
return nullptr;
}
template<>
Common::Array<Resource *> Resource::listChildren<Resource>(int subType) {
assert(subType == -1);
+3 -10
View File
@@ -197,6 +197,8 @@ public:
*/
virtual void onPreDestroy();
Resource *findChildWithIndex(ResourceType type, uint16 index, int subType = -1);
template<class T>
T *findChild(bool mustBeUnique = true);
@@ -280,16 +282,7 @@ T *Resource::findChildWithSubtype(int subType, bool mustBeUnique) {
template <class T>
T *Resource::findChildWithIndex(uint16 index, int subType) {
for (uint i = 0; i < _children.size(); i++) {
if (_children[i]->getType() == T::TYPE
&& (_children[i]->getSubType() == subType || subType == -1)
&& _children[i]->getIndex() == index) {
// Found a matching child
return (T *)_children[i];
}
}
return nullptr;
return (T *)findChildWithIndex(T::TYPE, index, subType);
}
} // End of namespace Stark
+12
View File
@@ -37,6 +37,10 @@
#include "common/system.h"
#include "audio/mixer.h"
namespace Common {
DECLARE_SINGLETON(Stark::StarkServices);
}
namespace Stark {
StarkEngine::StarkEngine(OSystem *syst, const ADGameDescription *gameDesc) :
@@ -69,6 +73,8 @@ StarkEngine::~StarkEngine() {
delete _global;
delete _stateProvider;
delete _archiveLoader;
StarkServices::destroy();
}
Common::Error StarkEngine::run() {
@@ -83,6 +89,12 @@ Common::Error StarkEngine::run() {
_global = new Global();
_resourceProvider = new ResourceProvider(_archiveLoader, _stateProvider, _global);
// Setup the public services
StarkServices &services = StarkServices::instance();
services.archiveLoader = _archiveLoader;
services.resourceProvider = _resourceProvider;
services.global = _global;
// Load global resources
_resourceProvider->initGlobal();
+16
View File
@@ -47,6 +47,22 @@ class ArchiveLoader;
class StateProvider;
class ResourceProvider;
/**
* Public services available as a singleton
*/
class StarkServices : public Common::Singleton<StarkServices> {
public:
StarkServices() {
global = nullptr;
archiveLoader = nullptr;
resourceProvider = nullptr;
}
Global *global;
ArchiveLoader *archiveLoader;
ResourceProvider *resourceProvider;
};
class StarkEngine : public Engine {
public:
StarkEngine(OSystem *syst, const ADGameDescription *gameDesc);