ass_renderer/plugin/
mod.rs1use crate::utils::RenderError;
4use ahash::AHashMap;
5
6#[cfg(feature = "nostd")]
7use alloc::{
8 string::{String, ToString},
9 sync::Arc,
10 vec::Vec,
11};
12#[cfg(not(feature = "nostd"))]
13use std::{
14 string::{String, ToString},
15 sync::Arc,
16 vec::Vec,
17};
18
19pub mod effects;
20
21pub trait EffectPlugin: Send + Sync {
23 fn name(&self) -> &str;
25
26 fn version(&self) -> &str;
28
29 fn apply_cpu(
31 &self,
32 pixels: &mut [u8],
33 width: u32,
34 height: u32,
35 params: &EffectParams,
36 ) -> Result<(), RenderError>;
37
38 fn shader_code(&self) -> Option<&str> {
40 None
41 }
42
43 fn supports_gpu(&self) -> bool {
45 self.shader_code().is_some()
46 }
47}
48
49#[derive(Debug, Clone)]
51pub struct EffectParams {
52 pub strength: f32,
54 pub custom: AHashMap<String, EffectValue>,
56}
57
58#[derive(Debug, Clone)]
60pub enum EffectValue {
61 Float(f32),
63 Integer(i32),
65 Color([u8; 4]),
67 Boolean(bool),
69 String(String),
71}
72
73impl EffectParams {
74 pub fn new(strength: f32) -> Self {
76 Self {
77 strength,
78 custom: AHashMap::new(),
79 }
80 }
81
82 pub fn set(&mut self, key: impl Into<String>, value: EffectValue) {
84 self.custom.insert(key.into(), value);
85 }
86
87 pub fn get(&self, key: &str) -> Option<&EffectValue> {
89 self.custom.get(key)
90 }
91
92 pub fn get_float(&self, key: &str) -> Option<f32> {
94 self.custom.get(key).and_then(|v| {
95 if let EffectValue::Float(f) = v {
96 Some(*f)
97 } else {
98 None
99 }
100 })
101 }
102
103 pub fn get_int(&self, key: &str) -> Option<i32> {
105 self.custom.get(key).and_then(|v| {
106 if let EffectValue::Integer(i) = v {
107 Some(*i)
108 } else {
109 None
110 }
111 })
112 }
113
114 pub fn get_color(&self, key: &str) -> Option<[u8; 4]> {
116 self.custom.get(key).and_then(|v| {
117 if let EffectValue::Color(c) = v {
118 Some(*c)
119 } else {
120 None
121 }
122 })
123 }
124}
125
126pub struct PluginRegistry {
128 effects: AHashMap<String, Arc<dyn EffectPlugin>>,
129}
130
131impl PluginRegistry {
132 pub fn new() -> Self {
134 Self {
135 effects: AHashMap::new(),
136 }
137 }
138
139 pub fn register_effect(&mut self, plugin: Arc<dyn EffectPlugin>) {
141 self.effects.insert(plugin.name().to_string(), plugin);
142 }
143
144 pub fn get_effect(&self, name: &str) -> Option<Arc<dyn EffectPlugin>> {
146 self.effects.get(name).cloned()
147 }
148
149 pub fn list_effects(&self) -> Vec<String> {
151 self.effects.keys().cloned().collect()
152 }
153
154 pub fn unregister_effect(&mut self, name: &str) -> Option<Arc<dyn EffectPlugin>> {
156 self.effects.remove(name)
157 }
158
159 pub fn clear(&mut self) {
161 self.effects.clear();
162 }
163}
164
165impl Default for PluginRegistry {
166 fn default() -> Self {
167 Self::new()
168 }
169}