Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion include/ncengine/asset/Assets.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
/**
* @file Assets.h
* @copyright Jaremie Romer and McCallister Romer 2025
*/

#pragma once

#include "ncasset/AssetType.h"
#include "ncengine/asset/AssetViews.h"

#include <span>

namespace nc::asset
{
struct Texture;
/** Assets must be loaded before dependent objects are created and should be unloaded only
* when they are no longer in use.
*
Expand Down Expand Up @@ -55,11 +63,17 @@ void UnloadAllMeshAssets();
auto AcquireMeshAsset(const std::string& path) -> MeshView;
auto AcquireMeshAsset(AssetId id) -> MeshView;

/** Supported file types: .nca
/** Supported file types: .nca, raw texture data
* @note Unloading textures invalidates all TextureViews. It is intended
* to be done on scene change. */
bool LoadTextureAsset(const std::string& path);
bool LoadTextureAssets(std::span<const std::string> paths);
bool LoadTextureFromMemory(const std::string& key, Texture texture);
bool LoadTextureFromRGBA(const std::string& key,
std::span<const uint8_t> rgbaData,
uint32_t width,
uint32_t height,
TextureFormat format = TextureFormat::RGBA8_UNORM);
bool UnloadTextureAsset(const std::string& path);
void UnloadAllTextureAssets();
auto AcquireTextureAsset(const std::string& path) -> TextureView;
Expand Down
6 changes: 4 additions & 2 deletions include/ncengine/asset/NcAsset.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ class NcAsset : public Module
/** @brief Load assets from an AssetMap. */
virtual void LoadAssets(const AssetMap& assets) = 0;

/** @brief Get the names of all loaded assets as an AssetMap. */
virtual auto GetLoadedAssets() const noexcept -> AssetMap = 0;
/** @brief Get the names of all loaded assets as an AssetMap.
* @param serializableOnly If true, excludes runtime assets that are not from disk and cannot survive serialization.
*/
virtual auto GetLoadedAssets(bool serializableOnly = false) const noexcept -> AssetMap = 0;

/** @brief Get the path to a loaded asset given its id. */
virtual auto GetAssetPath(AssetType type, size_t id) const -> std::string_view = 0;
Expand Down
2 changes: 1 addition & 1 deletion sample/source/scenes/SmokeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void SmokeTest::Load(ecs::Ecs world, ModuleProvider modules)
{
isSecondPass = true;
auto ncAsset = modules.Get<asset::NcAsset>();
::SaveScene(world, ncAsset->GetLoadedAssets());
::SaveScene(world, ncAsset->GetLoadedAssets(true));
auto ncScene = modules.Get<NcScene>();
ncScene->Queue(std::make_unique<SmokeTest>(quit));
ncScene->ScheduleTransition();
Expand Down
6 changes: 3 additions & 3 deletions source/ncengine/asset/AssetService.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ class IAssetServiceBase
public:
virtual ~IAssetServiceBase() = default;

virtual auto GetAllLoaded() const -> std::vector<std::string_view> = 0;
virtual auto GetPath(AssetId hash) const -> std::string_view = 0;
virtual auto GetAssetType() const -> asset::AssetType = 0;
virtual auto GetAllLoaded(bool serializableOnly = false) const -> std::vector<std::string_view> = 0;
virtual auto GetPath(AssetId hash) const -> std::string_view = 0;
virtual auto GetAssetType() const -> asset::AssetType = 0;
};

/** Interface for services that manage assets. */
Expand Down
17 changes: 17 additions & 0 deletions source/ncengine/asset/Assets.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "asset/Assets.h"
#include "AssetService.h"
#include "RuntimeTextureLoader.h"

#include "ncasset/Assets.h"

namespace nc::asset
{
Expand Down Expand Up @@ -193,6 +196,20 @@ bool LoadTextureAssets(std::span<const std::string> paths)
return AssetService<TextureView>::Get()->Load(paths);
}

bool LoadTextureFromMemory(const std::string& key, Texture texture)
{
return RuntimeTextureLoaderService::Get()->LoadFromMemory(key, std::move(texture));
}

bool LoadTextureFromRGBA(const std::string& key,
std::span<const uint8_t> rgbaData,
uint32_t width,
uint32_t height,
TextureFormat format)
{
return RuntimeTextureLoaderService::Get()->LoadFromRGBA(key, rgbaData, width, height, format);
}

bool UnloadTextureAsset(const std::string& path)
{
return AssetService<TextureView>::Get()->Unload(path);
Expand Down
6 changes: 3 additions & 3 deletions source/ncengine/asset/NcAssetImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void NcAssetImpl::LoadAssets(const AssetMap& assets)
m_textureManager->Load(assets.at(asset::AssetType::Texture));
}

auto NcAssetImpl::GetLoadedAssets() const noexcept -> AssetMap
auto NcAssetImpl::GetLoadedAssets(bool serializableOnly) const noexcept -> AssetMap
{
const auto managers = std::array<IAssetServiceBase*, 7>
{
Expand All @@ -116,9 +116,9 @@ auto NcAssetImpl::GetLoadedAssets() const noexcept -> AssetMap
};

auto out = AssetMap{};
std::ranges::for_each(managers, [&out](auto manager) mutable
std::ranges::for_each(managers, [&out, serializableOnly](auto manager) mutable
{
auto assets = manager->GetAllLoaded()
auto assets = manager->GetAllLoaded(serializableOnly)
| std::views::transform([](auto&& name){ return std::string{name}; });

out.emplace(manager->GetAssetType(), std::vector<std::string>{assets.begin(), assets.end()});
Expand Down
2 changes: 1 addition & 1 deletion source/ncengine/asset/NcAssetImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class NcAssetImpl : public NcAsset
auto OnMeshColliderUpdate() noexcept -> Signal<const MeshColliderUpdateEventData&>& override;
auto OnFontUpdate() noexcept -> Signal<>& override;
void LoadAssets(const AssetMap& assets) override;
auto GetLoadedAssets() const noexcept -> AssetMap override;
auto GetLoadedAssets(bool serializableOnly = false) const noexcept -> AssetMap override;
auto GetAssetPath(AssetType type, size_t id) const -> std::string_view override;

private:
Expand Down
33 changes: 33 additions & 0 deletions source/ncengine/asset/RuntimeTextureLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include "service/ServiceLocator.h"

#include "ncasset/AssetType.h"

#include <span>
#include <string>

namespace nc::asset
{
struct Texture;

class IRuntimeTextureLoader
{
public:
IRuntimeTextureLoader()
{
ServiceLocator<IRuntimeTextureLoader>::Register(this);
}

virtual ~IRuntimeTextureLoader() = default;

virtual auto LoadFromMemory(const std::string& key, Texture texture) -> bool = 0;
virtual auto LoadFromRGBA(const std::string& key,
std::span<const uint8_t> rgbaData,
uint32_t width,
uint32_t height,
TextureFormat format = TextureFormat::RGBA8_UNORM) -> bool = 0;
};

using RuntimeTextureLoaderService = ServiceLocator<IRuntimeTextureLoader>;
} // namespace nc::asset
3 changes: 2 additions & 1 deletion source/ncengine/asset/manager/AudioClipAssetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ auto AudioClipAssetManager::Acquire(AssetId id) const -> AudioClipView
};
}

auto AudioClipAssetManager::GetAllLoaded() const -> std::vector<std::string_view>
auto AudioClipAssetManager::GetAllLoaded(bool serializableOnly) const -> std::vector<std::string_view>
{
(void)serializableOnly;
return GetPaths(m_audioClips.keys());
}
} //namespace nc::asset
20 changes: 10 additions & 10 deletions source/ncengine/asset/manager/AudioClipAssetManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ class AudioClipAssetManager : public IAssetService<AudioClipView, std::string>
public:
explicit AudioClipAssetManager(const std::string& assetDirectory);

auto Load(const std::string& path) -> bool override;
auto Load(std::span<const std::string> paths) -> bool override;
auto Unload(const std::string& path) -> bool override;
void UnloadAll() override;
auto Acquire(const std::string& path) const -> AudioClipView override;
auto Acquire(AssetId id) const -> AudioClipView override;
auto GetAllLoaded() const -> std::vector<std::string_view> override;
auto IsLoaded(const std::string& path) const -> bool override { return m_audioClips.contains(path); }
auto GetPath(AssetId id) const -> std::string_view override { return m_audioClips.key_at(id); }
auto GetAssetType() const -> AssetType override { return AssetType::AudioClip; }
auto Load(const std::string& path) -> bool override;
auto Load(std::span<const std::string> paths) -> bool override;
auto Unload(const std::string& path) -> bool override;
void UnloadAll() override;
auto Acquire(const std::string& path) const -> AudioClipView override;
auto Acquire(AssetId id) const -> AudioClipView override;
auto GetAllLoaded(bool serializableOnly = false) const -> std::vector<std::string_view> override;
auto IsLoaded(const std::string& path) const -> bool override { return m_audioClips.contains(path); }
auto GetPath(AssetId id) const -> std::string_view override { return m_audioClips.key_at(id); }
auto GetAssetType() const -> AssetType override { return AssetType::AudioClip; }

private:
StringMap<AudioClip> m_audioClips;
Expand Down
3 changes: 2 additions & 1 deletion source/ncengine/asset/manager/ConvexHullAssetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ auto ConvexHullAssetManager::Acquire(AssetId id) const -> ConvexHullView
return ConvexHullView{id};
}

auto ConvexHullAssetManager::GetAllLoaded() const -> std::vector<std::string_view>
auto ConvexHullAssetManager::GetAllLoaded(bool serializableOnly) const -> std::vector<std::string_view>
{
(void)serializableOnly;
return GetPaths(m_map.keys());
}
} // namespace nc::asset
22 changes: 11 additions & 11 deletions source/ncengine/asset/manager/ConvexHullAssetManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ class ConvexHullAssetManager : public IAssetService<ConvexHullView, std::string>
public:
explicit ConvexHullAssetManager(const std::string& assetDirectory);

