1#![allow(missing_docs)]
2use std::fmt::Display;
5use std::ops::Range;
6
7use glam::Vec2;
8use serde::{Deserialize, Serialize};
9use uuid::Uuid;
10
11use crate::anim_obj::AnimObj;
12use crate::color::Color;
13use crate::ease::Ease;
14use crate::seconds::Time;
15use crate::sfx::Sfx;
16
17#[derive(Clone)]
18pub struct CurrentClosure(pub std::sync::Arc<dyn Fn(AnimObj) -> AnimOP + Send + Sync>);
19impl std::fmt::Debug for CurrentClosure {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 f.debug_struct("CurrentClosure").finish_non_exhaustive()
22 }
23}
24
25#[derive(Clone, Debug, Serialize, Deserialize)]
26pub struct SourceLoc {
27 pub file: String,
28 pub line: u32,
29}
30impl Display for SourceLoc {
31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 write!(f, "at {}:{}", self.file, self.line)
33 }
34}
35
36#[derive(Clone, Debug, Serialize, Deserialize)]
37pub enum AnimOP {
38 Instantiate(Box<AnimObj>, Option<SourceLoc>),
39 TransformMovePos(Uuid, Vec2, Time, Ease, Option<SourceLoc>),
40 TransformMoveToObj(Uuid, Uuid, Vec2, Time, Ease, Option<SourceLoc>),
41 TransformRotate(Uuid, f32, Time, Ease, Option<SourceLoc>),
42 TransformScale(Uuid, Vec2, Time, Ease, Option<SourceLoc>),
43 CodeAddLines(
44 Uuid,
45 String,
46 usize,
47 Time,
48 Ease,
49 CodeAnimationStyle,
50 Option<SourceLoc>,
51 ),
52 CodeModifyLine(
53 Uuid,
54 u32,
55 String,
56 Time,
57 Ease,
58 CodeAnimationStyle,
59 Option<SourceLoc>,
60 ),
61 CodeRemoveLines(
62 Uuid,
63 Range<u32>,
64 Time,
65 Ease,
66 CodeAnimationStyle,
67 Option<SourceLoc>,
68 ),
69 CodeHighlight(Uuid, CodeHighlightAction, Option<SourceLoc>),
70 All(Vec<Self>, Option<SourceLoc>),
71 Sequence(Vec<Self>, Option<SourceLoc>),
72 Wait(Time, Option<SourceLoc>),
73 PlaySound(Sfx, Time, Option<SourceLoc>),
74}
75
76impl AnimOP {
77 #[must_use]
78 pub const fn location(&self) -> Option<&SourceLoc> {
79 match self {
80 Self::Instantiate(_, l)
81 | Self::TransformMovePos(_, _, _, _, l)
82 | Self::TransformMoveToObj(_, _, _, _, _, l)
83 | Self::TransformRotate(_, _, _, _, l)
84 | Self::TransformScale(_, _, _, _, l)
85 | Self::CodeAddLines(_, _, _, _, _, _, l)
86 | Self::CodeModifyLine(_, _, _, _, _, _, l)
87 | Self::CodeRemoveLines(_, _, _, _, _, l)
88 | Self::CodeHighlight(_, _, l)
89 | Self::All(_, l)
90 | Self::Sequence(_, l)
91 | Self::Wait(_, l)
92 | Self::PlaySound(_, _, l) => l.as_ref(),
93 }
94 }
95}
96
97#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
98pub enum CodeAnimationStyle {
99 TypeWriter,
100 TypeWriterInstantResize,
101 Fold,
102}
103
104#[derive(Clone, Debug, Serialize, Deserialize)]
105pub enum CodeHighlightAction {
106 Lines {
107 ranges: Vec<Range<usize>>,
108 color: Color,
109 duration: Time,
110 curve: Ease,
111 },
112 Pattern {
113 regex: String,
114 color: Color,
115 duration: Time,
116 curve: Ease,
117 },
118}
119impl CodeHighlightAction {
120 #[must_use]
121 pub const fn duration_and_curve(&self) -> (Time, Ease) {
122 match self {
123 Self::Lines {
124 ranges: _,
125 color: _,
126 duration,
127 curve,
128 }
129 | Self::Pattern {
130 regex: _,
131 color: _,
132 duration,
133 curve,
134 } => (*duration, *curve),
135 }
136 }
137}
138
139pub trait IntoAnimOp {
140 fn into_anim_op(self) -> AnimOP;
141}
142
143impl IntoAnimOp for AnimOP {
144 fn into_anim_op(self) -> AnimOP {
145 self
146 }
147}
148
149impl AnimOP {
150 #[must_use]
151 pub fn with_location(mut self, loc: SourceLoc) -> Self {
152 match &mut self {
153 Self::Instantiate(_, l)
154 | Self::TransformMovePos(_, _, _, _, l)
155 | Self::TransformMoveToObj(_, _, _, _, _, l)
156 | Self::TransformRotate(_, _, _, _, l)
157 | Self::TransformScale(_, _, _, _, l)
158 | Self::CodeAddLines(_, _, _, _, _, _, l)
159 | Self::CodeModifyLine(_, _, _, _, _, _, l)
160 | Self::CodeRemoveLines(_, _, _, _, _, l)
161 | Self::CodeHighlight(_, _, l)
162 | Self::All(_, l)
163 | Self::Sequence(_, l)
164 | Self::Wait(_, l)
165 | Self::PlaySound(_, _, l) => *l = Some(loc),
166 }
167 self
168 }
169}