mecha10_behavior_runtime/
registry.rs1use crate::BoxedBehavior;
6use anyhow::{anyhow, Context as AnyhowContext, Result};
7use serde_json::Value;
8use std::collections::HashMap;
9use std::sync::{Arc, RwLock};
10
11pub type NodeFactory = Arc<dyn Fn(Value) -> Result<BoxedBehavior> + Send + Sync>;
12
13#[derive(Clone)]
14pub struct NodeRegistry {
15 factories: Arc<RwLock<HashMap<String, NodeFactory>>>,
16}
17
18impl NodeRegistry {
19 pub fn new() -> Self {
21 Self {
22 factories: Arc::new(RwLock::new(HashMap::new())),
23 }
24 }
25
26 pub fn register<F>(&mut self, node_type: impl Into<String>, factory: F)
30 where
31 F: Fn(Value) -> Result<BoxedBehavior> + Send + Sync + 'static,
32 {
33 let mut factories = self.factories.write().unwrap();
34 factories.insert(node_type.into(), Arc::new(factory));
35 }
36
37 pub fn create(&self, node_type: &str, config: Value) -> Result<BoxedBehavior> {
40 let factories = self.factories.read().unwrap();
41
42 let factory = factories
43 .get(node_type)
44 .ok_or_else(|| anyhow!("Node type '{}' not registered", node_type))?;
45
46 factory(config).with_context(|| format!("Failed to create node of type '{}'", node_type))
47 }
48
49 pub fn has_node(&self, node_type: &str) -> bool {
51 self.contains(node_type)
52 }
53
54 pub fn contains(&self, node_type: &str) -> bool {
58 let factories = self.factories.read().unwrap();
59 factories.contains_key(node_type)
60 }
61
62 pub fn registered_types(&self) -> Vec<String> {
64 let factories = self.factories.read().unwrap();
65 factories.keys().cloned().collect()
66 }
67
68 pub fn len(&self) -> usize {
70 let factories = self.factories.read().unwrap();
71 factories.len()
72 }
73
74 pub fn is_empty(&self) -> bool {
76 self.len() == 0
77 }
78}
79
80impl Default for NodeRegistry {
81 fn default() -> Self {
82 Self::new()
83 }
84}
85
86impl std::fmt::Debug for NodeRegistry {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 let factories = self.factories.read().unwrap();
89 f.debug_struct("NodeRegistry")
90 .field("registered_types", &factories.keys().collect::<Vec<_>>())
91 .finish()
92 }
93}