STARK: Allow resolving resource references
This commit is contained in:
parent
51730689c1
commit
5331b52226
9 changed files with 128 additions and 15 deletions
|
@ -35,9 +35,6 @@ ArchiveLoader::LoadedArchive::LoadedArchive(const Common::String& archiveName) :
|
||||||
}
|
}
|
||||||
|
|
||||||
_root = importResources();
|
_root = importResources();
|
||||||
|
|
||||||
// Resource lifecycle update
|
|
||||||
_root->onAllLoaded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchiveLoader::LoadedArchive::~LoadedArchive() {
|
ArchiveLoader::LoadedArchive::~LoadedArchive() {
|
||||||
|
|
|
@ -46,6 +46,9 @@ void ResourceProvider::initGlobal() {
|
||||||
Root *root = _archiveLoader->useRoot<Root>("x.xarc");
|
Root *root = _archiveLoader->useRoot<Root>("x.xarc");
|
||||||
_global->setRoot(root);
|
_global->setRoot(root);
|
||||||
|
|
||||||
|
// Resource lifecycle update
|
||||||
|
root->onAllLoaded();
|
||||||
|
|
||||||
// Find the global level node
|
// Find the global level node
|
||||||
Level *global = root->findChildWithSubtype<Level>(1);
|
Level *global = root->findChildWithSubtype<Level>(1);
|
||||||
|
|
||||||
|
@ -58,6 +61,9 @@ void ResourceProvider::initGlobal() {
|
||||||
_stateProvider->restoreLevelState(global);
|
_stateProvider->restoreLevelState(global);
|
||||||
_global->setLevel(global);
|
_global->setLevel(global);
|
||||||
|
|
||||||
|
// Resource lifecycle update
|
||||||
|
global->onAllLoaded();
|
||||||
|
|
||||||
//TODO: Retrieve the inventory and April from the global tree
|
//TODO: Retrieve the inventory and April from the global tree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +88,29 @@ Current *ResourceProvider::findLocation(uint16 level, uint16 location) {
|
||||||
return nullptr;
|
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) {
|
void ResourceProvider::requestLocationChange(uint16 level, uint16 location) {
|
||||||
Current *currentLocation = new Current();
|
Current *currentLocation = new Current();
|
||||||
|
_locations.push_back(currentLocation);
|
||||||
|
|
||||||
// Retrieve the level archive name
|
// Retrieve the level archive name
|
||||||
Root *root = _global->getRoot();
|
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 we just loaded a resource tree, restore its state
|
||||||
if (newlyLoaded) {
|
if (newlyLoaded) {
|
||||||
_stateProvider->restoreLevelState(currentLocation->getLevel());
|
_stateProvider->restoreLevelState(currentLocation->getLevel());
|
||||||
|
currentLocation->getLevel()->onAllLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the location archive name
|
// 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 we just loaded a resource tree, restore its state
|
||||||
if (newlyLoaded) {
|
if (newlyLoaded) {
|
||||||
_stateProvider->restoreLocationState(currentLocation->getLevel(), currentLocation->getLocation());
|
_stateProvider->restoreLocationState(currentLocation->getLevel(), currentLocation->getLocation());
|
||||||
|
currentLocation->getLocation()->onAllLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
_locations.push_back(currentLocation);
|
|
||||||
|
|
||||||
_locationChangeRequest = true;
|
_locationChangeRequest = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,12 @@ public:
|
||||||
/** Release the global and current resources */
|
/** Release the global and current resources */
|
||||||
void shutdown();
|
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:
|
private:
|
||||||
typedef Common::List<Current *> CurrentList;
|
typedef Common::List<Current *> CurrentList;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "engines/stark/resourcereference.h"
|
#include "engines/stark/resourcereference.h"
|
||||||
|
|
||||||
#include "engines/stark/debug.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 {
|
namespace Stark {
|
||||||
|
|
||||||
|
@ -41,6 +46,34 @@ void ResourceReference::addPathElement(ResourceType type, uint16 index) {
|
||||||
_path.push_back(PathElement(type, 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 ResourceReference::describe() {
|
||||||
Common::String desc;
|
Common::String desc;
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,19 @@ public:
|
||||||
Common::String describe();
|
Common::String describe();
|
||||||
|
|
||||||
void addPathElement(ResourceType type, uint16 index);
|
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:
|
private:
|
||||||
class PathElement {
|
class PathElement {
|
||||||
|
@ -51,6 +64,9 @@ private:
|
||||||
PathElement(ResourceType type, uint16 index);
|
PathElement(ResourceType type, uint16 index);
|
||||||
Common::String describe();
|
Common::String describe();
|
||||||
|
|
||||||
|
ResourceType getType() const { return _type; }
|
||||||
|
uint16 getIndex() const { return _index; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResourceType _type;
|
ResourceType _type;
|
||||||
uint16 _index;
|
uint16 _index;
|
||||||
|
|
|
@ -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<>
|
template<>
|
||||||
Common::Array<Resource *> Resource::listChildren<Resource>(int subType) {
|
Common::Array<Resource *> Resource::listChildren<Resource>(int subType) {
|
||||||
assert(subType == -1);
|
assert(subType == -1);
|
||||||
|
|
|
@ -197,6 +197,8 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void onPreDestroy();
|
virtual void onPreDestroy();
|
||||||
|
|
||||||
|
Resource *findChildWithIndex(ResourceType type, uint16 index, int subType = -1);
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T *findChild(bool mustBeUnique = true);
|
T *findChild(bool mustBeUnique = true);
|
||||||
|
|
||||||
|
@ -280,16 +282,7 @@ T *Resource::findChildWithSubtype(int subType, bool mustBeUnique) {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T *Resource::findChildWithIndex(uint16 index, int subType) {
|
T *Resource::findChildWithIndex(uint16 index, int subType) {
|
||||||
for (uint i = 0; i < _children.size(); i++) {
|
return (T *)findChildWithIndex(T::TYPE, index, subType);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Stark
|
} // End of namespace Stark
|
||||||
|
|
|
@ -37,6 +37,10 @@
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
#include "audio/mixer.h"
|
#include "audio/mixer.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
|
DECLARE_SINGLETON(Stark::StarkServices);
|
||||||
|
}
|
||||||
|
|
||||||
namespace Stark {
|
namespace Stark {
|
||||||
|
|
||||||
StarkEngine::StarkEngine(OSystem *syst, const ADGameDescription *gameDesc) :
|
StarkEngine::StarkEngine(OSystem *syst, const ADGameDescription *gameDesc) :
|
||||||
|
@ -69,6 +73,8 @@ StarkEngine::~StarkEngine() {
|
||||||
delete _global;
|
delete _global;
|
||||||
delete _stateProvider;
|
delete _stateProvider;
|
||||||
delete _archiveLoader;
|
delete _archiveLoader;
|
||||||
|
|
||||||
|
StarkServices::destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error StarkEngine::run() {
|
Common::Error StarkEngine::run() {
|
||||||
|
@ -83,6 +89,12 @@ Common::Error StarkEngine::run() {
|
||||||
_global = new Global();
|
_global = new Global();
|
||||||
_resourceProvider = new ResourceProvider(_archiveLoader, _stateProvider, _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
|
// Load global resources
|
||||||
_resourceProvider->initGlobal();
|
_resourceProvider->initGlobal();
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,22 @@ class ArchiveLoader;
|
||||||
class StateProvider;
|
class StateProvider;
|
||||||
class ResourceProvider;
|
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 {
|
class StarkEngine : public Engine {
|
||||||
public:
|
public:
|
||||||
StarkEngine(OSystem *syst, const ADGameDescription *gameDesc);
|
StarkEngine(OSystem *syst, const ADGameDescription *gameDesc);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue