Skip to content

Commit

Permalink
More asset management refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Feb 15, 2015
1 parent b402320 commit 83849b7
Show file tree
Hide file tree
Showing 29 changed files with 333 additions and 182 deletions.
38 changes: 36 additions & 2 deletions code/Modules/Assets/Assets.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,42 @@ Assets::IsValid() {
return nullptr != state;
}

//------------------------------------------------------------------------------
const class AssetsSetup&
Assets::AssetsSetup() {
o_assert_dbg(IsValid());
return state->setup;
}

//------------------------------------------------------------------------------
void
Assets::AttachLoader(const Ptr<AssetLoader>& loader) {
o_assert_dbg(IsValid());
state->loaderRegistry.AttachLoader(loader);
}

//------------------------------------------------------------------------------
void
Assets::DetachLoader(const Ptr<AssetLoader>& loader) {
o_assert_dbg(IsValid());
state->loaderRegistry.DetachLoader(loader);
}

//------------------------------------------------------------------------------
AssetId
Assets::Lookup(const Locator& loc) {
o_assert_dbg(IsValid());
return AssetId(state->registry.Lookup(loc));
}

FIXME:
- Load must first check the registry, then call assetLoaderRegistry
//------------------------------------------------------------------------------
AssetId
Assets::Register(const Locator& loc, Id resId, DiscardFunc discardFunc) {
o_assert_dbg(IsValid());
o_assert_dbg(!state->registry.Contains(id));
o_assert_dbg(!state->registry.Lookup(loc).IsValid());
state->registry.Add(loc, resId, discardFunc);
return AssetId(resId);
}

} // namespace Oryol
53 changes: 51 additions & 2 deletions code/Modules/Assets/Assets.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@
#include <functional>
#include "Core/Types.h"
#include "IO/Stream/Stream.h"
#include "Resource/ResourceState.h"
#include "Assets/AssetId.h"
#include "Assets/AssetsSetup.h"
#include "Assets/Core/assetRegistry.h"
#include "Assets/Core/assetLoaderRegistry.h"
#include "Assets/Core/assetCreator.h"
#include "Assets/Core/AssetLoader.h"

