motion_core/asset/
environment.rs1use crate::sync::MutexExt;
4use std::{
5 any::Any,
6 fmt,
7 sync::{Arc, Mutex},
8};
9
10#[derive(Clone, Default, Debug)]
12pub struct FontUsage(Arc<Mutex<Vec<FontIdentity>>>);
13
14impl FontUsage {
15 pub fn record(&self, font: FontIdentity) {
17 let mut fonts = self.0.lock_unpoisoned();
18 if !fonts.contains(&font) {
19 fonts.push(font);
20 }
21 }
22
23 pub fn fonts(&self) -> Vec<FontIdentity> {
25 let mut fonts = self.0.lock_unpoisoned().clone();
26 fonts.sort_by(|left, right| {
27 (&left.name, left.file_hash).cmp(&(&right.name, right.file_hash))
28 });
29 fonts
30 }
31}
32
33#[derive(Clone)]
37pub struct FontEnvironment {
38 value: Arc<dyn Any + Send + Sync>,
39 identity: u64,
40 usage: Option<Arc<dyn Fn() -> Vec<FontIdentity> + Send + Sync>>,
41}
42
43impl std::panic::RefUnwindSafe for FontEnvironment {}
44
45impl std::panic::UnwindSafe for FontEnvironment {}
46
47impl From<&FontEnvironment> for FontEnvironment {
48 fn from(value: &FontEnvironment) -> Self {
49 value.clone()
50 }
51}
52
53impl FontEnvironment {
54 pub fn new<T: Any + Send + Sync>(value: T, identity: u64) -> Self {
56 Self {
57 value: Arc::new(value),
58 identity,
59 usage: None,
60 }
61 }
62
63 pub fn snapshot_id(&self) -> u64 {
65 self.identity
66 }
67
68 pub fn with_usage(
70 mut self,
71 usage: impl Fn() -> Vec<FontIdentity> + Send + Sync + 'static,
72 ) -> Self {
73 self.usage = Some(Arc::new(usage));
74 self
75 }
76
77 pub fn used_fonts(&self) -> Vec<FontIdentity> {
79 self.usage.as_ref().map_or_else(Vec::new, |usage| usage())
80 }
81
82 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
84 self.value.downcast_ref()
85 }
86}
87
88impl fmt::Debug for FontEnvironment {
89 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
90 formatter
91 .debug_struct("FontEnvironment")
92 .field("snapshot", &self.identity)
93 .finish_non_exhaustive()
94 }
95}
96
97#[derive(Clone, Debug, PartialEq, Eq)]
101pub struct FontIdentity {
102 pub name: Option<String>,
104 pub file_hash: u64,
106}