feat(Resources): Add ResourcePackage system for asset bundling

- Implement ResourcePackageBuilder for creating .xcp packages
- Implement ResourcePackage for reading packaged assets
- Add unit tests for package builder and package reader
This commit is contained in:
2026-03-18 00:49:22 +08:00
parent 02ca59edf6
commit bd69c3e124
5 changed files with 448 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
#pragma once
#include "ResourceTypes.h"
#include "../Containers/String.h"
#include "../Containers/Array.h"
#include "../Core/Types.h"
namespace XCEngine {
namespace Resources {
struct PackageFileEntry {
Containers::String relativePath;
size_t size;
Core::uint64 checksum;
size_t offset;
};
class ResourcePackageBuilder {
public:
ResourcePackageBuilder();
~ResourcePackageBuilder();
bool AddFile(const Containers::String& sourcePath, const Containers::String& relativePath);
bool AddDirectory(const Containers::String& sourceDir, const Containers::String& relativeBase = "");
void SetOutputPath(const Containers::String& path) { m_outputPath = path; }
const Containers::String& GetOutputPath() const { return m_outputPath; }
bool Build();
float GetProgress() const { return m_progress; }
const Containers::String& GetError() const { return m_error; }
private:
Core::uint64 CalculateChecksum(const void* data, size_t size);
bool WriteHeader(FILE* file, size_t dataOffset);
bool WriteManifest(FILE* file);
bool WriteData(FILE* file);
struct FileEntry {
Containers::String sourcePath;
Containers::String relativePath;
size_t size;
Core::uint64 checksum;
size_t offset;
};
Containers::String m_outputPath;
Containers::Array<FileEntry> m_files;
float m_progress = 0.0f;
Containers::String m_error;
};
class ResourcePackage {
public:
ResourcePackage();
~ResourcePackage();
bool Open(const Containers::String& packagePath);
void Close();
bool IsValid() const { return m_isValid; }
bool Exists(const Containers::String& relativePath) const;
Containers::Array<Core::uint8> Read(const Containers::String& relativePath) const;
size_t GetSize(const Containers::String& relativePath) const;
void Enumerate(const Containers::String& pattern, Containers::Array<Containers::String>& outFiles) const;
struct PackageInfo {
Containers::String path;
Core::uint16 version;
size_t fileCount;
size_t totalSize;
};
const PackageInfo& GetInfo() const { return m_info; }
private:
bool ReadHeader(FILE* file);
bool ReadManifest(FILE* file);
bool m_isValid = false;
PackageInfo m_info;
Containers::String m_packagePath;
size_t m_dataOffset;
struct FileEntryInternal {
Containers::String path;
size_t size;
size_t offset;
Core::uint64 checksum;
};
Containers::Array<FileEntryInternal> m_entries;
};
} // namespace Resources
} // namespace XCEngine