1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use std::cell::RefCell;
use crate::prelude::*;
/// inlet.rs
///
///
///
pub struct Inlet {
name: String,
source_connections: Vec<Box<dyn SourceConnection>>,
default_value: CapsulePtr,
buffer: RefCell<Option<CapsulePtr>>,
}
impl Inlet {
pub fn new(name: &str, default_value: Value) -> Inlet {
Inlet{
name: name.to_owned(),
default_value: default_value.into(),
source_connections: Vec::new(),
buffer: RefCell::new(None),
}
}
pub fn name(&self) -> &String {
&self.name
}
// pub fn source_connection_by_identifier(&mut self, identifier: &Identifier) -> Option<&Box<dyn SourceConnection>> {
// for c in self.source_connections.iter() {
// if c.identifier() == identifier {
// return Some(c)
// }
// }
// return None
// }
pub fn source_connections(&self) -> &Vec<Box<dyn SourceConnection>> {
return &self.source_connections
}
// pub fn source_connections_mut(&mut self) -> &mut Vec<Box<dyn SourceConnection>> {
// return &mut self.source_connections
// }
pub fn profile_full(&self) -> JuizResult<Value> {
Ok(jvalue!({
"name": self.name,
"source_connections": self.source_connections.iter().map(|sc| -> Value {
sc.profile_full().unwrap_or_else(|e| { jvalue!(format!("Error. SourceConnection::profile_full() failed. Error {e:}")) })
}).collect::<Vec<Value>>()
}).into())
}
pub fn is_updated(&self) -> JuizResult<bool> {
//self.source_connections.iter().find_map(|sc| { if sc.is_source_updated() })
for sc in self.source_connections.iter() {
if sc.is_source_updated()? {
return Ok(true);
}
}
Ok(false)
}
/// データを収集。
///
/// まず全てのコネクションに対してpullでデータ収集を行う。
/// 出力はself.bufferに保存されるため、あとからの接続が優先される。
/// エラーはログは出すが無視する。
/// 接続が無いか、全ての接続がPull型ではないか、もしくはPull型接続をpullしてもエラーがあった場合、
/// self.bufferを確認する。bufferがNoneならばデフォルトの値を出力する。
/// bufferにデータが残っていればそれを返す。
pub fn collect_value(&self) -> CapsulePtr {
log::trace!("Inlet({})::collect_value() called", self.name());
for sc in self.source_connections.iter() {
if sc.connection_type() == ConnectionType::Pull {
match sc.pull() {
Err(e) => {
log::error!("Pull data via Connection({}) in Inlet({})::collect_value() failed. Error: {:}", sc.name(), self.name(), e);
},
Ok(output) => {
self.buffer.replace(Some(output.clone()));
//return self.buffer.borrow().unwrap().clone();
}
}
}
}
if self.buffer.borrow().is_none() {
self.default_value.clone()
} else {
self.buffer.borrow().clone().unwrap()
}
}
pub(crate) fn insert(&mut self, con: Box<dyn SourceConnection + 'static>) {
self.source_connections.push(con);
}
pub fn bind(&mut self, value: CapsulePtr) -> JuizResult<CapsulePtr> {
//self.buffer = value;
if self.buffer.borrow().is_none() {
self.buffer.replace(Some(value.clone()));
}
Ok(value)
}
}