Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
b935816
chore(Asset): add concrete namespace for declare asset type macro
infirit89 Feb 4, 2026
b8dfd7a
chore(Core): start from unnamed namespace for log macros
infirit89 Feb 4, 2026
11b995e
chore(Core): move math utilities into core
infirit89 Feb 4, 2026
a0fb928
chore(Scene): initial work for LibScene separation from engine library
infirit89 Feb 4, 2026
7dae78a
chore(Asset): add AssetError type to signal errors during asset loading
infirit89 Feb 15, 2026
f85853f
chore(Scene): remove commented code
infirit89 Feb 15, 2026
324f611
chore(Scene): refactor scene serializer
infirit89 Feb 15, 2026
f81e60a
chore(Sandbox): add scene and asset systems as dependencies
infirit89 Feb 15, 2026
cd8b489
chore(Scene): add scene transition event
infirit89 Feb 15, 2026
dac5195
chore(Scene): fix sonarcloud issues
infirit89 Feb 15, 2026
7f703d4
chore(Core): fix sonarcloud issues
infirit89 Feb 15, 2026
c224773
chore(Core): fix serializer build errors
infirit89 Feb 15, 2026
8b64775
chore(Scene): fix more sonarcloud issues
infirit89 Feb 15, 2026
03b9eff
chore(Core): fix more sonarcloud errors
infirit89 Feb 15, 2026
b7e664f
chore(Asset): fix more sonarcloud issues
infirit89 Feb 15, 2026
b9a0165
chore(Scene): dispatch scene transition event on scene transition
infirit89 Feb 15, 2026
d070aef
chore(Scene): move copy scene method to scene manager
infirit89 Feb 16, 2026
578b9a2
chore(Asset): add remove_asset to AssetManager
infirit89 Feb 16, 2026
ef9a48f
chore(Core): add intrusive reference counting smart pointer
infirit89 Feb 16, 2026
f6d9d76
chore(Scene): fix more sonarcloud errors
infirit89 Feb 16, 2026
7782a62
build(Sandbox): add yaml-cpp as dependency
infirit89 Feb 16, 2026
776da01
test(Core): add unit tests for RefPtr
infirit89 Feb 16, 2026
bf3b89c
chore(Core): add smart pointer casts
infirit89 Feb 16, 2026
d761f83
chore(Core): add nonowning smart pointer for intrusive ref counted
infirit89 Feb 16, 2026
4923a79
chore(Core): make std::forward be called on a forwarding reference
infirit89 Feb 16, 2026
1d99b9d
chore(Asset): make create asset methods accept forwarding reference to
infirit89 Feb 16, 2026
3c96a47
test(Core): remove unnecessary header guard in ByteBufferTests
infirit89 Feb 16, 2026
d8e8e06
chore(Core): add some missing stuff from first pass of intrusive refs
infirit89 Feb 17, 2026
fa03f8f
chore(Asset): make Asset be intrusive ref counted
infirit89 Feb 17, 2026
f9e0d80
chore(Scene): change scene to reflect intrusive ref counting in Asset
infirit89 Feb 17, 2026
e1dd708
chore(Core): fix sonarcloud errors regarding RefPtr and WeakPtr
infirit89 Feb 18, 2026
1f1ad40
chore(Asset): move designed to be private member data into private
infirit89 Feb 18, 2026
b979dfd
chore(Scene): mark current_scene getter as const
infirit89 Feb 18, 2026
9a6adf1
chore(Core): add explicit keyword to RefPtr and WeakPtr
infirit89 Feb 18, 2026
a7d1680
chore(Asset): add asset free queue in Asset Manager
infirit89 Feb 18, 2026
cd532af
chore(Asset): add implementation for add_asset_metadata
infirit89 Feb 18, 2026
1ef23d1
test(Scene): add unit tests for Scene class
infirit89 Feb 18, 2026
9725c10
build(Sonarcloud): fix test coverage gathering
infirit89 Feb 19, 2026
56ce3bb
test(Scene): add unit test for destroying child entity
infirit89 Feb 19, 2026
9ebeb10
test(Scene): add entity unit tests
infirit89 Feb 19, 2026
b96c0b1
test(Scene): add more unit tests for the Entity and Scene classes
infirit89 Feb 19, 2026
cb11131
chore(Core): fix ub in Result type
infirit89 Feb 20, 2026
dbad457
chore(Scene): fix sonarcloud error
infirit89 Feb 20, 2026
6bb1ea1
test(Asset): add AssetImporterRegistry unit tests
infirit89 Feb 20, 2026
02be680
chore(Core): change base logging macro names
infirit89 Feb 23, 2026
d8543a4
chore(Asset): make AssetHandle the way to access loaded assets
infirit89 Feb 23, 2026
cb26b96
chore(Asset): fix logical errors introduced by reworking
infirit89 Feb 25, 2026
307fb0c
chore(Scene): fix logical errors introduced by refactoring
infirit89 Feb 25, 2026
32fdce4
chore(Core): imporve WeakPtr
infirit89 Mar 4, 2026
ae4c545
chore(Asset): address sonarqube errors
infirit89 Mar 4, 2026
a91ec26
chore(Scene): address sonarqube errors
infirit89 Mar 4, 2026
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
32 changes: 25 additions & 7 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,32 @@ jobs:
run: |
/opt/homebrew/opt/llvm/bin/llvm-profdata merge -sparse coverage/*.profraw -o coverage/coverage.profdata

SOURCE_FILES=$(find Libraries Sandbox -type f \( -name "*.cpp" -o -name "*.h" -o -name "*.hpp" \) | tr '\n' ' ')
TEST_BINS=$(find Tests -type f -name "Test.*" -perm +111 | tr '\n' ' ')
# Collect all test binaries into an array
TEST_BINS=()
while IFS= read -r bin; do
TEST_BINS+=("$bin")
done < <(find Tests -type f -name "Test.*" -perm +111)

/opt/homebrew/opt/llvm/bin/llvm-cov show $TEST_BINS \
--show-branches=count \
-instr-profile=coverage/coverage.profdata \
--ignore-filename-regex='.*(/usr/|/opt/|/Library/|\.h$)' \
> coverage/coverage.txt
if [ ${#TEST_BINS[@]} -eq 0 ]; then
echo "No test binaries found!"
exit 1
fi

# Build -object flags for every binary after the first
OBJECT_FLAGS=()
for bin in "${TEST_BINS[@]:1}"; do
OBJECT_FLAGS+=(-object "$bin")
done

/opt/homebrew/opt/llvm/bin/llvm-cov show "${TEST_BINS[0]}" \
"${OBJECT_FLAGS[@]}" \
--show-branches=count \
-instr-profile=coverage/coverage.profdata \
--ignore-filename-regex='.*(/usr/|/opt/|/Library/)' \
> coverage/coverage.txt

# Sanity check — print coverage size so you can see it in logs
wc -l coverage/coverage.txt

# ---- MANAGED BUILD ----
- name: Generate managed solution
Expand Down
5 changes: 0 additions & 5 deletions Libraries/LibAsset/Asset.cpp

This file was deleted.

26 changes: 14 additions & 12 deletions Libraries/LibAsset/Asset.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,40 @@

#include "AssetTypes.h"

#include <LibCore/Base.h>
#include <LibCore/Hash.h>
#include <LibCore/RefCounted.h>

#include <LibCore/RefPtr.h>
#include <concepts>
#include <string>

namespace Terran {
namespace Asset {

class Asset {
class AssetManager;
class Asset : public Core::RefCounted {
public:
Asset() = default;
virtual ~Asset() = default;
Asset(AssetHandle const& handle)
: m_handle(handle)
explicit Asset(AssetId const& handle)
: m_id(handle)
{
}

bool is_valid()
{
return m_handle.is_valid();
return m_id.is_valid();
}

AssetHandle const& handle()
AssetId const& id() const
{
return m_handle;
return m_id;
}

virtual AssetTypeId type() const = 0;

protected:
AssetHandle m_handle;
AssetTypeId m_type_id;
private:
AssetId m_id;
friend class AssetManager;
};

Expand All @@ -43,8 +45,8 @@ concept HasStaticType = requires(T) {
};

#define TR_DECLARE_ASSET_TYPE(type_name) \
static AssetTypeId static_type() { return Terran::Core::Hash::fnv1a_64(#type_name); } \
virtual AssetTypeId type() const override { return static_type(); }
static Terran::Asset::AssetTypeId static_type() { return Terran::Core::Hash::fnv1a_64(#type_name); } \
virtual Terran::Asset::AssetTypeId type() const override { return static_type(); }

class TextAsset final : public Asset {
public:
Expand Down
14 changes: 14 additions & 0 deletions Libraries/LibAsset/AssetError.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <string_view>

namespace Terran::Asset {

class AssetError {
public:
virtual ~AssetError() = default;
[[nodiscard]] virtual std::string_view message() const = 0;
[[nodiscard]] virtual std::string_view source() const = 0;
};

}
17 changes: 9 additions & 8 deletions Libraries/LibAsset/AssetEvents.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,30 @@ namespace Terran::Asset {

class AssetRemovedEvent {
public:
constexpr AssetRemovedEvent(AssetHandle const& handle) noexcept
constexpr AssetRemovedEvent(AssetId const& handle) noexcept
: m_handle(handle)
{
}

[[nodiscard]] constexpr AssetHandle const& handle() const noexcept
[[nodiscard]] constexpr AssetId const& handle() const noexcept
{
return m_handle;
}

private:
AssetHandle m_handle;
AssetId m_handle;
};

class AssetRenamedEvent {
public:
AssetRenamedEvent(AssetHandle const& handle, std::filesystem::path const& new_file_name, std::filesystem::path const& old_file_name)
AssetRenamedEvent(AssetId const& handle, std::filesystem::path const& new_file_name, std::filesystem::path const& old_file_name)
: m_handle(handle)
, m_new_file_name(new_file_name)
, m_old_file_name(old_file_name)
{
}

[[nodiscard]] constexpr AssetHandle const& handle() const noexcept
[[nodiscard]] constexpr AssetId const& handle() const noexcept
{
return m_handle;
}
Expand All @@ -40,13 +40,14 @@ class AssetRenamedEvent {
{
return m_old_file_name;
}

[[nodiscard]] constexpr std::filesystem::path const& new_file_name() const noexcept {

[[nodiscard]] constexpr std::filesystem::path const& new_file_name() const noexcept
{
return m_new_file_name;
}

private:
AssetHandle m_handle;
AssetId m_handle;
std::filesystem::path m_new_file_name;
std::filesystem::path m_old_file_name;
};
Expand Down
16 changes: 16 additions & 0 deletions Libraries/LibAsset/AssetHandle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "AssetHandle.h"
#include "AssetManager.h"

namespace Terran::Asset {

AssetHandle::~AssetHandle()
{
m_asset_manager->enqueue_asset_for_deletion(m_id);
}

bool AssetHandle::is_valid() const
{
return m_asset_manager->is_asset_loaded(m_id);
}

}
50 changes: 50 additions & 0 deletions Libraries/LibAsset/AssetHandle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once
#include "AssetTypes.h"

#include <LibCore/Base.h>
#include <LibCore/Event.h>
#include <LibCore/RefPtr.h>
#include <LibCore/UUID.h>
#include <LibCore/RefCounted.h>
#include <LibCore/WeakRef.h>

namespace Terran::Asset {

class AssetManager;
class AssetHandle : public Core::RefCounted {
public:
virtual ~AssetHandle() override;

constexpr AssetId const& id() const
{
return m_id;
}

bool is_valid() const;
explicit(false) constexpr operator bool() const {
return is_valid();
}

private:
// A nifty trick to ensure AssetHandle is only used with RefPtr or WeakPtr
AssetHandle(AssetId const& id, Core::RawPtr<AssetManager const> asset_manager)
: m_id(id)
, m_asset_manager(asset_manager)
{
}

private:
AssetId m_id;
Core::RawPtr<AssetManager const> m_asset_manager;
template<Core::IsRefCounted T>
friend class Core::RefPtr;

template<Core::IsRefCounted T>
friend class Core::WeakPtr;
};

using StrongAssetHandle = Core::RefPtr<AssetHandle>;
using WeakAssetHandle = Core::WeakPtr<AssetHandle>;

}

16 changes: 11 additions & 5 deletions Libraries/LibAsset/AssetImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@

#include "AssetMetadata.h"
#include "Asset.h"
#include "AssetTypes.h"
#include "AssetError.h"

#include <LibAsset/AssetTypes.h>
#include <LibCore/Base.h>
#include <LibCore/Result.h>
#include <LibCore/RefPtr.h>

#include <filesystem>

namespace Terran::Asset {

using AssetLoadResult = Core::Result<Core::RefPtr<Asset>, Core::Shared<AssetError>>;

class AssetImporter {
public:
virtual ~AssetImporter() = default;
virtual void load(AssetMetadata const& assetInfo, Terran::Core::Shared<Asset>& asset) = 0;
virtual bool save(AssetMetadata const& assetInfo, Terran::Core::Shared<Asset> const& asset) = 0;
virtual bool can_handle(std::filesystem::path const& assetPath) = 0;
virtual AssetTypeId asset_type() = 0;
[[nodiscard]] virtual AssetLoadResult load(AssetMetadata const& assetMetadata) = 0;
virtual bool save(AssetMetadata const& assetMetadata, Core::RefPtr<Asset> const& asset) = 0;
[[nodiscard]] virtual bool can_handle(std::filesystem::path const& assetPath) = 0;
[[nodiscard]] virtual AssetTypeId asset_type() = 0;
};

}
41 changes: 41 additions & 0 deletions Libraries/LibAsset/AssetImporterError.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include "AssetError.h"

#include <cstdint>
#include <string_view>

namespace Terran::Asset {

class AssetImporterError final : public AssetError {
public:
enum class Code : uint8_t {
ImporterNotFound,
};

explicit AssetImporterError(Code code)
: m_code(code)
{
}

~AssetImporterError() override = default;

[[nodiscard]] std::string_view message() const override
{
if (m_code == Code::ImporterNotFound) {
return "No importer registered for asset type";
}

return "Unknown error";
}

[[nodiscard]] std::string_view source() const override
{
return "Asset";
}

private:
Code m_code;
};

}
19 changes: 13 additions & 6 deletions Libraries/LibAsset/AssetImporterRegistry.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,43 @@
#include "AssetImporterRegistry.h"
#include "Asset.h"
#include "AssetImporter.h"
#include "AssetImporterError.h"
#include "AssetMetadata.h"
#include "AssetTypes.h"

#include <LibCore/Base.h>
#include <LibCore/Log.h>
#include <LibCore/RefPtr.h>

#include <LibCore/Result.h>
#include <unordered_map>

namespace Terran::Asset {

std::unordered_map<AssetTypeId, Terran::Core::Shared<AssetImporter>> AssetImporterRegistry::s_loaders;

void AssetImporterRegistry::load(AssetMetadata const& assetMetadata, Terran::Core::Shared<Asset>& asset)
AssetLoadResult AssetImporterRegistry::load(AssetMetadata const& assetMetadata)
{
AssetTypeId const type_id = assetMetadata.Type;
if (s_loaders.contains(type_id)) {
s_loaders[type_id]->load(assetMetadata, asset);
return;
return s_loaders[type_id]->load(assetMetadata);
}

TR_CORE_ERROR(TR_LOG_ASSET, "Invalid asset type for asset: {0}", assetMetadata.Path);
TR_ERROR(TR_LOG_ASSET, "Invalid asset type for asset: {0}", assetMetadata.Path);
return { Core::CreateShared<AssetImporterError>(AssetImporterError::Code::ImporterNotFound) };
}

bool AssetImporterRegistry::save(AssetMetadata const& assetMetadata, Terran::Core::Shared<Asset> const& asset)
bool AssetImporterRegistry::save(AssetMetadata const& assetMetadata, Core::RefPtr<Asset> const& asset)
{
if(assetMetadata.Type != asset->type()) {
return false;
}

AssetTypeId const type_id = assetMetadata.Type;
if (s_loaders.contains(type_id))
return s_loaders[type_id]->save(assetMetadata, asset);

TR_CORE_ERROR(TR_LOG_ASSET, "Invalid asset type for asset: {0}", assetMetadata.Path);
TR_ERROR(TR_LOG_ASSET, "Invalid asset type for asset: {0}", assetMetadata.Path);
return false;
}

Expand Down
Loading
Loading