namespace Oryol {
class Assets {
public:
/// asset discard function
typedef std::function<void(const Id&)> DiscardFunc;
typedef _priv::assetRegistry::DiscardFunc DiscardFunc;

/// setup the Asset module
static void Setup(const AssetsSetup& setup = AssetsSetup());
Expand All @@ -35,9 +38,19 @@ class Assets {
static void AttachLoader(const Ptr<AssetLoader>& loader);
/// detach an asset loader
static void DetachLoader(const Ptr<AssetLoader>& loader);


/// push a new asset creation label
void PushAssetLabel(uint8 label);
/// pop top most asset creation label
uint8 PopAssetLabel();
/// discard all assets matching label
void DiscardAssets(uint8 label);
/// async load shared asset (or return existing shared asset)
template<class SETUP> static AssetId Load(const SETUP& setup);
/// directly create a shared, use-counted asset
template<class SETUP> static AssetId Create(const SETUP& setup);
/// directly create a shared, use-count asset with data
template<class SETUP> static AssetId Create(const SETUP& setup, const Ptr<Stream>& data);
/// lookup a shared asset by locator (bumps use-count)
static AssetId Lookup(const Locator& loc);
/// register an existing resource as shared asset
Expand All @@ -54,10 +67,46 @@ class Assets {
struct _state {
class AssetsSetup setup;
_priv::assetRegistry registry;
_priv::assetLoaderRegistry loaderRegistry;
};
static _state* state;
};

//------------------------------------------------------------------------------
template<class SETUP> AssetId
Assets::Create(const SETUP& setup) {
o_assert_dbg(IsValid());
Id resId = state->registry.Lookup(setup.Locator);
if (!resId.IsValid()) {
resId = _priv::assetCreator::Create(setup, state->registry);
}
return AssetId(resId);
}

//------------------------------------------------------------------------------
template<class SETUP> AssetId
Assets::Create(const SETUP& setup, const Ptr<Stream>& data) {
o_assert_dbg(IsValid());
Id resId = state->registry.Lookup(setup.Locator);
if (!resId.IsValid()) {
resId = _priv::assetCreator::Create(setup, state->registry);
}
return AssetId(resId);
}

//------------------------------------------------------------------------------
template<class SETUP> AssetId
Assets::Load(const SETUP& setup) {
o_assert_dbg(IsValid());

// first check whether the asset already exists
Id resId = state->registry.Lookup(setup.Locator);
if (!resId.IsValid()) {
resId = state->loaderRegistry.Load(setup);
}
return AssetId(resId);
}

//------------------------------------------------------------------------------
inline void
Assets::releaseAsset(const Id& resId) {
Expand Down
5 changes: 4 additions & 1 deletion code/Modules/Assets/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ fips_begin_module(Assets)
fips_dir(Core)
fips_files(
assetRegistry.cc assetRegistry.h
AssetLoader.h
assetLoaderRegistry.cc assetLoaderRegistry.h
assetCreator.h
assetCreator_Gfx.cc
AssetLoader.cc AssetLoader.h
)
fips_dir(Util)
fips_files(
Expand Down
29 changes: 29 additions & 0 deletions code/Modules/Assets/Core/AssetLoader.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//------------------------------------------------------------------------------
// AssetLoader.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "AssetLoader.h"

namespace Oryol {

OryolClassImpl(AssetLoader);

//------------------------------------------------------------------------------
void
AssetLoader::Attached() {
// empty
}

//------------------------------------------------------------------------------
void
AssetLoader::Detached() {
// empty
}

//------------------------------------------------------------------------------
bool
AssetLoader::TryLoad(const Id& /*id*/, const Ptr<Stream>& /*data*/) {
return false;
}

} // namespace Oryol
11 changes: 7 additions & 4 deletions code/Modules/Assets/Core/AssetLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@
@ingroup Assets
@brief base class for asset loaders
*/
#include "Assets/AssetFormat.h"
#include "Core/RefCounted.h"
#include "Resource/Id.h"
#include "IO/Stream/Stream.h"

namespace Oryol {
class AssetLoader {
class AssetLoader : public RefCounted {
OryolClassDecl(AssetLoader);
public:
/// called when attached to Assets module
virtual void Attached() = 0;
virtual void Attached();
/// called when detached from Assets module
virtual void Detached() = 0;
virtual void Detached();
/// try loading/creating the resource, return false if not possible
virtual bool TryLoad(const Id& id, const Ptr<Stream>& data);
};
Expand Down
42 changes: 42 additions & 0 deletions code/Modules/Assets/Core/assetCreator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once
//------------------------------------------------------------------------------
/**
@class Oryol::assetCreator
@ingroup Assets
@brief wrapper class for directly creating assets
This class contains entirely of specialized template methods
to forward a resource creation request to a specific Module
and return the resulting resource id as AssetId. Each set of
specialization methods should live in its own source code
(compilation unit) to make sure that unused Modules are not
linked in.
*/
#include "IO/Stream/Stream.h"
#include "Assets/Core/assetRegistry.h"

namespace Oryol {
namespace _priv {

class assetCreator {
public:
/// setup the asset creator
void Setup(assetRegistry* registry);
/// discard the asset creator
void Discard();

/// directly create a shared, use-counted asset
template<class SETUP> Id Create(const SETUP& setup, assetRegistry* registry);
/// directly create a shared, use-count asset with data
template<class SETUP> Id Create(const SETUP& setup, const Ptr<Stream>& data, assetRegistry* registry);
/// allocate a resource (for async resource loading)
template<class SETUP> Id Alloc(const SETUP& setup, Id placeholder, assetRegistry* registry);
/// setup a previously allocated resource from data (for async resource loading)
template<class SETUP> void Init(const Id& id, const SETUP& setup, const Ptr<Stream>& data);

/// one-time register a push-label function
void regFuncsOnce(void(*push)(uint8), uint8(*pop)(), void(*discard)(uint8));
};

} // namespace _priv
} // namespace Oryol
45 changes: 45 additions & 0 deletions code/Modules/Assets/Core/assetCreator_Gfx.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//------------------------------------------------------------------------------
// assetCreator_Gfx.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "assetCreator.h"
#include "Gfx/Gfx.h"

namespace Oryol {
namespace _priv {

//------------------------------------------------------------------------------
template<class SETUP> Id
assetCreator::Create(const SETUP& setup, assetRegistry* registry) {
this->regFuncsOnce(Gfx::PushResourceLabel, Gfx::PopResourceLabel, Gfx::DiscardResources);
Id resId = Gfx::CreateResource(setup);
registry->Add(setup.Locator, resId);
return resId;
}

//------------------------------------------------------------------------------
template<class SETUP> Id
assetCreator::Create(const SETUP& setup, const Ptr<Stream>& data, assetRegistry* registry) {
this->regFuncsOnce(Gfx::PushResourceLabel, Gfx::PopResourceLabel, Gfx::DiscardResources);
Id resId = Gfx::CreateResource(setup, data);
registry->Add(setup.Locator, resId);
return resId;
}

//------------------------------------------------------------------------------
template<class SETUP> Id
assetCreator::Alloc(const SETUP& setup, Id placeholder, assetRegistry* registry) {
this->regFuncsOnce(Gfx::PushResourceLabel, Gfx::PopResourceLabel, Gfx::DiscardResources);
Id resId = Gfx::AllocResource(setup, placeholder);
registry->Add(setup.Locator, resId);
return resId;
}

//------------------------------------------------------------------------------
template<class SETUP> void
assetCreator::Init(const Id& id, const SETUP& setup, const Ptr<Stream>& data) {
Gfx::InitResource(id, setup, data);
}

} // namespace _priv
} // namespace Oryol
13 changes: 3 additions & 10 deletions code/Modules/Assets/Core/assetLoaderRegistry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
//------------------------------------------------------------------------------
#include "Pre.h"
#include "assetLoaderRegistry.h"
#include "Core/Core.h"

namespace Oryol {
namespace _priv {

//------------------------------------------------------------------------------
assetLoaderRegistry::assetLoaderRegistry() :
Expand Down Expand Up @@ -69,14 +71,5 @@ assetLoaderRegistry::DetachLoader(Ptr<AssetLoader> loader) {
this->loaders.Erase(loaderIndex);
}

//------------------------------------------------------------------------------
FIXME: Load method:

- specialized for asset type by SETUP template param
- get resource Id from Gfx via Gfx::AllocResource
- create IO request
- append to pendingRequests
- then in update: check requests for finished, and call Gfx::SetupResource


} // namespace _priv
} // namespace Oryol
2 changes: 1 addition & 1 deletion code/Modules/Assets/Core/assetLoaderRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class assetLoaderRegistry {
Array<Ptr<AssetLoader>> loaders;
struct request {
Id id;
Ptr<IORequest> ioRequest;
Ptr<IOProtocol::Request> ioRequest;
};
Array<request> pendingRequests;
RunLoop::Id runLoopId;
Expand Down
Loading

0 comments on commit 83849b7

Please sign in to comment.