oxygengine_core/assets/protocols/
meta.rs1use crate::assets::{
2 asset::{Asset, AssetId},
3 protocol::{AssetLoadResult, AssetProtocol, AssetVariant, Meta},
4};
5use serde::{Deserialize, Serialize};
6use std::{collections::HashMap, str::from_utf8};
7
8#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
9pub struct MetaAsset {
10 #[serde(default)]
11 target: Vec<String>,
12 #[serde(skip)]
13 ids: HashMap<String, AssetId>,
14}
15
16impl MetaAsset {
17 pub fn with_target(mut self, target: impl ToString) -> Self {
18 self.target.push(target.to_string());
19 self
20 }
21
22 pub fn target(&self) -> impl Iterator<Item = &str> {
23 self.target.iter().map(|path| path.as_str())
24 }
25
26 pub fn asset_ids(&self) -> impl Iterator<Item = (&str, AssetId)> {
27 self.ids.iter().map(|(key, id)| (key.as_str(), *id))
28 }
29
30 pub fn asset_id(&self, key: &str) -> Option<AssetId> {
31 self.ids.get(key).copied()
32 }
33}
34
35pub struct MetaAssetProtocol;
36
37impl AssetProtocol for MetaAssetProtocol {
38 fn name(&self) -> &str {
39 "meta"
40 }
41
42 fn on_load_with_path(&mut self, path: &str, data: Vec<u8>) -> AssetLoadResult {
43 let data = if path.ends_with(".asset") {
44 let data = from_utf8(&data).unwrap();
45 match serde_json::from_str::<MetaAsset>(data) {
46 Ok(value) => value,
47 Err(error) => {
48 return AssetLoadResult::Error(format!(
49 "Error loading Meta JSON asset: {:?}",
50 error
51 ));
52 }
53 }
54 } else {
55 match bincode::deserialize::<MetaAsset>(&data) {
56 Ok(value) => value,
57 Err(error) => {
58 return AssetLoadResult::Error(format!(
59 "Error loading Meta binary asset: {:?}",
60 error
61 ));
62 }
63 }
64 };
65 let list = data
66 .target
67 .iter()
68 .map(|path| (path.to_owned(), path.to_owned()))
69 .collect();
70 AssetLoadResult::Yield(None, list)
71 }
72
73 fn on_resume(&mut self, _: Meta, list: &[(&str, &Asset)]) -> AssetLoadResult {
74 let target = list
75 .iter()
76 .map(|(_, asset)| asset.to_full_path())
77 .collect::<Vec<_>>();
78 let ids = list
79 .iter()
80 .map(|(key, asset)| (key.to_string(), asset.id()))
81 .collect::<HashMap<_, _>>();
82 AssetLoadResult::Data(Box::new(MetaAsset { target, ids }))
83 }
84
85 fn on_unload(&mut self, asset: &Asset) -> Option<Vec<AssetVariant>> {
86 asset
87 .get::<MetaAsset>()
88 .map(|asset| asset.ids.values().map(|id| AssetVariant::Id(*id)).collect())
89 }
90
91 fn on_load(&mut self, _data: Vec<u8>) -> AssetLoadResult {
93 unreachable!()
94 }
95}