Skip to content

Commit

Permalink
fix(tesseratos): handleImport function
Browse files Browse the repository at this point in the history
  • Loading branch information
Scarface1809 committed Sep 30, 2024
1 parent 480805d commit 4207f85
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 144 deletions.
44 changes: 44 additions & 0 deletions engine/include/cubos/engine/assets/assets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <condition_variable>
#include <deque>
#include <memory>
#include <optional>
#include <shared_mutex>
#include <string>
#include <thread>
Expand Down Expand Up @@ -57,6 +58,7 @@ namespace cubos::engine
Unloaded, ///< The asset is not loaded.
Loading, ///< The asset is being loaded.
Loaded, ///< The asset is loaded.
Failed, ///< The asset failed to load.
};

~Assets();
Expand Down Expand Up @@ -86,6 +88,11 @@ namespace cubos::engine
/// @param path Path to load metadata from.
void importAll(std::string_view path);

/// @brief Get AssetHandle from Path.
/// @param path Path to get handle from.
/// @return AssetHandle from Path, or a null handle if unable to find.
AnyAsset getAsset(std::string_view path);

/// @brief Loads all metadata from the virtual filesystem, in the given path. If the path
/// points to a directory, it will be recursively searched for metadata files.
/// @param path Path to load metadata from.
Expand Down Expand Up @@ -152,6 +159,28 @@ namespace cubos::engine
return AssetRead<T>(*data, std::move(lock));
}

/// @brief Gets read-only access to the asset data associated with the given handle.
///
/// If the asset is not loaded, this blocks until it is. If the asset cannot be loaded,
/// returns std::nullopt.
///
/// @tparam T Type of the asset data.
/// @param handle Handle to get the asset data for.
/// @return Reference to the asset data.
template <typename T>
inline std::optional<std::reference_wrapper<const T>> tryRead(Asset<T> handle) const
{
// Create a strong handle to the asset, so that the asset starts loading if it isn't already.
auto strong = this->load(handle);
auto lock = this->lockRead(strong);
auto data = static_cast<const T*>(this->tryAccess(strong, core::reflection::reflect<T>(), lock, false));
if (data == nullptr)
{
return std::nullopt;
}
return std::cref(*data);
}

/// @brief Gets read-write access to the asset data associated with the given handle.
///
/// If the asset is not loaded, this blocks until it is. If the asset cannot be loaded,
Expand Down Expand Up @@ -302,6 +331,21 @@ namespace cubos::engine
template <typename Lock>
void* access(const AnyAsset& handle, const core::reflection::Type& type, Lock& lock, bool incVersion) const;

/// @brief Gets a pointer to the asset data associated with the given handle.
///
/// If the asset is not loaded, this blocks until it is. If the asset cannot be loaded,
/// return nullpt. If this function is called from the loader thread, instead of waiting
/// for the asset to load, it will be loaded synchronously.
///
/// @tparam Lock The type of the lock guard.
/// @param handle Handle to get the asset data for.
/// @param type Expected type of the asset data.
/// @param lock Lock guard for the asset.
/// @param incVersion Whether to increase the asset's version.
/// @return Pointer to the asset's data.
template <typename Lock>
void* tryAccess(const AnyAsset& handle, const core::reflection::Type& type, Lock& lock, bool incVersion) const;

/// @brief Locks the given asset for reading.
/// @param handle Handle to lock.
/// @return Lock guard.
Expand Down
6 changes: 5 additions & 1 deletion engine/include/cubos/engine/voxels/voxel_model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ namespace cubos::engine

const VoxelPalette& getPalette() const;

VoxelGrid& getGrid(uint16_t index);
void setPalette(const VoxelPalette& palette);

const VoxelGrid& getGrid(uint16_t index) const;

void setGrid(uint16_t index, const VoxelGrid& grid, const glm::ivec3& position);

/// @brief Loads the grid's data from the given stream.
///
Expand Down
81 changes: 79 additions & 2 deletions engine/src/assets/assets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void Assets::importAll(std::string_view path)
child = child->sibling();

