khora_core/asset/metadata.rs
1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use super::uuid::AssetUUID;
16use serde::{Deserialize, Serialize};
17use std::{collections::HashMap, path::PathBuf};
18
19/// On-disk compression scheme for a packed asset.
20#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
21pub enum CompressionKind {
22 /// Raw bytes — no compression applied. Fastest read path.
23 #[default]
24 None,
25 /// LZ4 block compression (`lz4_flex`). Cheap to decompress, modest
26 /// ratio. Good default for shipping builds.
27 Lz4,
28}
29
30/// Represents the physical source of an asset's data.
31///
32/// This enum allows the asset system to transparently handle assets from two
33/// different contexts:
34/// - In editor/development mode, assets are loaded directly from loose files on disk (`Path`).
35/// - In release/standalone mode, assets are loaded from an optimized packfile (`Packed`).
36///
37/// **Pack format version:** v2 added per-entry compression (`compression`,
38/// `uncompressed_size`). v1 packs (without these fields) are no longer
39/// supported on the read side; the loader bails on the header version
40/// check before reaching this struct.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub enum AssetSource {
43 /// The asset is a loose file on disk. The `PathBuf` points to the file.
44 Path(PathBuf),
45 /// The asset is located within a packfile.
46 Packed {
47 /// Byte offset from the start of the asset region (i.e. *after*
48 /// the 24-byte header) in `data.pack`.
49 offset: u64,
50 /// Number of bytes to read from the pack at `offset` — the
51 /// **on-disk size**, possibly compressed.
52 size: u64,
53 /// Size of the asset after decompression. Equals `size` when
54 /// `compression == CompressionKind::None`.
55 uncompressed_size: u64,
56 /// Compression scheme applied to the bytes between `offset` and
57 /// `offset + size`.
58 compression: CompressionKind,
59 },
60}
61
62/// Serializable metadata that describes an asset and its relationships.
63///
64/// This structure serves as the "identity card" for each asset within the engine's
65/// Virtual File System (VFS). It contains all the information needed by the
66/// `AssetAgent` to make intelligent loading and management decisions *without*
67/// having to load the actual asset data from disk.
68///
69/// A collection of these metadata entries forms the VFS "Index".
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct AssetMetadata {
72 /// The unique, stable identifier for this asset. This is the primary key.
73 pub uuid: AssetUUID,
74
75 /// The canonical path to the original source file (e.g., a `.blend` or `.png`).
76 /// This is primarily used by the asset importer and editor tooling.
77 pub source_path: PathBuf,
78
79 /// A string identifier for the asset's type (e.g., "texture", "mesh", "material").
80 /// This is used by the loading system to select the correct `AssetLoader` trait object.
81 pub asset_type_name: String,
82
83 /// A list of other assets that this asset directly depends on.
84 /// For example, a material asset would list its required texture assets here.
85 /// This information is crucial for tracking dependencies and ensuring all
86 /// necessary assets are loaded.
87 pub dependencies: Vec<AssetUUID>,
88
89 /// A map of available, pre-processed asset variants ready for runtime use.
90 ///
91 /// The key is a variant identifier (e.g., "LOD0", "4K", "low_quality"),
92 /// and the value is the source of the compiled, engine-ready file for that variant. (Which contains the necessary metadata for loading the asset.)
93 /// This map allows the `AssetAgent` to make strategic choices, such as loading
94 /// a lower-quality texture to stay within a VRAM budget.
95 pub variants: HashMap<String, AssetSource>,
96
97 /// A collection of semantic tags for advanced querying and organization.
98 /// Tags can be used to group assets for collective operations, such as
99 /// loading all assets for a specific game level or character.
100 pub tags: Vec<String>,
101}