auto Load(const std::string& path) -> bool override;
auto Load(std::span<const std::string> paths) -> bool override;
auto Unload(const std::string& path) -> bool override;
void UnloadAll() override;
auto Acquire(const std::string& path) const -> ConvexHullView override;
auto Acquire(AssetId id) const -> ConvexHullView override;
auto GetAllLoaded() const -> std::vector<std::string_view> override;
auto IsLoaded(const std::string& path) const -> bool override { return m_map.contains(path); }
auto GetPath(AssetId id) const -> std::string_view override { return m_map.at(m_map.index(id)); }
auto GetAssetType() const -> asset::AssetType override { return asset::AssetType::ConvexHull; }
auto OnUpdate() -> decltype(auto) { return (m_onUpdate); }
auto Load(const std::string& path) -> bool override;
auto Load(std::span<const std::string> paths) -> bool override;
auto Unload(const std::string& path) -> bool override;
void UnloadAll() override;
auto Acquire(const std::string& path) const -> ConvexHullView override;
auto Acquire(AssetId id) const -> ConvexHullView override;
auto GetAllLoaded(bool serializableOnly = false) const -> std::vector<std::string_view> override;
auto IsLoaded(const std::string& path) const -> bool override { return m_map.contains(path); }
auto GetPath(AssetId id) const -> std::string_view override { return m_map.at(m_map.index(id)); }
auto GetAssetType() const -> asset::AssetType override { return asset::AssetType::ConvexHull; }
auto OnUpdate() -> decltype(auto) { return (m_onUpdate); }