Check warning on line 108 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L107-L108

Added lines #L107 - L108 were not covered by tests
}
}
// Skip files that already have a .meta extension.
// Skip meta files.
else if (!file->name().ends_with(".meta"))

Check warning on line 112 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L112

Added line #L112 was not covered by tests
{
// Check if the .meta file exists.
Expand Down Expand Up @@ -141,6 +141,19 @@ void Assets::importAll(std::string_view path)
}
}

AnyAsset Assets::getAsset(std::string_view path)

Check warning on line 144 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L144

Added line #L144 was not covered by tests
{
for (const auto& [uuid, entry] : mEntries)

Check warning on line 146 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L146

Added line #L146 was not covered by tests
{
auto path_meta = entry->meta.get("path");
if (path_meta.has_value() && path_meta.value() == path)

Check warning on line 149 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L148-L149

Added lines #L148 - L149 were not covered by tests
{
return AnyAsset(uuid);

Check warning on line 151 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L151

Added line #L151 was not covered by tests
}
}
return {};

Check warning on line 154 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L154

Added line #L154 was not covered by tests
}

void Assets::loadMeta(std::string_view path)
{
auto file = core::data::FileSystem::find(path);
Expand Down Expand Up @@ -524,13 +537,77 @@ void* Assets::access(const AnyAsset& handle, const Type& type, Lock& lock, bool
return assetEntry->data;
}

template <typename Lock>
void* Assets::tryAccess(const AnyAsset& handle, const Type& type, Lock& lock, bool incVersion) const

Check warning on line 541 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L541

Added line #L541 was not covered by tests
{
CUBOS_ASSERT(!handle.isNull(), "Could not access asset");

Check warning on line 543 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L543

Added line #L543 was not covered by tests

// Get the entry for the asset.
auto assetEntry = this->entry(handle);
CUBOS_ASSERT(assetEntry != nullptr, "Could not access asset");

Check warning on line 547 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L546-L547

Added lines #L546 - L547 were not covered by tests

// If the asset hasn't been loaded yet, and its bridge isn't asynchronous, or we're in the loader thread, then load
// it now.
if (assetEntry->status != Status::Loaded)

Check warning on line 551 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L551

Added line #L551 was not covered by tests
{
auto bridge = this->bridge(handle);
CUBOS_ASSERT(bridge != nullptr, "Could not access asset");

Check warning on line 554 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L553-L554

Added lines #L553 - L554 were not covered by tests

if (!bridge->asynchronous() || std::this_thread::get_id() == mLoaderThread.get_id())

Check warning on line 556 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L556

Added line #L556 was not covered by tests
{
CUBOS_DEBUG("Loading asset {} as a dependency", handle);

Check warning on line 558 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L558

Added line #L558 was not covered by tests

// Load the asset - the const_cast is okay since the const qualifiers are only used to make
// the interface more readable. We need to unlock temporarily to avoid a deadlock, since the
// bridge will call back into the asset manager.
lock.unlock();
if (!bridge->load(const_cast<Assets&>(*this), handle))

Check warning on line 564 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L563-L564

Added lines #L563 - L564 were not covered by tests
{
CUBOS_CRITICAL("Could not load asset {}", handle);
abort();

Check warning on line 567 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L566-L567

Added lines #L566 - L567 were not covered by tests
}
lock.lock();

Check warning on line 569 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L569

Added line #L569 was not covered by tests
}
}

// Wait until the asset finishes loading.
while (assetEntry->status == Status::Loading)

Check warning on line 574 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L574

Added line #L574 was not covered by tests
{
assetEntry->cond.wait(lock);

Check warning on line 576 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L576

Added line #L576 was not covered by tests
}

if (assetEntry->status != Status::Loaded || assetEntry->data == nullptr)

Check warning on line 579 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L579

Added line #L579 was not covered by tests
{
CUBOS_ERROR("Could not access asset");
return nullptr;

Check warning on line 582 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L581-L582

Added lines #L581 - L582 were not covered by tests
}

if (assetEntry->type != &type)

Check warning on line 585 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L585

Added line #L585 was not covered by tests
{
CUBOS_ERROR("Type mismatch, expected {}, got {}", type.name(), assetEntry->type->name());
return nullptr;

Check warning on line 588 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L587-L588

Added lines #L587 - L588 were not covered by tests
}

if (incVersion)

Check warning on line 591 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L591

Added line #L591 was not covered by tests
{
assetEntry->version++;
CUBOS_DEBUG("Incremented version of asset {}", handle);

Check warning on line 594 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L593-L594

Added lines #L593 - L594 were not covered by tests
}

return assetEntry->data;

Check warning on line 597 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L597

Added line #L597 was not covered by tests
}

// Define the explicit instantiations of the access() function, one for each lock type.
// Necessary because the function is template - would otherwise cause linker errors.

template void* Assets::access<std::shared_lock<std::shared_mutex>>(const AnyAsset&, const Type&,
std::shared_lock<std::shared_mutex>&, bool) const;
template void* Assets::access<std::unique_lock<std::shared_mutex>>(const AnyAsset&, const Type&,
std::unique_lock<std::shared_mutex>&, bool) const;
template void* Assets::tryAccess<std::shared_lock<std::shared_mutex>>(const AnyAsset&, const Type&,
std::shared_lock<std::shared_mutex>&, bool) const;
template void* Assets::tryAccess<std::unique_lock<std::shared_mutex>>(const AnyAsset&, const Type&,
std::unique_lock<std::shared_mutex>&, bool) const;

std::shared_lock<std::shared_mutex> Assets::lockRead(const AnyAsset& handle) const
{
Expand Down Expand Up @@ -680,7 +757,7 @@ void Assets::loader()

auto assetEntry = this->entry(task.handle);
CUBOS_ASSERT(assetEntry != nullptr, "This should never happen");
assetEntry->status = Assets::Status::Unloaded;
assetEntry->status = Assets::Status::Failed;

Check warning on line 760 in engine/src/assets/assets.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/assets/assets.cpp#L760

Added line #L760 was not covered by tests
assetEntry->cond.notify_all();
}
else
Expand Down
17 changes: 16 additions & 1 deletion engine/src/voxels/voxel_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,26 @@ const VoxelPalette& VoxelModel::getPalette() const
return palette;

Check warning on line 33 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L33

Added line #L33 was not covered by tests
}

