Skip to main content

pfx_play/
live.rs

1use std::collections::BTreeMap;
2
3use pfx_load::scene::{Target, Value};
4
5use crate::tunables::TunableValue;
6
7#[derive(Clone, Debug, PartialEq)]
8pub enum Edit {
9    Scene {
10        target: Target,
11        path: Vec<String>,
12        value: Value,
13    },
14    Tunable {
15        name: String,
16        value: TunableValue,
17    },
18}
19
20impl Edit {
21    pub fn scene(target: Target, path: &[&str], value: impl Into<Value>) -> Edit {
22        Edit::Scene {
23            target,
24            path: path.iter().map(|key| key.to_string()).collect(),
25            value: value.into(),
26        }
27    }
28
29    pub fn tunable(name: &str, value: TunableValue) -> Edit {
30        Edit::Tunable {
31            name: name.to_string(),
32            value,
33        }
34    }
35
36    pub fn key(&self) -> String {
37        match self {
38            Edit::Scene { target, path, .. } => format!("{target} {}", path.join(".")),
39            Edit::Tunable { name, .. } => format!("tunable {name}"),
40        }
41    }
42}
43
44#[derive(Clone, Debug, PartialEq)]
45pub struct Stamped {
46    pub tick: u64,
47    pub edit: Edit,
48}
49
50#[derive(Clone, Debug, Default, PartialEq)]
51pub struct Pending {
52    edits: BTreeMap<String, Edit>,
53}
54
55impl Pending {
56    pub(crate) fn hold(&mut self, edit: Edit) {
57        self.edits.insert(edit.key(), edit);
58    }
59
60    pub fn is_empty(&self) -> bool {
61        self.edits.is_empty()
62    }
63
64    pub fn len(&self) -> usize {
65        self.edits.len()
66    }
67
68    pub fn get(&self, key: &str) -> Option<&Edit> {
69        self.edits.get(key)
70    }
71
72    pub fn contains(&self, key: &str) -> bool {
73        self.edits.contains_key(key)
74    }
75
76    pub fn iter(&self) -> impl Iterator<Item = &Edit> {
77        self.edits.values()
78    }
79
80    pub fn scene(&self) -> impl Iterator<Item = (&Target, &[String], &Value)> {
81        self.edits.values().filter_map(|edit| match edit {
82            Edit::Scene {
83                target,
84                path,
85                value,
86            } => Some((target, path.as_slice(), value)),
87            Edit::Tunable { .. } => None,
88        })
89    }
90
91    pub fn tunables(&self) -> impl Iterator<Item = (&str, TunableValue)> {
92        self.edits.values().filter_map(|edit| match edit {
93            Edit::Tunable { name, value } => Some((name.as_str(), *value)),
94            Edit::Scene { .. } => None,
95        })
96    }
97}