tiger_lib/vic3/data/
media_aliases.rs

1use crate::block::Block;
2use crate::db::{Db, DbKind};
3use crate::everything::Everything;
4use crate::game::GameFlags;
5use crate::helpers::TigerHashSet;
6use crate::item::{Item, ItemLoader};
7use crate::report::{ErrorKey, untidy};
8use crate::token::Token;
9use crate::validator::Validator;
10
11#[derive(Clone, Debug)]
12pub struct MediaAlias {}
13
14inventory::submit! {
15    ItemLoader::Normal(GameFlags::Vic3, Item::MediaAlias, MediaAlias::add)
16}
17
18impl MediaAlias {
19    pub fn add(db: &mut Db, key: Token, block: Block) {
20        db.add_exact_dup_ok(Item::MediaAlias, key, block, Box::new(Self {}));
21    }
22}
23
24impl DbKind for MediaAlias {
25    fn validate(&self, key: &Token, block: &Block, data: &Everything) {
26        let mut vd = Validator::new(block, data);
27
28        vd.field_item("video", Item::File);
29        vd.field_item("audio", Item::Sound);
30        vd.field_item("texture", Item::File);
31        vd.field_item("fallback", Item::MediaAlias);
32        check_fallback_cycle(key, block, data);
33    }
34}
35
36fn check_fallback_cycle(key: &Token, block: &Block, data: &Everything) {
37    let mut fallback;
38    if let Some(key) = block.get_field_value("fallback") {
39        fallback = key;
40    } else {
41        return;
42    }
43    let mut seen = TigerHashSet::default();
44    seen.insert(key.as_str());
45    loop {
46        if seen.contains(fallback.as_str()) {
47            let msg = "fallbacks cycle back to the same key";
48            // TODO: check if fatal
49            untidy(ErrorKey::Loop).strong().msg(msg).loc(fallback).push();
50            break;
51        }
52        seen.insert(fallback.as_str());
53        if let Some((_, block)) = data.get_key_block(Item::MediaAlias, fallback.as_str()) {
54            if let Some(key) = block.get_field_value("fallback") {
55                fallback = key;
56            } else {
57                break;
58            }
59        } else {
60            break;
61        }
62    }
63}