private:
StringTable m_map;
Expand Down
3 changes: 2 additions & 1 deletion source/ncengine/asset/manager/CubeMapAssetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ auto CubeMapAssetManager::Acquire(AssetId id) const -> CubeMapView
};
}

auto CubeMapAssetManager::GetAllLoaded() const -> std::vector<std::string_view>
auto CubeMapAssetManager::GetAllLoaded(bool serializableOnly) const -> std::vector<std::string_view>
{
(void)serializableOnly;
return GetPaths(m_cubeMapIds.keys());
}
} // namespace nc::asset
22 changes: 11 additions & 11 deletions source/ncengine/asset/manager/CubeMapAssetManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ class CubeMapAssetManager : public IAssetService<CubeMapView, std::string>
explicit CubeMapAssetManager(const std::string& cubeMapAssetDirectory,
uint32_t maxCubeMapsCount);

auto Load(const std::string& path) -> bool override;
auto Load(std::span<const std::string> paths) -> bool override;
auto Unload(const std::string& path) -> bool override;
void UnloadAll() override;
auto Acquire(const std::string& path) const -> CubeMapView override;
auto Acquire(AssetId id) const -> CubeMapView override;
auto GetAllLoaded() const -> std::vector<std::string_view> override;
auto IsLoaded(const std::string& path) const -> bool override { return m_cubeMapIds.contains(path); }
auto GetPath(AssetId id) const -> std::string_view override { return m_cubeMapIds.at(m_cubeMapIds.index(id)); }
auto GetAssetType() const -> asset::AssetType override { return asset::AssetType::CubeMap; }
auto OnUpdate() -> decltype(auto) { return (m_onUpdate); }
auto Load(const std::string& path) -> bool override;
auto Load(std::span<const std::string> paths) -> bool override;
auto Unload(const std::string& path) -> bool override;
void UnloadAll() override;
auto Acquire(const std::string& path) const -> CubeMapView override;
auto Acquire(AssetId id) const -> CubeMapView override;
auto GetAllLoaded(bool serializableOnly = false) const -> std::vector<std::string_view> override;
auto IsLoaded(const std::string& path) const -> bool override { return m_cubeMapIds.contains(path); }
auto GetPath(AssetId id) const -> std::string_view override { return m_cubeMapIds.at(m_cubeMapIds.index(id)); }
auto GetAssetType() const -> asset::AssetType override { return asset::AssetType::CubeMap; }
auto OnUpdate() -> decltype(auto) { return (m_onUpdate); }