VoxelGrid& VoxelModel::getGrid(uint16_t index)
void VoxelModel::setPalette(const VoxelPalette& palette)

Check warning on line 36 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L36

Added line #L36 was not covered by tests
{
this->palette = palette;

Check warning on line 38 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L38

Added line #L38 was not covered by tests
}

const VoxelGrid& VoxelModel::getGrid(uint16_t index) const

Check warning on line 41 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L41

Added line #L41 was not covered by tests
{
return matrices[index].grid;

Check warning on line 43 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L43

Added line #L43 was not covered by tests
}

void VoxelModel::setGrid(uint16_t index, const VoxelGrid& grid, const glm::ivec3& position)

Check warning on line 46 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L46

Added line #L46 was not covered by tests
{
if (index >= matrices.size())

Check warning on line 48 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L48

Added line #L48 was not covered by tests
{
matrices.resize(index + 1);

Check warning on line 50 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L50

Added line #L50 was not covered by tests
}
matrices[index].grid = grid;
matrices[index].position = position;

Check warning on line 53 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L52-L53

Added lines #L52 - L53 were not covered by tests
}

bool VoxelModel::loadFrom(Stream& stream)

Check warning on line 56 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L56

Added line #L56 was not covered by tests
{
uint8_t version[4] = {0, 0, 0, 0};

Check warning on line 58 in engine/src/voxels/voxel_model.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/voxels/voxel_model.cpp#L58

Added line #L58 was not covered by tests
Expand Down
Loading

0 comments on commit 4207f85

Please sign in to comment.