fmt
This commit is contained in:
@ -1134,7 +1134,8 @@ where
|
||||
let max_connections = self.graph[*param]
|
||||
.max_connections
|
||||
.map(NonZeroU32::get)
|
||||
.unwrap_or(u32::MAX) as usize;
|
||||
.unwrap_or(u32::MAX)
|
||||
as usize;
|
||||
draw_port(
|
||||
pan_zoom,
|
||||
ui,
|
||||
@ -1209,8 +1210,12 @@ where
|
||||
vec2(outer_rect.width(), outer_rect.height() - titlebar_height),
|
||||
);
|
||||
let body = Shape::Rect(
|
||||
RectShape::filled(body_rect, CornerRadius::ZERO, background_color)
|
||||
.with_texture(Default::default(), Rect::ZERO),
|
||||
RectShape::filled(
|
||||
body_rect,
|
||||
CornerRadius::ZERO,
|
||||
background_color,
|
||||
)
|
||||
.with_texture(Default::default(), Rect::ZERO),
|
||||
);
|
||||
|
||||
let bottom_body_rect = Rect::from_min_size(
|
||||
@ -1230,8 +1235,9 @@ where
|
||||
RectShape::filled(
|
||||
node_rect.expand(1.0 * pan_zoom.zoom),
|
||||
rounding,
|
||||
Color32::WHITE.lighten(0.8))
|
||||
.with_texture(Default::default(), Rect::ZERO)
|
||||
Color32::WHITE.lighten(0.8),
|
||||
)
|
||||
.with_texture(Default::default(), Rect::ZERO),
|
||||
)
|
||||
} else {
|
||||
Shape::Noop
|
||||
|
||||
@ -79,8 +79,8 @@ where
|
||||
let mut query_submit = resp.lost_focus()
|
||||
&& ui.input(|i| i.key_pressed(Key::Enter));
|
||||
|
||||
let max_height =
|
||||
ui.input(|i| f32::max(i.content_rect().height() * 0.5, 200.));
|
||||
let max_height = ui
|
||||
.input(|i| f32::max(i.content_rect().height() * 0.5, 200.));
|
||||
let scroll_area_width = resp.rect.width();
|
||||
|
||||
let all_kinds = all_kinds.all_kinds();
|
||||
|
||||
@ -494,7 +494,7 @@ impl NodeInstruction {
|
||||
],
|
||||
| Self::Sleep => vec![("seconds", PositiveInt)],
|
||||
| Self::StringToSvg => vec![("value", String)],
|
||||
| Self::SaveSvg => vec![("path", Path), ("value", Svg)]
|
||||
| Self::SaveSvg => vec![("path", Path), ("value", Svg)],
|
||||
}
|
||||
.into_iter()
|
||||
.map(|e| (e.0.to_string(), e.1))
|
||||
@ -695,10 +695,7 @@ impl NodeInstruction {
|
||||
PositiveGroupFunction,
|
||||
assert::positive_grouping::PositiveAssert::default()
|
||||
),
|
||||
| BasicDataType::Svg => helper!(
|
||||
Svg,
|
||||
super::svg::Svg::default()
|
||||
)
|
||||
| BasicDataType::Svg => helper!(Svg, super::svg::Svg::default()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -754,8 +751,7 @@ impl NodeInstruction {
|
||||
helper!(PositiveAssertFunction),
|
||||
| BasicDataType::PositiveGroupFunction =>
|
||||
helper!(PositiveGroupFunction),
|
||||
| BasicDataType::Svg =>
|
||||
helper!(Svg),
|
||||
| BasicDataType::Svg => helper!(Svg),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -796,7 +792,9 @@ pub(crate) struct OutputsCache {
|
||||
|
||||
impl Clone for OutputsCache {
|
||||
fn clone(&self) -> Self {
|
||||
Self { internals: Arc::clone(&self.internals) }
|
||||
Self {
|
||||
internals: Arc::clone(&self.internals),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -952,8 +950,7 @@ impl DataTypeTrait<GlobalState> for BasicDataType {
|
||||
egui::Color32::from_rgb(200, 150, 120),
|
||||
| Self::PositiveGroupFunction =>
|
||||
egui::Color32::from_rgb(150, 120, 200),
|
||||
| Self::Svg =>
|
||||
egui::Color32::from_rgb(200, 200, 240),
|
||||
| Self::Svg => egui::Color32::from_rgb(200, 200, 240),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1172,9 +1169,8 @@ impl NodeTemplateTrait for NodeInstruction {
|
||||
| Self::PositiveBisimilarityPaigeTarjanNoLabels
|
||||
| Self::PositiveBisimilarityPaigeTarjan =>
|
||||
vec!["Positive Graph", "Positive Bisimilarity"],
|
||||
| Self::Sleep
|
||||
| Self::StringToSvg
|
||||
| Self::SaveSvg => vec!["General"],
|
||||
| Self::Sleep | Self::StringToSvg | Self::SaveSvg =>
|
||||
vec!["General"],
|
||||
}
|
||||
}
|
||||
|
||||
@ -1423,7 +1419,7 @@ impl WidgetValueTrait for BasicValue {
|
||||
},
|
||||
| BasicValue::Svg { value: _ } => {
|
||||
ui.label(param_name);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
responses
|
||||
@ -1467,13 +1463,12 @@ impl NodeDataTrait for NodeData {
|
||||
));
|
||||
}
|
||||
},
|
||||
| (_, NodeInstruction::SaveSvg) => {
|
||||
| (_, NodeInstruction::SaveSvg) =>
|
||||
if ui.button("Write").clicked() {
|
||||
responses.push(NodeResponse::User(
|
||||
CustomResponse::SaveToFile(node_id),
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
| (true, NodeInstruction::ReadPath) => {
|
||||
// since no filewatcher we simply give the option to reload the
|
||||
// file
|
||||
@ -1597,7 +1592,13 @@ impl AppHandle {
|
||||
.unwrap_or_default();
|
||||
|
||||
let user_state = Arc::new(RwLock::new(GlobalState::default()));
|
||||
Self { state, user_state, cache, translator, ..Default::default() }
|
||||
Self {
|
||||
state,
|
||||
user_state,
|
||||
cache,
|
||||
translator,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1607,10 +1608,10 @@ fn write_state(
|
||||
state: &str,
|
||||
translator: &str,
|
||||
cache: &str,
|
||||
path: &std::path::PathBuf
|
||||
path: &std::path::PathBuf,
|
||||
) -> std::io::Result<()> {
|
||||
use std::io::{Write, BufWriter};
|
||||
use std::fs::File;
|
||||
use std::io::{BufWriter, Write};
|
||||
|
||||
let f = File::create(path)?;
|
||||
let mut writer = BufWriter::new(f);
|
||||
@ -1630,10 +1631,14 @@ fn write_state(
|
||||
#[cfg(feature = "persistence")]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn read_state(
|
||||
path: &std::path::PathBuf
|
||||
) -> Result<(EditorState, rsprocess::translator::Translator, OutputsCache), String> {
|
||||
use std::io::Read;
|
||||
path: &std::path::PathBuf,
|
||||
) -> Result<
|
||||
(EditorState, rsprocess::translator::Translator, OutputsCache),
|
||||
String,
|
||||
> {
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
||||
use rsprocess::translator::Translator;
|
||||
|
||||
let mut f = File::open(path).map_err(|e| format!("{e}"))?;
|
||||
@ -1666,25 +1671,37 @@ fn read_state(
|
||||
let string_state = {
|
||||
let mut s = Vec::new();
|
||||
s.reserve_exact(len_state as usize);
|
||||
f.by_ref().take(len_state).read_to_end(&mut s).map_err(|e| format!("{e}"))?;
|
||||
f.by_ref()
|
||||
.take(len_state)
|
||||
.read_to_end(&mut s)
|
||||
.map_err(|e| format!("{e}"))?;
|
||||
String::from_utf8(s).map_err(|e| format!("{e}"))?
|
||||
};
|
||||
let string_translator = {
|
||||
let mut s = Vec::new();
|
||||
s.reserve_exact(len_translator as usize);
|
||||
f.by_ref().take(len_translator).read_to_end(&mut s).map_err(|e| format!("{e}"))?;
|
||||
f.by_ref()
|
||||
.take(len_translator)
|
||||
.read_to_end(&mut s)
|
||||
.map_err(|e| format!("{e}"))?;
|
||||
String::from_utf8(s).map_err(|e| format!("{e}"))?
|
||||
};
|
||||
let string_cache = {
|
||||
let mut s = Vec::new();
|
||||
s.reserve_exact(len_cache as usize);
|
||||
f.by_ref().take(len_cache).read_to_end(&mut s).map_err(|e| format!("{e}"))?;
|
||||
f.by_ref()
|
||||
.take(len_cache)
|
||||
.read_to_end(&mut s)
|
||||
.map_err(|e| format!("{e}"))?;
|
||||
String::from_utf8(s).map_err(|e| format!("{e}"))?
|
||||
};
|
||||
|
||||
let state = ron::from_str::<EditorState>(&string_state).map_err(|e| format!("{e}"))?;
|
||||
let translator = ron::from_str::<Translator>(&string_translator).map_err(|e| format!("{e}"))?;
|
||||
let cache = ron::from_str::<OutputsCache>(&string_cache).map_err(|e| format!("{e}"))?;
|
||||
let state = ron::from_str::<EditorState>(&string_state)
|
||||
.map_err(|e| format!("{e}"))?;
|
||||
let translator = ron::from_str::<Translator>(&string_translator)
|
||||
.map_err(|e| format!("{e}"))?;
|
||||
let cache = ron::from_str::<OutputsCache>(&string_cache)
|
||||
.map_err(|e| format!("{e}"))?;
|
||||
|
||||
Ok((state, translator, cache))
|
||||
}
|
||||
@ -1747,7 +1764,7 @@ impl eframe::App for AppHandle {
|
||||
.pick_file()
|
||||
{
|
||||
match read_state(&path) {
|
||||
Ok((state, translator, cache)) => {
|
||||
| Ok((state, translator, cache)) => {
|
||||
eframe::set_value(
|
||||
_frame
|
||||
.storage_mut()
|
||||
@ -1761,18 +1778,23 @@ impl eframe::App for AppHandle {
|
||||
_frame
|
||||
.storage_mut()
|
||||
.expect("no storage found"),
|
||||
TRANSLATOR_KEY, &translator,
|
||||
TRANSLATOR_KEY,
|
||||
&translator,
|
||||
);
|
||||
self.translator = Arc::new(Mutex::new(translator));
|
||||
self.translator =
|
||||
Arc::new(Mutex::new(translator));
|
||||
|
||||
eframe::set_value(
|
||||
_frame
|
||||
.storage_mut()
|
||||
.expect("no storage found"),
|
||||
CACHE_KEY, &cache);
|
||||
CACHE_KEY,
|
||||
&cache,
|
||||
);
|
||||
self.cache = cache;
|
||||
},
|
||||
Err(e) => println!("Error reading file: {e}"),
|
||||
| Err(e) =>
|
||||
println!("Error reading file: {e}"),
|
||||
}
|
||||
ui.close();
|
||||
}
|
||||
@ -1790,7 +1812,8 @@ impl eframe::App for AppHandle {
|
||||
},
|
||||
};
|
||||
let translator =
|
||||
match ron::ser::to_string(&self.translator) {
|
||||
match ron::ser::to_string(&self.translator)
|
||||
{
|
||||
| Ok(value) => value,
|
||||
| Err(e) => {
|
||||
println!("Error serializing: {e}");
|
||||
@ -1805,9 +1828,15 @@ impl eframe::App for AppHandle {
|
||||
panic!()
|
||||
},
|
||||
};
|
||||
match write_state(&state, &translator, &cache, &path) {
|
||||
Ok(_) => {},
|
||||
Err(e) => println!("Could not save file: {e}"),
|
||||
match write_state(
|
||||
&state,
|
||||
&translator,
|
||||
&cache,
|
||||
&path,
|
||||
) {
|
||||
| Ok(_) => {},
|
||||
| Err(e) =>
|
||||
println!("Could not save file: {e}"),
|
||||
}
|
||||
|
||||
ui.close();
|
||||
@ -1878,8 +1907,7 @@ impl eframe::App for AppHandle {
|
||||
self.cached_last_value = None;
|
||||
},
|
||||
| NodeResponse::User(CustomResponse::FieldModified(node)) => {
|
||||
self.cache
|
||||
.invalidate_outputs(&self.state.graph, *node);
|
||||
self.cache.invalidate_outputs(&self.state.graph, *node);
|
||||
self.cache.invalidate_last_state();
|
||||
self.cached_last_value = None;
|
||||
},
|
||||
@ -1912,7 +1940,8 @@ impl eframe::App for AppHandle {
|
||||
if let Some(l_v) = &self.cached_last_value {
|
||||
content = l_v.clone();
|
||||
} else {
|
||||
#[cfg(not(target_arch = "wasm32"))] {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
// wasm does not support threads :-(
|
||||
// ---------------------------------------------------------
|
||||
// did we already start a thread?
|
||||
@ -1929,41 +1958,60 @@ impl eframe::App for AppHandle {
|
||||
graph,
|
||||
&cache,
|
||||
arc_translator,
|
||||
&ctx
|
||||
&ctx,
|
||||
)
|
||||
})
|
||||
};
|
||||
self.app_logic_thread = Some(thread_join_handle);
|
||||
}
|
||||
|
||||
if self.app_logic_thread.as_ref()
|
||||
if self
|
||||
.app_logic_thread
|
||||
.as_ref()
|
||||
.map(|handle| handle.is_finished())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let handle = std::mem::take(&mut self.app_logic_thread);
|
||||
|
||||
let err = handle.unwrap().join()
|
||||
let err = handle
|
||||
.unwrap()
|
||||
.join()
|
||||
.expect("Could not join thread");
|
||||
|
||||
if let Err(e) = err {
|
||||
let text = get_layout(Err(e), &self.translator.lock().unwrap(), ctx);
|
||||
let text = get_layout(
|
||||
Err(e),
|
||||
&self.translator.lock().unwrap(),
|
||||
ctx,
|
||||
);
|
||||
self.cached_last_value = Some(text);
|
||||
} else if let Some(l_b_v) = self.cache.get_last_state() {
|
||||
if let BasicValue::SaveBytes { path, value } = &l_b_v {
|
||||
} else if let Some(l_b_v) = self.cache.get_last_state()
|
||||
{
|
||||
if let BasicValue::SaveBytes { path, value } =
|
||||
&l_b_v
|
||||
{
|
||||
use std::io::Write;
|
||||
let mut f = match std::fs::File::create(path) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
println!("Error creating file {path}: {e}");
|
||||
| Ok(f) => f,
|
||||
| Err(e) => {
|
||||
println!(
|
||||
"Error creating file {path}: {e}"
|
||||
);
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
if let Err(e) = f.write_all(value) {
|
||||
println!("Error writing to file {path}: {e}");
|
||||
println!(
|
||||
"Error writing to file {path}: {e}"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
content = get_layout(Ok(l_b_v), &self.translator.lock().unwrap(), ctx);
|
||||
content = get_layout(
|
||||
Ok(l_b_v),
|
||||
&self.translator.lock().unwrap(),
|
||||
ctx,
|
||||
);
|
||||
self.cached_last_value = Some(content.clone());
|
||||
}
|
||||
} else {
|
||||
@ -1971,33 +2019,42 @@ impl eframe::App for AppHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
let err = create_output(
|
||||
Arc::clone(&self.user_state),
|
||||
self.state.graph.clone(),
|
||||
&self.cache,
|
||||
Arc::clone(&self.translator),
|
||||
&ctx
|
||||
&ctx,
|
||||
);
|
||||
if let Err(e) = err {
|
||||
let text = get_layout(Err(e), &self.translator.lock().unwrap(), ctx);
|
||||
let text = get_layout(
|
||||
Err(e),
|
||||
&self.translator.lock().unwrap(),
|
||||
ctx,
|
||||
);
|
||||
self.cached_last_value = Some(text);
|
||||
} else if let Some(l_b_v) = self.cache.get_last_state() {
|
||||
if let BasicValue::SaveBytes { path, value } = &l_b_v {
|
||||
use std::io::Write;
|
||||
let mut f = match std::fs::File::create(path) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
| Ok(f) => f,
|
||||
| Err(e) => {
|
||||
println!("Error creating file {path}: {e}");
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
if let Err(e) = f.write_all(value) {
|
||||
println!("Error writing to file {path}: {e}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
content = get_layout(Ok(l_b_v), &self.translator.lock().unwrap(), ctx);
|
||||
content = get_layout(
|
||||
Ok(l_b_v),
|
||||
&self.translator.lock().unwrap(),
|
||||
ctx,
|
||||
);
|
||||
self.cached_last_value = Some(content.clone());
|
||||
}
|
||||
spin = false;
|
||||
@ -2035,7 +2092,7 @@ fn create_output(
|
||||
graph: Graph<NodeData, BasicDataType, BasicValue>,
|
||||
cache: &OutputsCache,
|
||||
translator: Arc<Mutex<rsprocess::translator::Translator>>,
|
||||
ctx: &egui::Context
|
||||
ctx: &egui::Context,
|
||||
) -> anyhow::Result<()> {
|
||||
let (save_node, active_node) = {
|
||||
let user_state = user_state.read().unwrap();
|
||||
@ -2092,17 +2149,16 @@ impl egui::Widget for WidgetLayout {
|
||||
match self {
|
||||
| Self::LayoutJob(lj) => {
|
||||
let mut response = None;
|
||||
egui::ScrollArea::vertical().auto_shrink([false, false]).show(ui, |ui| {
|
||||
response = Some(egui::Label::new(lj).ui(ui));
|
||||
});
|
||||
egui::ScrollArea::vertical()
|
||||
.auto_shrink([false, false])
|
||||
.show(ui, |ui| {
|
||||
response = Some(egui::Label::new(lj).ui(ui));
|
||||
});
|
||||
response.unwrap()
|
||||
},
|
||||
| Self::Empty => {
|
||||
egui::Label::new("").ui(ui)
|
||||
},
|
||||
| Self::Image(i) => {
|
||||
egui::Image::new(&i).max_size(ui.available_size()).ui(ui)
|
||||
}
|
||||
| Self::Empty => egui::Label::new("").ui(ui),
|
||||
| Self::Image(i) =>
|
||||
egui::Image::new(&i).max_size(ui.available_size()).ui(ui),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2118,7 +2174,8 @@ fn get_layout(
|
||||
| Ok(value) => match value {
|
||||
| BasicValue::SaveBytes { path, value: _ } => text.append(
|
||||
&format!("Saving to file \"{}\"", path),
|
||||
0., Default::default(),
|
||||
0.,
|
||||
Default::default(),
|
||||
),
|
||||
| BasicValue::Error { value } => {
|
||||
text = value;
|
||||
@ -2130,7 +2187,8 @@ fn get_layout(
|
||||
text.append(&value, 0., Default::default()),
|
||||
| BasicValue::System { value } => text.append(
|
||||
&format!("{}", Formatter::from(translator, &value)),
|
||||
0., Default::default(),
|
||||
0.,
|
||||
Default::default(),
|
||||
),
|
||||
| BasicValue::PositiveInt { value } =>
|
||||
text.append(&format!("{value}"), 0., Default::default()),
|
||||
|
||||
@ -55,7 +55,7 @@ pub fn evaluate_node(
|
||||
| None => {},
|
||||
| Some(val) => {
|
||||
outputs_cache.set_last_state(val);
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -109,21 +109,20 @@ fn generate_to_evaluate(
|
||||
let mut input_hashes = vec![];
|
||||
|
||||
match graph[n_id].user_data.template {
|
||||
NodeInstruction::SaveString | NodeInstruction::SaveSvg => {
|
||||
| NodeInstruction::SaveString | NodeInstruction::SaveSvg => {
|
||||
res.push(n_id);
|
||||
invalid_ids.insert(n_id);
|
||||
outputs_cache.invalidate_outputs(graph, n_id);
|
||||
continue;
|
||||
},
|
||||
_ => {}
|
||||
| _ => {},
|
||||
}
|
||||
|
||||
let first_output =
|
||||
if let Some(o) = graph[n_id].output_ids().next() {
|
||||
o
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let first_output = if let Some(o) = graph[n_id].output_ids().next() {
|
||||
o
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let hashes =
|
||||
if let Some(hashes) = outputs_cache.input_hashes(&first_output) {
|
||||
hashes
|
||||
@ -442,7 +441,10 @@ fn process_template(
|
||||
value: format!(
|
||||
"After {} steps arrived at state {}",
|
||||
limit.0,
|
||||
Formatter::from(&translator.lock().unwrap(), &limit.1)
|
||||
Formatter::from(
|
||||
&translator.lock().unwrap(),
|
||||
&limit.1
|
||||
)
|
||||
),
|
||||
};
|
||||
set_cache_output!((
|
||||
@ -694,12 +696,14 @@ fn process_template(
|
||||
BasicValue::AssertFunction { value: grouping },
|
||||
) => {
|
||||
use execution::data::MapEdges;
|
||||
let graph_1 = match graph_1.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_1 = match graph_1
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
};
|
||||
let graph_2 = match graph_2.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_2 = match graph_2
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
@ -762,12 +766,14 @@ fn process_template(
|
||||
BasicValue::AssertFunction { value: grouping },
|
||||
) => {
|
||||
use execution::data::MapEdges;
|
||||
let graph_1 = match graph_1.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_1 = match graph_1
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
};
|
||||
let graph_2 = match graph_2.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_2 = match graph_2
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
@ -797,12 +803,14 @@ fn process_template(
|
||||
BasicValue::AssertFunction { value: grouping },
|
||||
) => {
|
||||
use execution::data::MapEdges;
|
||||
let graph_1 = match graph_1.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_1 = match graph_1
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
};
|
||||
let graph_2 = match graph_2.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_2 = match graph_2
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
@ -851,7 +859,10 @@ fn process_template(
|
||||
BasicValue::Path { value: path },
|
||||
BasicValue::String { value },
|
||||
) => {
|
||||
*to_ret = Some(BasicValue::SaveBytes { path, value: value.into() });
|
||||
*to_ret = Some(BasicValue::SaveBytes {
|
||||
path,
|
||||
value: value.into(),
|
||||
});
|
||||
},
|
||||
| (BasicValue::Path { .. }, _) => {
|
||||
anyhow::bail!("Not a string");
|
||||
@ -899,13 +910,18 @@ fn process_template(
|
||||
BasicValue::ColorNode { value: color_node },
|
||||
BasicValue::ColorEdge { value: color_edge },
|
||||
) => {
|
||||
let current_translator: rsprocess::translator::Translator = translator.lock().unwrap().clone();
|
||||
let current_translator: rsprocess::translator::Translator =
|
||||
translator.lock().unwrap().clone();
|
||||
let arc_translator = Arc::new(current_translator);
|
||||
let modified_graph = input_graph.map(
|
||||
display_node
|
||||
.generate(Arc::clone(&arc_translator), &input_graph),
|
||||
display_edge
|
||||
.generate(Arc::clone(&arc_translator), &input_graph),
|
||||
display_node.generate(
|
||||
Arc::clone(&arc_translator),
|
||||
&input_graph,
|
||||
),
|
||||
display_edge.generate(
|
||||
Arc::clone(&arc_translator),
|
||||
&input_graph,
|
||||
),
|
||||
);
|
||||
|
||||
let input_graph = Arc::new(input_graph.to_owned());
|
||||
@ -1076,8 +1092,10 @@ fn process_template(
|
||||
let current_translator = translator.lock().unwrap().clone();
|
||||
let arc_translator = Arc::new(current_translator);
|
||||
let modified_graph = input_graph.map(
|
||||
display_node
|
||||
.generate(Arc::clone(&arc_translator), &input_graph),
|
||||
display_node.generate(
|
||||
Arc::clone(&arc_translator),
|
||||
&input_graph,
|
||||
),
|
||||
display_edge.generate(arc_translator, &input_graph),
|
||||
);
|
||||
|
||||
@ -1303,7 +1321,10 @@ fn process_template(
|
||||
value: format!(
|
||||
"After {} steps arrived at state {}",
|
||||
limit.0,
|
||||
Formatter::from(&translator.lock().unwrap(), &limit.1)
|
||||
Formatter::from(
|
||||
&translator.lock().unwrap(),
|
||||
&limit.1
|
||||
)
|
||||
),
|
||||
};
|
||||
set_cache_output!((
|
||||
@ -1788,7 +1809,10 @@ fn process_template(
|
||||
|
||||
if let BasicValue::Trace { value } = trace {
|
||||
let res = BasicValue::String {
|
||||
value: format!("{}", Formatter::from(&translator.lock().unwrap(), &value)),
|
||||
value: format!(
|
||||
"{}",
|
||||
Formatter::from(&translator.lock().unwrap(), &value)
|
||||
),
|
||||
};
|
||||
set_cache_output!((
|
||||
output_names.first().unwrap(),
|
||||
@ -1805,7 +1829,10 @@ fn process_template(
|
||||
|
||||
if let BasicValue::PositiveTrace { value } = trace {
|
||||
let res = BasicValue::String {
|
||||
value: format!("{}", Formatter::from(&translator.lock().unwrap(), &value)),
|
||||
value: format!(
|
||||
"{}",
|
||||
Formatter::from(&translator.lock().unwrap(), &value)
|
||||
),
|
||||
};
|
||||
set_cache_output!((
|
||||
output_names.first().unwrap(),
|
||||
@ -2124,7 +2151,11 @@ fn process_template(
|
||||
) => {
|
||||
use execution::data;
|
||||
let mut graph = g.clone();
|
||||
match data::grouping(&mut graph, &grouping, &mut translator.lock().unwrap()) {
|
||||
match data::grouping(
|
||||
&mut graph,
|
||||
&grouping,
|
||||
&mut translator.lock().unwrap(),
|
||||
) {
|
||||
| Ok(_) => {},
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
};
|
||||
@ -2223,7 +2254,9 @@ fn process_template(
|
||||
use execution::data;
|
||||
let mut graph = g.clone();
|
||||
match data::positive_grouping(
|
||||
&mut graph, &grouping, &mut translator.lock().unwrap(),
|
||||
&mut graph,
|
||||
&grouping,
|
||||
&mut translator.lock().unwrap(),
|
||||
) {
|
||||
| Ok(_) => {},
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
@ -2254,12 +2287,14 @@ fn process_template(
|
||||
BasicValue::PositiveAssertFunction { value: grouping },
|
||||
) => {
|
||||
use execution::data::PositiveMapEdges;
|
||||
let graph_1 = match graph_1.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_1 = match graph_1
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
};
|
||||
let graph_2 = match graph_2.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_2 = match graph_2
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
@ -2289,12 +2324,14 @@ fn process_template(
|
||||
BasicValue::PositiveAssertFunction { value: grouping },
|
||||
) => {
|
||||
use execution::data::PositiveMapEdges;
|
||||
let graph_1 = match graph_1.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_1 = match graph_1
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
};
|
||||
let graph_2 = match graph_2.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_2 = match graph_2
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
@ -2324,12 +2361,14 @@ fn process_template(
|
||||
BasicValue::PositiveAssertFunction { value: grouping },
|
||||
) => {
|
||||
use execution::data::PositiveMapEdges;
|
||||
let graph_1 = match graph_1.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_1 = match graph_1
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
};
|
||||
let graph_2 = match graph_2.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
let graph_2 = match graph_2
|
||||
.map_edges(&grouping, &mut translator.lock().unwrap())
|
||||
{
|
||||
| Ok(g) => g,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
@ -2476,12 +2515,16 @@ fn process_template(
|
||||
}
|
||||
},
|
||||
| NodeInstruction::Sleep => {
|
||||
#[cfg(not(target_arch = "wasm32"))] {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
let input_seconds = retrieve_from_cache![1];
|
||||
let hash_inputs = hash_inputs!(input_seconds);
|
||||
|
||||
if let BasicValue::PositiveInt { value: _value } = input_seconds {
|
||||
std::thread::sleep(std::time::Duration::from_secs(_value as u64));
|
||||
if let BasicValue::PositiveInt { value: _value } = input_seconds
|
||||
{
|
||||
std::thread::sleep(std::time::Duration::from_secs(
|
||||
_value as u64,
|
||||
));
|
||||
|
||||
set_cache_output!((
|
||||
output_names.first().unwrap(),
|
||||
@ -2492,7 +2535,8 @@ fn process_template(
|
||||
anyhow::bail!("Not an integer");
|
||||
}
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")] {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
anyhow::bail!("Cannot sleep on wams");
|
||||
}
|
||||
},
|
||||
@ -2502,8 +2546,8 @@ fn process_template(
|
||||
|
||||
if let BasicValue::String { value } = s {
|
||||
let res = match super::svg::Svg::parse_dot_string(&value) {
|
||||
Ok(svg) => svg,
|
||||
Err(e) => anyhow::bail!(e),
|
||||
| Ok(svg) => svg,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
};
|
||||
|
||||
let res = BasicValue::Svg { value: res };
|
||||
@ -2529,8 +2573,8 @@ fn process_template(
|
||||
path.push_str(".png");
|
||||
}
|
||||
let svg = match value.rasterize() {
|
||||
Ok(svg) => svg,
|
||||
Err(e) => anyhow::bail!(e),
|
||||
| Ok(svg) => svg,
|
||||
| Err(e) => anyhow::bail!(e),
|
||||
};
|
||||
*to_ret = Some(BasicValue::SaveBytes { path, value: svg });
|
||||
},
|
||||
@ -2544,7 +2588,7 @@ fn process_template(
|
||||
anyhow::bail!("Values of wrong type");
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use std::{fmt::Debug, hash::Hash, sync::{Arc, Mutex}};
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use layout::{backends::svg::SVGWriter, gv::{self, GraphBuilder}};
|
||||
use eframe::egui;
|
||||
use layout::backends::svg::SVGWriter;
|
||||
use layout::gv::{self, GraphBuilder};
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "persistence",
|
||||
@ -9,7 +12,7 @@ use eframe::egui;
|
||||
)]
|
||||
#[derive(Clone, Default)]
|
||||
pub(crate) struct Svg {
|
||||
image: egui::ColorImage,
|
||||
image: egui::ColorImage,
|
||||
/// original size of the svg
|
||||
svg_size: egui::Vec2,
|
||||
|
||||
@ -26,9 +29,9 @@ impl Svg {
|
||||
|
||||
let mut parser = gv::DotParser::new(dot_str);
|
||||
let g = match parser.process() {
|
||||
Ok(g) => g,
|
||||
Err(_) =>
|
||||
// errors are printed to sdtout so we ignore them
|
||||
| Ok(g) => g,
|
||||
| Err(_) =>
|
||||
// errors are printed to sdtout so we ignore them
|
||||
return Err("Could not parse dot string.".into()),
|
||||
};
|
||||
|
||||
@ -36,53 +39,58 @@ impl Svg {
|
||||
gb.visit_graph(&g);
|
||||
let mut graph = gb.get();
|
||||
let mut svg = SVGWriter::new();
|
||||
graph.do_it(
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
&mut svg,
|
||||
);
|
||||
graph.do_it(false, false, false, &mut svg);
|
||||
let content = svg.finalize();
|
||||
|
||||
let svg_tree = match resvg::usvg::Tree::from_str(
|
||||
&content,
|
||||
&resvg::usvg::Options {
|
||||
let svg_tree =
|
||||
match resvg::usvg::Tree::from_str(&content, &resvg::usvg::Options {
|
||||
dpi: 92.,
|
||||
font_family: "Andale Mono".into(),
|
||||
fontdb: Arc::new(fontdb),
|
||||
..Default::default()
|
||||
}
|
||||
) {
|
||||
Ok(svg) => svg,
|
||||
Err(err) => return Err(format!("{}", err)),
|
||||
};
|
||||
}) {
|
||||
| Ok(svg) => svg,
|
||||
| Err(err) => return Err(format!("{}", err)),
|
||||
};
|
||||
|
||||
let svg_size = egui::vec2(svg_tree.size().width(), svg_tree.size().height());
|
||||
let svg_size =
|
||||
egui::vec2(svg_tree.size().width(), svg_tree.size().height());
|
||||
|
||||
let mut pixmap = resvg::tiny_skia::Pixmap::new(svg_size.x as _, svg_size.y as _)
|
||||
.expect("Could not allocate svg");
|
||||
let mut pixmap =
|
||||
resvg::tiny_skia::Pixmap::new(svg_size.x as _, svg_size.y as _)
|
||||
.expect("Could not allocate svg");
|
||||
let pixmap_mut = &mut pixmap.as_mut();
|
||||
resvg::render(&svg_tree, Default::default(), pixmap_mut);
|
||||
let pixmap = pixmap_mut.to_owned();
|
||||
|
||||
let image = egui::ColorImage::from_rgba_unmultiplied([pixmap.width() as _, pixmap.height() as _], pixmap.data());
|
||||
let image = egui::ColorImage::from_rgba_unmultiplied(
|
||||
[pixmap.width() as _, pixmap.height() as _],
|
||||
pixmap.data(),
|
||||
);
|
||||
|
||||
let svg = Svg { image,
|
||||
original: content,
|
||||
svg_size,
|
||||
svg_texture: Arc::new(Mutex::new(None)) };
|
||||
let svg = Svg {
|
||||
image,
|
||||
original: content,
|
||||
svg_size,
|
||||
svg_texture: Arc::new(Mutex::new(None)),
|
||||
};
|
||||
|
||||
Ok(svg)
|
||||
}
|
||||
|
||||
pub(crate) fn get_texture(&self, ctx: &egui::Context) -> egui::TextureHandle {
|
||||
pub(crate) fn get_texture(
|
||||
&self,
|
||||
ctx: &egui::Context,
|
||||
) -> egui::TextureHandle {
|
||||
let tx = self.svg_texture.lock().expect("Poisoned");
|
||||
if tx.is_some() {
|
||||
(*tx).clone().unwrap()
|
||||
} else {
|
||||
std::mem::drop(tx);
|
||||
let svg_texture = ctx.load_texture("svg", self.image.clone(), Default::default());
|
||||
*self.svg_texture.lock().expect("Poisoned") = Some(svg_texture.clone());
|
||||
let svg_texture =
|
||||
ctx.load_texture("svg", self.image.clone(), Default::default());
|
||||
*self.svg_texture.lock().expect("Poisoned") =
|
||||
Some(svg_texture.clone());
|
||||
svg_texture
|
||||
}
|
||||
}
|
||||
@ -94,34 +102,39 @@ impl Svg {
|
||||
dpi: 92.,
|
||||
font_family: "Andale Mono".into(),
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
) {
|
||||
Ok(svg) => svg,
|
||||
Err(err) => return Err(format!("{}", err)),
|
||||
| Ok(svg) => svg,
|
||||
| Err(err) => return Err(format!("{}", err)),
|
||||
};
|
||||
let mut pixmap = resvg::tiny_skia::Pixmap::new(self.svg_size.x as _, self.svg_size.y as _)
|
||||
.expect("Could not allocate svg");
|
||||
let mut pixmap = resvg::tiny_skia::Pixmap::new(
|
||||
self.svg_size.x as _,
|
||||
self.svg_size.y as _,
|
||||
)
|
||||
.expect("Could not allocate svg");
|
||||
let pixmap_mut = &mut pixmap.as_mut();
|
||||
resvg::render(&svg_tree, Default::default(), pixmap_mut);
|
||||
let pixmap = pixmap_mut.to_owned();
|
||||
|
||||
match pixmap.encode_png() {
|
||||
Ok(png) => Ok(png),
|
||||
Err(e) => Err(format!("{}", e)),
|
||||
| Ok(png) => Ok(png),
|
||||
| Err(e) => Err(format!("{}", e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Svg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "[image: {:?}, svg_size: {:?}, svg_texture: {}",
|
||||
self.image,
|
||||
self.svg_size,
|
||||
if self.svg_texture.lock().expect("Poisoned").is_some() {
|
||||
"Some(...)"
|
||||
} else {
|
||||
"None"
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
"[image: {:?}, svg_size: {:?}, svg_texture: {}",
|
||||
self.image,
|
||||
self.svg_size,
|
||||
if self.svg_texture.lock().expect("Poisoned").is_some() {
|
||||
"Some(...)"
|
||||
} else {
|
||||
"None"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user