sim_lib_music_serial/
registry.rs1use std::collections::BTreeMap;
4use std::sync::Arc;
5
6use crate::{
7 ChromaticSerialRealizer, MarkedChromaticInflectionRealizer, ModalDegreeCycleRealizer,
8 NearestScaleToneRealizer, NonPitchSpineRealizer, RealizationContext, RealizerId, SerialPlan,
9 SerialRealization, SerialRealizer, StrictRealizationError,
10};
11
12#[derive(Clone, Default)]
14pub struct SerialRealizerRegistry {
15 entries: BTreeMap<RealizerId, Arc<dyn SerialRealizer>>,
16}
17
18impl SerialRealizerRegistry {
19 pub fn new() -> Self {
21 Self::default()
22 }
23
24 pub fn register(&mut self, realizer: Arc<dyn SerialRealizer>) -> Result<(), RealizerId> {
26 if self.entries.contains_key(realizer.id()) {
27 return Err(realizer.id().clone());
28 }
29 self.entries.insert(realizer.id().clone(), realizer);
30 Ok(())
31 }
32
33 pub fn replace(
35 &mut self,
36 realizer: Arc<dyn SerialRealizer>,
37 ) -> Option<Arc<dyn SerialRealizer>> {
38 self.entries.insert(realizer.id().clone(), realizer)
39 }
40
41 pub fn get(&self, id: &RealizerId) -> Option<&Arc<dyn SerialRealizer>> {
43 self.entries.get(id)
44 }
45
46 pub fn ids(&self) -> Vec<RealizerId> {
48 self.entries.keys().cloned().collect()
49 }
50
51 pub fn realize(
53 &self,
54 id: &RealizerId,
55 plan: &SerialPlan,
56 context: &RealizationContext,
57 ) -> Result<SerialRealization, StrictRealizationError> {
58 let Some(realizer) = self.get(id) else {
59 return Err(StrictRealizationError::UnknownRealizer(id.clone()));
60 };
61 realizer.realize(plan, context)
62 }
63
64 pub fn realize_named(
66 &self,
67 id: &str,
68 plan: &SerialPlan,
69 context: &RealizationContext,
70 ) -> Result<SerialRealization, StrictRealizationError> {
71 let id = RealizerId::new(id)
72 .map_err(|error| StrictRealizationError::PitchMap(error.to_string()))?;
73 self.realize(&id, plan, context)
74 }
75}
76
77pub fn default_realizer_registry() -> SerialRealizerRegistry {
79 let mut registry = SerialRealizerRegistry::new();
80 registry.replace(Arc::new(ChromaticSerialRealizer::default()));
81 registry.replace(Arc::new(ModalDegreeCycleRealizer::default()));
82 registry.replace(Arc::new(NearestScaleToneRealizer::default()));
83 registry.replace(Arc::new(MarkedChromaticInflectionRealizer::default()));
84 registry.replace(Arc::new(NonPitchSpineRealizer::default()));
85 registry
86}