private:
StringTable m_cubeMapIds;
Expand Down
3 changes: 2 additions & 1 deletion source/ncengine/asset/manager/FontAssetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,9 @@ auto FontAssetManager::IsLoaded(const FontInfo& font) const -> bool
return m_fonts.contains(font);
}

auto FontAssetManager::GetAllLoaded() const -> std::vector<std::string_view>
auto FontAssetManager::GetAllLoaded(bool serializableOnly) const -> std::vector<std::string_view>
{
(void)serializableOnly;
auto out = std::vector<std::string_view>{};
out.reserve(m_fonts.size());
std::ranges::transform(m_fonts, std::back_inserter(out), [](const auto& pair)
Expand Down
22 changes: 11 additions & 11 deletions source/ncengine/asset/manager/FontAssetManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ class FontAssetManager : public IAssetService<FontView, FontInfo>
public:
explicit FontAssetManager(const std::string& assetDirectory);

auto Load(const FontInfo& font) -> bool override;
auto Load(std::span<const FontInfo> fonts) -> bool override;
auto Unload(const FontInfo& font) -> bool override;
void UnloadAll() override;
auto Acquire(const FontInfo& font) const -> FontView override;
auto Acquire(AssetId) const -> FontView override { throw NcError{"Not Implemented"};}
auto GetAllLoaded() const -> std::vector<std::string_view> override;
auto IsLoaded(const FontInfo& font) const -> bool override;
auto GetPath(AssetId) const -> std::string_view override { throw NcError{"Not Implemented"}; }
auto GetAssetType() const -> asset::AssetType override { return asset::AssetType::Font; }
auto OnUpdate() -> decltype(auto) { return (m_onUpdate); }
auto Load(const FontInfo& font) -> bool override;
auto Load(std::span<const FontInfo> fonts) -> bool override;
auto Unload(const FontInfo& font) -> bool override;
void UnloadAll() override;
auto Acquire(const FontInfo& font) const -> FontView override;
auto Acquire(AssetId) const -> FontView override { throw NcError{"Not Implemented"};}
auto GetAllLoaded(bool serializableOnly = false) const -> std::vector<std::string_view> override;
auto IsLoaded(const FontInfo& font) const -> bool override;
auto GetPath(AssetId) const -> std::string_view override { throw NcError{"Not Implemented"}; }
auto GetAssetType() const -> asset::AssetType override { return asset::AssetType::Font; }
auto OnUpdate() -> decltype(auto) { return (m_onUpdate); }

private:
std::unordered_map<FontInfo, FontView, FontHash, FontEqual> m_fonts;
Expand Down
3 changes: 2 additions & 1 deletion source/ncengine/asset/manager/MeshAssetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,9 @@ auto MeshAssetManager::Acquire(AssetId id) const -> MeshView
return m_accessors.at(index);
}

auto MeshAssetManager::GetAllLoaded() const -> std::vector<std::string_view>
auto MeshAssetManager::GetAllLoaded(bool serializableOnly) const -> std::vector<std::string_view>
{
(void)serializableOnly;
return GetPaths(m_accessors.keys());
}
} // namespace nc::asset
Loading