Skip to content

Commit

Permalink
feat(assets): add identifying assets in code from their path
Browse files Browse the repository at this point in the history
  • Loading branch information
GalaxyCrush committed Oct 17, 2024
1 parent 1ebeeb5 commit e7a4c8a
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 36 deletions.
21 changes: 20 additions & 1 deletion engine/include/cubos/engine/assets/asset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace cubos::engine
{

template <typename T>
class Asset;

Expand All @@ -27,6 +28,13 @@ namespace cubos::engine
{
public:
CUBOS_REFLECT;
/// @brief Type of the asset identifier.
enum class IdType
{
UUID,
Path,
Invalid
};

/// @brief Avoid using this field, use @ref getId() instead.
/// @todo This was added as a dirty fix for #692, should be removed once the issue is fixed.
Expand Down Expand Up @@ -71,11 +79,22 @@ namespace cubos::engine
/// @return Asset version.
int getVersion() const;

/// @brief Gets the type of the asset identifier.
/// @return Asset identifier type.
IdType getIdType() const;

/// @brief Gets the Path or UUID of the asset.
/// @return Asset Path or UUID.
std::string getIdString() const;

/// @brief Gets the UUID of the asset if it is the case of having one.
/// @brief Gets the UUID of the asset if it has one.
///
/// There are two possible reasons for an asset handle to have no UUID:
/// - it being an invalid or null handle;
/// - it being created from an asset path.
///
/// To ensure an asset handle gets a UUID, you can use @ref Assets::load.
///
/// @return Asset UUID.
std::optional<uuids::uuid> getId() const;

Expand Down
5 changes: 0 additions & 5 deletions engine/include/cubos/engine/assets/assets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,11 +364,6 @@ namespace cubos::engine
/// @return Lock guard.
std::unique_lock<std::shared_mutex> lockWrite(const AnyAsset& handle) const;

/// @brief Checks if the given path is a valid path to an asset.
/// @param path Path to check.
/// @return A string that says if the given string is a path, uuid or not a valid format string
static std::string isPath(const std::string& path);

/// @brief Gets a pointer to the entry associated with the given handle.
/// @param handle Handle to get the entry for.
/// @return Entry for the given handle, or nullptr if there is no such entry.
Expand Down
2 changes: 1 addition & 1 deletion engine/include/cubos/engine/assets/meta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace cubos::engine

/// @brief Gets the path of the asset.
/// @return Path of the asset.
std::string getPath() const;
std::optional<std::string> getPath() const;

/// @brief Sets a parameter on the asset's metadata.
/// @param key Key of the parameter.
Expand Down
17 changes: 15 additions & 2 deletions engine/src/assets/asset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ AnyAsset::AnyAsset(std::string_view str)
pathOrId = str;
mId = id.value();
}
else if (str.find('/') != std::string_view::npos || str.find('\\') != std::string_view::npos)
else if (!str.empty() && str[0] == '/')
{
pathOrId = str;
}
else
{
CUBOS_ERROR("Could not create asset handle, invalid UUID: \"{}\"", str);
CUBOS_ERROR("Could not create asset handle, invalid path or UUID: \"{}\"", str);
}
}

Expand Down Expand Up @@ -113,6 +113,19 @@ int AnyAsset::getVersion() const
return getId().has_value() && getId().value() == mId ? mVersion : 0;
}

AnyAsset::IdType AnyAsset::getIdType() const
{
if (!pathOrId.empty() && pathOrId[0] == '/')
{
return IdType::Path;
}
else if (auto id = uuids::uuid::from_string(pathOrId))
{
return IdType::UUID;
}
return IdType::Invalid;
}

std::string AnyAsset::getIdString() const
{
return pathOrId;
Expand Down
24 changes: 6 additions & 18 deletions engine/src/assets/assets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,18 +621,6 @@ std::unique_lock<std::shared_mutex> Assets::lockWrite(const AnyAsset& handle) co
abort();
}

std::string Assets::isPath(const std::string& path)
{
if (path.find('/') != std::string::npos || path.find('\\') != std::string::npos)
{
return "Path";
}
else if (auto id = uuids::uuid::from_string(path))
{
return "UUID";
}
return "Invalid format";
}
std::shared_ptr<Assets::Entry> Assets::entry(const AnyAsset& handle) const
{
// If the handle is null, we can't access the asset.
Expand All @@ -646,8 +634,9 @@ std::shared_ptr<Assets::Entry> Assets::entry(const AnyAsset& handle) const
auto sharedLock = std::shared_lock(mMutex);

auto sid = handle.getIdString();
auto type = handle.getIdType();

if (isPath(sid) == "Path")
if (type == AnyAsset::IdType::Path)
{
for (const auto& [eid, entry] : mEntries)
{
Expand All @@ -659,7 +648,7 @@ std::shared_ptr<Assets::Entry> Assets::entry(const AnyAsset& handle) const
CUBOS_ERROR("No such asset {}", handle);
return nullptr;
}
if (isPath(sid) == "UUID")
if (type == AnyAsset::IdType::UUID)
{
// Search for the entry in the map.
auto it = mEntries.find(handle.getId().value());
Expand Down Expand Up @@ -697,8 +686,8 @@ std::shared_ptr<Assets::Entry> Assets::entry(const AnyAsset& handle, bool create
}

auto sid = handle.getIdString();

if (isPath(sid) == "Path")
auto type = handle.getIdType();
if (type == AnyAsset::IdType::Path)
{
for (const auto& [eid, entry] : mEntries)
{
Expand All @@ -721,9 +710,8 @@ std::shared_ptr<Assets::Entry> Assets::entry(const AnyAsset& handle, bool create
CUBOS_ERROR("No such asset {}", handle);
return nullptr;
}
if (isPath(sid) == "UUID")
else if (type == AnyAsset::IdType::UUID)
{

// Search for an existing entry for the asset.
auto it = mEntries.find(handle.getId().value());
if (it == mEntries.end())
Expand Down
8 changes: 2 additions & 6 deletions engine/src/assets/meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ uuids::uuid AssetMeta::getId() const
return uuids::uuid::from_string(this->get("id").value()).value();
}

std::string AssetMeta::getPath() const
std::optional<std::string> AssetMeta::getPath() const
{
if (auto path = this->get("path"))
{
return path.value();
}
return {};
return this->get("path");
}
6 changes: 3 additions & 3 deletions engine/src/render/mesh/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,16 @@ void cubos::engine::renderMeshPlugin(Cubos& cubos)

cubos.observer("update RenderMesh on LoadRenderVoxels")
.onAdd<LoadRenderVoxels>()
.call([](Commands cmds, State& state, Assets& assets, Query<Entity, const RenderVoxelGrid&> query) {
.call([](Commands cmds, State& state, Assets& assets, Query<Entity, RenderVoxelGrid&> query) {
for (auto [ent, grid] : query)
{
if (grid.asset.isNull())
{
continue;
}

// If not loaded, the mId might be a nil UUID, so we need to load the asset first.
assets.load(grid.asset);
// The asset handle might not yet have a valid ID, and since we need getId, we load it first.
grid.asset = assets.load(grid.asset);
// If the asset has never been loaded, or it has been updated since the last meshing, update the entry
// and queue a meshing task. Otherwise, just reuse the existing mesh.
auto& entry = state.entries[grid.asset.getId().value()];
Expand Down

0 comments on commit e7a4c8a

Please sign in to comment.