mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-31 02:07:21 +00:00
A few minor lints and docs (#1436)
* A few minor lints and docs * Added required packages to compile on Debian-style linux * Inlined some format args, and removed some `&` in args (they cause about 6% slowdown that compiler cannot inline) * a few spelling mistakes * fix fmt
This commit is contained in:
parent
67edac4aca
commit
3d4e3a74e5
51 changed files with 140 additions and 158 deletions
|
@ -878,7 +878,7 @@ impl Document {
|
||||||
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
|
||||||
}
|
}
|
||||||
Operation::SetLayerBlobUrl { layer_path, blob_url, resolution: _ } => {
|
Operation::SetLayerBlobUrl { layer_path, blob_url, resolution: _ } => {
|
||||||
let layer = self.layer_mut(&layer_path).unwrap_or_else(|_| panic!("Blob URL for invalid layer with path '{:?}'", layer_path));
|
let layer = self.layer_mut(&layer_path).unwrap_or_else(|_| panic!("Blob URL for invalid layer with path '{layer_path:?}'"));
|
||||||
|
|
||||||
let LayerDataType::Layer(layer) = &mut layer.data else {
|
let LayerDataType::Layer(layer) = &mut layer.data else {
|
||||||
panic!("Incorrectly trying to set the image blob URL for a layer that is not a 'Layer' layer type");
|
panic!("Incorrectly trying to set the image blob URL for a layer that is not a 'Layer' layer type");
|
||||||
|
|
|
@ -302,7 +302,7 @@ impl LayerNodeIdentifier {
|
||||||
pub fn new(node_id: NodeId, network: &NodeNetwork) -> Self {
|
pub fn new(node_id: NodeId, network: &NodeNetwork) -> Self {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
is_layer_node(node_id, network),
|
is_layer_node(node_id, network),
|
||||||
"Layer identifer constructed from non layer node {node_id}: {:#?}",
|
"Layer identifier constructed from non layer node {node_id}: {:#?}",
|
||||||
network.nodes.get(&node_id)
|
network.nodes.get(&node_id)
|
||||||
);
|
);
|
||||||
Self::new_unchecked(node_id)
|
Self::new_unchecked(node_id)
|
||||||
|
|
|
@ -1044,7 +1044,7 @@ mod tests {
|
||||||
// TODO: 3 real root case
|
// TODO: 3 real root case
|
||||||
// for root in roots {
|
// for root in roots {
|
||||||
// if let Some(num) = root {
|
// if let Some(num) = root {
|
||||||
// print!("{:.32}", num);
|
// print!("{num:.32}");
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,6 @@ fn main() {
|
||||||
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_HASH={}", git_command(&["rev-parse", "HEAD"]));
|
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_HASH={}", git_command(&["rev-parse", "HEAD"]));
|
||||||
let branch = std::env::var("GITHUB_HEAD_REF").unwrap_or_default();
|
let branch = std::env::var("GITHUB_HEAD_REF").unwrap_or_default();
|
||||||
let branch = if branch.is_empty() { git_command(&["name-rev", "--name-only", "HEAD"]) } else { branch };
|
let branch = if branch.is_empty() { git_command(&["name-rev", "--name-only", "HEAD"]) } else { branch };
|
||||||
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_BRANCH={}", branch);
|
println!("cargo:rustc-env=GRAPHITE_GIT_COMMIT_BRANCH={branch}");
|
||||||
println!("cargo:rustc-env=GRAPHITE_RELEASE_SERIES={}", GRAPHITE_RELEASE_SERIES);
|
println!("cargo:rustc-env=GRAPHITE_RELEASE_SERIES={GRAPHITE_RELEASE_SERIES}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,11 +86,11 @@ r#"
|
||||||
block_on(crate::node_graph_executor::run_node_graph());
|
block_on(crate::node_graph_executor::run_node_graph());
|
||||||
let mut res = VecDeque::new();
|
let mut res = VecDeque::new();
|
||||||
editor.poll_node_graph_evaluation(&mut res);
|
editor.poll_node_graph_evaluation(&mut res);
|
||||||
//println!("node_graph_poll: {:#?}", res);
|
//println!("node_graph_poll: {res:#?}");
|
||||||
|
|
||||||
//println!("in: {:#?}", message);
|
//println!("in: {message:#?}");
|
||||||
let res = editor.handle_message(message);
|
let res = editor.handle_message(message);
|
||||||
//println!("out: {:#?}", res);
|
//println!("out: {res:#?}");
|
||||||
responses.push(res);
|
responses.push(res);
|
||||||
}
|
}
|
||||||
let responses = responses.pop().unwrap();
|
let responses = responses.pop().unwrap();
|
||||||
|
@ -100,6 +100,6 @@ r#"
|
||||||
} else {
|
} else {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
println!("responses: {:#?}", responses);
|
println!("responses: {responses:#?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,7 +175,7 @@ impl Dispatcher {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
warn!("Called ToolMessage without an active document.\nGot {:?}", message);
|
warn!("Called ToolMessage without an active document.\nGot {message:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Workspace(message) => {
|
Workspace(message) => {
|
||||||
|
@ -518,7 +518,7 @@ mod test {
|
||||||
paths.iter().map(|layer| layer.to_vec()).collect::<Vec<_>>()
|
paths.iter().map(|layer| layer.to_vec()).collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
let sorted_layers = map_to_vec(editor.dispatcher.message_handlers.portfolio_message_handler.active_document().unwrap().all_layers_sorted());
|
let sorted_layers = map_to_vec(editor.dispatcher.message_handlers.portfolio_message_handler.active_document().unwrap().all_layers_sorted());
|
||||||
println!("Sorted layers: {:?}", sorted_layers);
|
println!("Sorted layers: {sorted_layers:?}");
|
||||||
|
|
||||||
let verify_order = |handler: &mut DocumentMessageHandler| {
|
let verify_order = |handler: &mut DocumentMessageHandler| {
|
||||||
(
|
(
|
||||||
|
@ -562,7 +562,7 @@ mod test {
|
||||||
println!();
|
println!();
|
||||||
println!("DisplayDialogError details:");
|
println!("DisplayDialogError details:");
|
||||||
println!();
|
println!();
|
||||||
println!("Description: {}", value);
|
println!("Description: {value}");
|
||||||
println!("-------------------------------------------------");
|
println!("-------------------------------------------------");
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
|
|
|
@ -214,7 +214,7 @@ pub enum Key {
|
||||||
impl fmt::Display for Key {
|
impl fmt::Display for Key {
|
||||||
// TODO: Relevant key labels should be localized when we get around to implementing localization/internationalization
|
// TODO: Relevant key labels should be localized when we get around to implementing localization/internationalization
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
|
||||||
let key_name = format!("{:?}", self);
|
let key_name = format!("{self:?}");
|
||||||
|
|
||||||
// Writing system keys
|
// Writing system keys
|
||||||
const DIGIT_PREFIX: &str = "Digit";
|
const DIGIT_PREFIX: &str = "Digit";
|
||||||
|
@ -293,14 +293,14 @@ impl fmt::Display for Key {
|
||||||
_ => key_name.as_str(),
|
_ => key_name.as_str(),
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(f, "{}", name)
|
write!(f, "{name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Key> for LayoutKey {
|
impl From<Key> for LayoutKey {
|
||||||
fn from(key: Key) -> Self {
|
fn from(key: Key) -> Self {
|
||||||
Self {
|
Self {
|
||||||
key: format!("{:?}", key),
|
key: format!("{key:?}"),
|
||||||
label: key.to_string(),
|
label: key.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ impl fmt::Display for KeysGroup {
|
||||||
joined.truncate(joined.len() - JOINER_MARK.len());
|
joined.truncate(joined.len() - JOINER_MARK.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, "{}", joined)
|
write!(f, "{joined}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ impl ActionKeys {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Keys(keys) => {
|
Self::Keys(keys) => {
|
||||||
warn!("Calling `.to_keys()` on a `ActionKeys::Keys` is a mistake/bug. Keys are: {:?}.", keys);
|
warn!("Calling `.to_keys()` on a `ActionKeys::Keys` is a mistake/bug. Keys are: {keys:?}.");
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,20 +71,14 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
|
||||||
let layout = if let Some(layout) = self.layouts.get_mut(layout_target as usize) {
|
let layout = if let Some(layout) = self.layouts.get_mut(layout_target as usize) {
|
||||||
layout
|
layout
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
warn!("UpdateLayout was called referencing an invalid layout. `widget_id: {widget_id}`, `layout_target: {layout_target:?}`",);
|
||||||
"UpdateLayout was called referencing an invalid layout. `widget_id: {}`, `layout_target: {:?}`",
|
|
||||||
widget_id, layout_target
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let widget_holder = if let Some(widget_holder) = layout.iter_mut().find(|widget| widget.widget_id == widget_id) {
|
let widget_holder = if let Some(widget_holder) = layout.iter_mut().find(|widget| widget.widget_id == widget_id) {
|
||||||
widget_holder
|
widget_holder
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
warn!("UpdateLayout was called referencing an invalid widget ID, although the layout target was valid. `widget_id: {widget_id}`, `layout_target: {layout_target:?}`",);
|
||||||
"UpdateLayout was called referencing an invalid widget ID, although the layout target was valid. `widget_id: {}`, `layout_target: {:?}`",
|
|
||||||
widget_id, layout_target
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ impl From<&str> for PivotPosition {
|
||||||
"BottomLeft" => PivotPosition::BottomLeft,
|
"BottomLeft" => PivotPosition::BottomLeft,
|
||||||
"BottomCenter" => PivotPosition::BottomCenter,
|
"BottomCenter" => PivotPosition::BottomCenter,
|
||||||
"BottomRight" => PivotPosition::BottomRight,
|
"BottomRight" => PivotPosition::BottomRight,
|
||||||
_ => panic!("Failed parsing unrecognized PivotPosition enum value '{}'", input),
|
_ => panic!("Failed parsing unrecognized PivotPosition enum value '{input}'"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
responses.add(BroadcastEvent::DocumentIsDirty);
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => error!("DocumentError: {:?}", e),
|
Err(e) => error!("DocumentError: {e:?}"),
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
// Messages
|
// Messages
|
||||||
AbortTransaction => {
|
AbortTransaction => {
|
||||||
if !self.undo_in_progress {
|
if !self.undo_in_progress {
|
||||||
self.undo(responses).unwrap_or_else(|e| warn!("{}", e));
|
self.undo(responses).unwrap_or_else(|e| warn!("{e}"));
|
||||||
responses.extend([RenderDocument.into(), DocumentStructureChanged.into()]);
|
responses.extend([RenderDocument.into(), DocumentStructureChanged.into()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,8 +320,8 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
responses.add_front(DocumentMessage::DirtyRenderDocument);
|
responses.add_front(DocumentMessage::DirtyRenderDocument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DocumentHistoryBackward => self.undo(responses).unwrap_or_else(|e| warn!("{}", e)),
|
DocumentHistoryBackward => self.undo(responses).unwrap_or_else(|e| warn!("{e}")),
|
||||||
DocumentHistoryForward => self.redo(responses).unwrap_or_else(|e| warn!("{}", e)),
|
DocumentHistoryForward => self.redo(responses).unwrap_or_else(|e| warn!("{e}")),
|
||||||
DocumentStructureChanged => {
|
DocumentStructureChanged => {
|
||||||
let data_buffer: RawBuffer = self.serialize_root().as_slice().into();
|
let data_buffer: RawBuffer = self.serialize_root().as_slice().into();
|
||||||
responses.add(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer })
|
responses.add(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer })
|
||||||
|
@ -652,7 +652,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
RollbackTransaction => {
|
RollbackTransaction => {
|
||||||
self.rollback(responses).unwrap_or_else(|e| warn!("{}", e));
|
self.rollback(responses).unwrap_or_else(|e| warn!("{e}"));
|
||||||
responses.extend([RenderDocument.into(), DocumentStructureChanged.into()]);
|
responses.extend([RenderDocument.into(), DocumentStructureChanged.into()]);
|
||||||
}
|
}
|
||||||
SaveDocument => {
|
SaveDocument => {
|
||||||
|
@ -754,7 +754,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
warn!("Setting blob URL for invalid layer type, which must be a `Layer` layer type. Found: `{:?}`", other);
|
warn!("Setting blob URL for invalid layer type, which must be a `Layer` layer type. Found: `{other:?}`");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -982,7 +982,7 @@ impl DocumentMessageHandler {
|
||||||
};
|
};
|
||||||
let outside_artboards_color = outside.map_or_else(|| if false { "ffffff" } else { "222222" }.to_string(), |col| col.rgba_hex());
|
let outside_artboards_color = outside.map_or_else(|| if false { "ffffff" } else { "222222" }.to_string(), |col| col.rgba_hex());
|
||||||
let outside_artboards = match transparent_background {
|
let outside_artboards = match transparent_background {
|
||||||
false => format!(r##"<rect x="0" y="0" width="100%" height="100%" fill="#{}" />"##, outside_artboards_color),
|
false => format!(r##"<rect x="0" y="0" width="100%" height="100%" fill="#{outside_artboards_color}" />"##),
|
||||||
true => "".into(),
|
true => "".into(),
|
||||||
};
|
};
|
||||||
let matrix = transform
|
let matrix = transform
|
||||||
|
@ -1055,7 +1055,7 @@ impl DocumentMessageHandler {
|
||||||
let data = self.layer_panel_entry(path.to_vec(), &render_data).ok()?;
|
let data = self.layer_panel_entry(path.to_vec(), &render_data).ok()?;
|
||||||
(!path.is_empty()).then(|| FrontendMessage::UpdateDocumentLayerDetails { data }.into())
|
(!path.is_empty()).then(|| FrontendMessage::UpdateDocumentLayerDetails { data }.into())
|
||||||
} else {
|
} else {
|
||||||
warn!("Tried to select non existing layer {:?}", path);
|
warn!("Tried to select non existing layer {path:?}");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1185,7 +1185,7 @@ impl DocumentMessageHandler {
|
||||||
// TODO: `indices_for_path` can return an error. We currently skip these layers and log a warning. Once this problem is solved this code can be simplified.
|
// TODO: `indices_for_path` can return an error. We currently skip these layers and log a warning. Once this problem is solved this code can be simplified.
|
||||||
match self.document_legacy.indices_for_path(path) {
|
match self.document_legacy.indices_for_path(path) {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("layers_sorted: Could not get indices for the layer {:?}: {:?}", path, err);
|
warn!("layers_sorted: Could not get indices for the layer {path:?}: {err:?}");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Ok(indices) => Some((path, indices)),
|
Ok(indices) => Some((path, indices)),
|
||||||
|
@ -1214,7 +1214,7 @@ impl DocumentMessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layer_metadata(&self, path: &[LayerId]) -> &LayerMetadata {
|
pub fn layer_metadata(&self, path: &[LayerId]) -> &LayerMetadata {
|
||||||
self.layer_metadata.get(path).unwrap_or_else(|| panic!("Editor's layer metadata for {:?} does not exist", path))
|
self.layer_metadata.get(path).unwrap_or_else(|| panic!("Editor's layer metadata for {path:?} does not exist"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layer_metadata_mut(&mut self, path: &[LayerId]) -> &mut LayerMetadata {
|
pub fn layer_metadata_mut(&mut self, path: &[LayerId]) -> &mut LayerMetadata {
|
||||||
|
@ -1224,7 +1224,7 @@ impl DocumentMessageHandler {
|
||||||
pub fn layer_metadata_mut_no_borrow_self<'a>(layer_metadata: &'a mut HashMap<Vec<LayerId>, LayerMetadata>, path: &[LayerId]) -> &'a mut LayerMetadata {
|
pub fn layer_metadata_mut_no_borrow_self<'a>(layer_metadata: &'a mut HashMap<Vec<LayerId>, LayerMetadata>, path: &[LayerId]) -> &'a mut LayerMetadata {
|
||||||
layer_metadata
|
layer_metadata
|
||||||
.get_mut(path)
|
.get_mut(path)
|
||||||
.unwrap_or_else(|| panic!("Layer data cannot be found because the path {:?} does not exist", path))
|
.unwrap_or_else(|| panic!("Layer data cannot be found because the path {path:?} does not exist"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Places a document into the history system
|
/// Places a document into the history system
|
||||||
|
@ -1379,7 +1379,7 @@ impl DocumentMessageHandler {
|
||||||
let data: LayerMetadata = *self
|
let data: LayerMetadata = *self
|
||||||
.layer_metadata
|
.layer_metadata
|
||||||
.get_mut(&path)
|
.get_mut(&path)
|
||||||
.ok_or_else(|| EditorError::Document(format!("Could not get layer metadata for {:?}", path)))?;
|
.ok_or_else(|| EditorError::Document(format!("Could not get layer metadata for {path:?}")))?;
|
||||||
let layer = self.document_legacy.layer(&path)?;
|
let layer = self.document_legacy.layer(&path)?;
|
||||||
let entry = LayerPanelEntry::new(&data, self.document_legacy.multiply_transforms(&path)?, layer, path, render_data);
|
let entry = LayerPanelEntry::new(&data, self.document_legacy.multiply_transforms(&path)?, layer, path, render_data);
|
||||||
Ok(entry)
|
Ok(entry)
|
||||||
|
|
|
@ -165,15 +165,7 @@ fn derive_transform() {
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
new_transform.abs_diff_eq(original_transform, 1e-10),
|
new_transform.abs_diff_eq(original_transform, 1e-10),
|
||||||
"original_transform {} new_transform {} / scale {} new_scale {} / angle {} new_angle {} / shear {} / new_shear {}",
|
"original_transform {original_transform} new_transform {new_transform} / scale {scale} new_scale {new_scale} / angle {angle} new_angle {new_angle} / shear {shear} / new_shear {new_shear}",
|
||||||
original_transform,
|
|
||||||
new_transform,
|
|
||||||
scale,
|
|
||||||
new_scale,
|
|
||||||
angle,
|
|
||||||
new_angle,
|
|
||||||
shear,
|
|
||||||
new_shear,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ impl MessageHandler<OverlaysMessage, (bool, &PersistentData, &InputPreprocessorM
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
DispatchOperation(operation) => match self.overlays_document.handle_operation(*operation) {
|
DispatchOperation(operation) => match self.overlays_document.handle_operation(*operation) {
|
||||||
Ok(_) => responses.add(OverlaysMessage::Rerender),
|
Ok(_) => responses.add(OverlaysMessage::Rerender),
|
||||||
Err(e) => error!("OverlaysError: {:?}", e),
|
Err(e) => error!("OverlaysError: {e:?}"),
|
||||||
},
|
},
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
|
|
|
@ -32,7 +32,7 @@ macro_rules! derive_from {
|
||||||
($type:ty, $kind:ident) => {
|
($type:ty, $kind:ident) => {
|
||||||
impl From<$type> for EditorError {
|
impl From<$type> for EditorError {
|
||||||
fn from(error: $type) -> Self {
|
fn from(error: $type) -> Self {
|
||||||
EditorError::$kind(format!("{:?}", error))
|
EditorError::$kind(format!("{error:?}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -382,7 +382,7 @@ impl<'a> Selected<'a> {
|
||||||
let original_layer_transforms = match self.original_transforms {
|
let original_layer_transforms = match self.original_transforms {
|
||||||
OriginalTransforms::Layer(layer_map) => *layer_map.get(&layer).unwrap(),
|
OriginalTransforms::Layer(layer_map) => *layer_map.get(&layer).unwrap(),
|
||||||
OriginalTransforms::Path(_path_map) => {
|
OriginalTransforms::Path(_path_map) => {
|
||||||
warn!("Found Path variant in original_transforms, returning identity transform for layer {:?}", layer);
|
warn!("Found Path variant in original_transforms, returning identity transform for layer {layer:?}");
|
||||||
DAffine2::IDENTITY
|
DAffine2::IDENTITY
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -161,7 +161,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
||||||
(Ok(layer), layer_metadata) => {
|
(Ok(layer), layer_metadata) => {
|
||||||
buffer.push(CopyBufferEntry { layer, layer_metadata });
|
buffer.push(CopyBufferEntry { layer, layer_metadata });
|
||||||
}
|
}
|
||||||
(Err(e), _) => warn!("Could not access selected layer {:?}: {:?}", layer_path, e),
|
(Err(e), _) => warn!("Could not access selected layer {layer_path:?}: {e:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -348,7 +348,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
||||||
self.load_document(document, document_id, responses);
|
self.load_document(document, document_id, responses);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Failed to open document: {}", e);
|
println!("Failed to open document: {e}");
|
||||||
if !document_is_auto_saved {
|
if !document_is_auto_saved {
|
||||||
responses.add(DialogMessage::DisplayDialogError {
|
responses.add(DialogMessage::DisplayDialogError {
|
||||||
title: "Failed to open document".to_string(),
|
title: "Failed to open document".to_string(),
|
||||||
|
@ -385,7 +385,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
||||||
} => {
|
} => {
|
||||||
let paste = |entry: &CopyBufferEntry, responses: &mut VecDeque<_>| {
|
let paste = |entry: &CopyBufferEntry, responses: &mut VecDeque<_>| {
|
||||||
if let Some(document) = self.active_document() {
|
if let Some(document) = self.active_document() {
|
||||||
trace!("Pasting into folder {:?} as index: {}", &path, insert_index);
|
trace!("Pasting into folder {path:?} as index: {insert_index}");
|
||||||
let destination_path = [path.to_vec(), vec![generate_uuid()]].concat();
|
let destination_path = [path.to_vec(), vec![generate_uuid()]].concat();
|
||||||
|
|
||||||
responses.add_front(DocumentMessage::UpdateLayerMetadata {
|
responses.add_front(DocumentMessage::UpdateLayerMetadata {
|
||||||
|
@ -623,7 +623,7 @@ impl PortfolioMessageHandler {
|
||||||
|
|
||||||
match new_doc_title_num {
|
match new_doc_title_num {
|
||||||
1 => DEFAULT_DOCUMENT_NAME.to_string(),
|
1 => DEFAULT_DOCUMENT_NAME.to_string(),
|
||||||
_ => format!("{} {}", DEFAULT_DOCUMENT_NAME, new_doc_title_num),
|
_ => format!("{DEFAULT_DOCUMENT_NAME} {new_doc_title_num}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,7 +713,7 @@ impl PortfolioMessageHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.executor.poll_node_graph_evaluation(&mut active_document.document_legacy, responses).unwrap_or_else(|e| {
|
self.executor.poll_node_graph_evaluation(&mut active_document.document_legacy, responses).unwrap_or_else(|e| {
|
||||||
log::error!("Error while evaluating node graph: {}", e);
|
log::error!("Error while evaluating node graph: {e}");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,16 +60,16 @@ impl OverlayRenderer {
|
||||||
self.layer_overlay_visibility(document, layer, true, responses);
|
self.layer_overlay_visibility(document, layer, true, responses);
|
||||||
|
|
||||||
let outline_cache = self.shape_overlay_cache.get(&layer);
|
let outline_cache = self.shape_overlay_cache.get(&layer);
|
||||||
trace!("Overlay: Outline cache {:?}", &outline_cache);
|
trace!("Overlay: Outline cache {outline_cache:?}");
|
||||||
|
|
||||||
// Create an outline if we do not have a cached one
|
// Create an outline if we do not have a cached one
|
||||||
if outline_cache.is_none() {
|
if outline_cache.is_none() {
|
||||||
let outline_path = self.create_shape_outline_overlay(graphene_core::vector::Subpath::from_bezier_rs(subpaths), responses);
|
let outline_path = self.create_shape_outline_overlay(graphene_core::vector::Subpath::from_bezier_rs(subpaths), responses);
|
||||||
self.shape_overlay_cache.insert(layer, outline_path.clone());
|
self.shape_overlay_cache.insert(layer, outline_path.clone());
|
||||||
Self::place_outline_overlays(outline_path.clone(), &transform, responses);
|
Self::place_outline_overlays(outline_path.clone(), &transform, responses);
|
||||||
trace!("Overlay: Creating new outline {:?}", &outline_path);
|
trace!("Overlay: Creating new outline {outline_path:?}");
|
||||||
} else if let Some(outline_path) = outline_cache {
|
} else if let Some(outline_path) = outline_cache {
|
||||||
trace!("Overlay: Updating overlays for {:?} owning layer: {:?}", outline_path, layer);
|
trace!("Overlay: Updating overlays for {outline_path:?} owning layer: {layer:?}");
|
||||||
Self::modify_outline_overlays(outline_path.clone(), graphene_core::vector::Subpath::from_bezier_rs(subpaths), responses);
|
Self::modify_outline_overlays(outline_path.clone(), graphene_core::vector::Subpath::from_bezier_rs(subpaths), responses);
|
||||||
Self::place_outline_overlays(outline_path.clone(), &transform, responses);
|
Self::place_outline_overlays(outline_path.clone(), &transform, responses);
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ impl OverlayRenderer {
|
||||||
/// Removes the manipulator overlays from the overlay document.
|
/// Removes the manipulator overlays from the overlay document.
|
||||||
fn remove_manipulator_group_overlays(overlay_paths: &ManipulatorGroupOverlays, responses: &mut VecDeque<Message>) {
|
fn remove_manipulator_group_overlays(overlay_paths: &ManipulatorGroupOverlays, responses: &mut VecDeque<Message>) {
|
||||||
overlay_paths.iter().flatten().for_each(|layer_id| {
|
overlay_paths.iter().flatten().for_each(|layer_id| {
|
||||||
trace!("Overlay: Sending delete message for: {:?}", layer_id);
|
trace!("Overlay: Sending delete message for: {layer_id:?}");
|
||||||
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: layer_id.clone() }.into()));
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: layer_id.clone() }.into()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ impl ShapeState {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((layer, manipulator_point_id)) = self.find_nearest_point_indices(document, mouse_position, select_threshold) {
|
if let Some((layer, manipulator_point_id)) = self.find_nearest_point_indices(document, mouse_position, select_threshold) {
|
||||||
trace!("Selecting... manipulator point: {:?}", manipulator_point_id);
|
trace!("Selecting... manipulator point: {manipulator_point_id:?}");
|
||||||
|
|
||||||
let subpaths = get_subpaths(layer, document)?;
|
let subpaths = get_subpaths(layer, document)?;
|
||||||
let manipulator_group = get_manipulator_groups(subpaths).find(|group| group.id == manipulator_point_id.group)?;
|
let manipulator_group = get_manipulator_groups(subpaths).find(|group| group.id == manipulator_point_id.group)?;
|
||||||
|
@ -631,7 +631,7 @@ impl ShapeState {
|
||||||
if let Some((manipulator_point_id, distance_squared)) = Self::closest_point_in_layer(document, layer, mouse_position) {
|
if let Some((manipulator_point_id, distance_squared)) = Self::closest_point_in_layer(document, layer, mouse_position) {
|
||||||
// Choose the first point under the threshold
|
// Choose the first point under the threshold
|
||||||
if distance_squared < select_threshold_squared {
|
if distance_squared < select_threshold_squared {
|
||||||
trace!("Selecting... manipulator point: {:?}", manipulator_point_id);
|
trace!("Selecting... manipulator point: {manipulator_point_id:?}");
|
||||||
return Some((layer, manipulator_point_id));
|
return Some((layer, manipulator_point_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,7 +317,7 @@ impl SelectToolData {
|
||||||
// let layer = match document.document_legacy.layer(layer_path) {
|
// let layer = match document.document_legacy.layer(layer_path) {
|
||||||
// Ok(layer) => layer.clone(),
|
// Ok(layer) => layer.clone(),
|
||||||
// Err(e) => {
|
// Err(e) => {
|
||||||
// warn!("Could not access selected layer {:?}: {:?}", layer_path, e);
|
// warn!("Could not access selected layer {layer_path:?}: {e:?}");
|
||||||
// continue;
|
// continue;
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
|
@ -438,10 +438,7 @@ pub fn tool_message_to_tool_type(tool_message: &ToolMessage) -> ToolType {
|
||||||
// ToolMessage::Relight(_) => ToolType::Relight,
|
// ToolMessage::Relight(_) => ToolType::Relight,
|
||||||
ToolMessage::Imaginate(_) => ToolType::Imaginate,
|
ToolMessage::Imaginate(_) => ToolType::Imaginate,
|
||||||
ToolMessage::Frame(_) => ToolType::Frame,
|
ToolMessage::Frame(_) => ToolType::Frame,
|
||||||
_ => panic!(
|
_ => panic!("Conversion from ToolMessage to ToolType impossible because the given ToolMessage does not have a matching ToolType. Got: {tool_message:?}"),
|
||||||
"Conversion from ToolMessage to ToolType impossible because the given ToolMessage does not have a matching ToolType. Got: {:?}",
|
|
||||||
tool_message
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,10 +472,7 @@ pub fn tool_type_to_activate_tool_message(tool_type: ToolType) -> ToolMessageDis
|
||||||
// ToolType::Relight => ToolMessageDiscriminant::ActivateToolRelight,
|
// ToolType::Relight => ToolMessageDiscriminant::ActivateToolRelight,
|
||||||
ToolType::Imaginate => ToolMessageDiscriminant::ActivateToolImaginate,
|
ToolType::Imaginate => ToolMessageDiscriminant::ActivateToolImaginate,
|
||||||
ToolType::Frame => ToolMessageDiscriminant::ActivateToolFrame,
|
ToolType::Frame => ToolMessageDiscriminant::ActivateToolFrame,
|
||||||
_ => panic!(
|
_ => panic!("Conversion from ToolType to ToolMessage impossible because the given ToolType does not have a matching ToolMessage. Got: {tool_type:?}"),
|
||||||
"Conversion from ToolType to ToolMessage impossible because the given ToolType does not have a matching ToolMessage. Got: {:?}",
|
|
||||||
tool_type
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,7 +204,7 @@ impl NodeRuntime {
|
||||||
|
|
||||||
assert_ne!(proto_network.nodes.len(), 0, "No protonodes exist?");
|
assert_ne!(proto_network.nodes.len(), 0, "No protonodes exist?");
|
||||||
if let Err(e) = self.executor.update(proto_network).await {
|
if let Err(e) = self.executor.update(proto_network).await {
|
||||||
error!("Failed to update executor:\n{}", e);
|
error!("Failed to update executor:\n{e}");
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ impl NodeRuntime {
|
||||||
let result = match self.executor.input_type() {
|
let result = match self.executor.input_type() {
|
||||||
Some(t) if t == concrete!(WasmEditorApi) => (&self.executor).execute(editor_api).await.map_err(|e| e.to_string()),
|
Some(t) if t == concrete!(WasmEditorApi) => (&self.executor).execute(editor_api).await.map_err(|e| e.to_string()),
|
||||||
Some(t) if t == concrete!(()) => (&self.executor).execute(()).await.map_err(|e| e.to_string()),
|
Some(t) if t == concrete!(()) => (&self.executor).execute(()).await.map_err(|e| e.to_string()),
|
||||||
Some(t) => Err(format!("Invalid input type {:?}", t)),
|
Some(t) => Err(format!("Invalid input type {t:?}")),
|
||||||
_ => Err("No input type".to_string()),
|
_ => Err("No input type".to_string()),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ impl NodeGraphExecutor {
|
||||||
self.thumbnails = new_thumbnails;
|
self.thumbnails = new_thumbnails;
|
||||||
document.metadata.update_transforms(new_transforms, new_upstream_transforms);
|
document.metadata.update_transforms(new_transforms, new_upstream_transforms);
|
||||||
document.metadata.update_click_targets(new_click_targets);
|
document.metadata.update_click_targets(new_click_targets);
|
||||||
let node_graph_output = result.map_err(|e| format!("Node graph evaluation failed: {:?}", e))?;
|
let node_graph_output = result.map_err(|e| format!("Node graph evaluation failed: {e:?}"))?;
|
||||||
let execution_context = self.futures.remove(&generation_id).ok_or_else(|| "Invalid generation ID".to_string())?;
|
let execution_context = self.futures.remove(&generation_id).ok_or_else(|| "Invalid generation ID".to_string())?;
|
||||||
responses.extend(updates);
|
responses.extend(updates);
|
||||||
self.process_node_graph_output(node_graph_output, execution_context.layer_path.clone(), responses, execution_context.document_id)?;
|
self.process_node_graph_output(node_graph_output, execution_context.layer_path.clone(), responses, execution_context.document_id)?;
|
||||||
|
@ -610,7 +610,7 @@ impl NodeGraphExecutor {
|
||||||
responses.add(DocumentMessage::RenderScrollbars);
|
responses.add(DocumentMessage::RenderScrollbars);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(format!("Invalid node graph output type: {:#?}", node_graph_output));
|
return Err(format!("Invalid node graph output type: {node_graph_output:#?}"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -85,7 +85,7 @@ fn set_random_seed(seed: f64) {
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn handle_message(message: String) -> String {
|
fn handle_message(message: String) -> String {
|
||||||
let Ok(message) = ron::from_str::<graphite_editor::messages::message::Message>(&message) else {
|
let Ok(message) = ron::from_str::<graphite_editor::messages::message::Message>(&message) else {
|
||||||
panic!("Error parsing message: {}", message)
|
panic!("Error parsing message: {message}")
|
||||||
};
|
};
|
||||||
let responses = EDITOR.with(|editor| {
|
let responses = EDITOR.with(|editor| {
|
||||||
let mut editor = editor.borrow_mut();
|
let mut editor = editor.borrow_mut();
|
||||||
|
@ -103,7 +103,7 @@ fn handle_message(message: String) -> String {
|
||||||
let path = image.path.clone();
|
let path = image.path.clone();
|
||||||
let mime = image.mime.clone();
|
let mime = image.mime.clone();
|
||||||
let transform = image.transform;
|
let transform = image.transform;
|
||||||
images.insert(format!("{:?}_{}", &image.path, document_id), image);
|
images.insert(format!("{:?}_{}", image.path, document_id), image);
|
||||||
stub_data.push(FrontendImageData {
|
stub_data.push(FrontendImageData {
|
||||||
path,
|
path,
|
||||||
node_id: None,
|
node_id: None,
|
||||||
|
@ -121,7 +121,7 @@ fn handle_message(message: String) -> String {
|
||||||
for response in &responses {
|
for response in &responses {
|
||||||
let serialized = ron::to_string(&send_frontend_message_to_js(response.clone())).unwrap();
|
let serialized = ron::to_string(&send_frontend_message_to_js(response.clone())).unwrap();
|
||||||
if let Err(error) = ron::from_str::<FrontendMessage>(&serialized) {
|
if let Err(error) = ron::from_str::<FrontendMessage>(&serialized) {
|
||||||
log::error!("Error deserializing message: {}", error);
|
log::error!("Error deserializing message: {error}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,7 @@ impl JsEditorHandle {
|
||||||
}
|
}
|
||||||
#[cfg(feature = "tauri")]
|
#[cfg(feature = "tauri")]
|
||||||
{
|
{
|
||||||
let identifier = format!("http://localhost:3001/image/{:?}_{}", &image.path, document_id);
|
let identifier = format!("http://localhost:3001/image/{:?}_{}", image.path, document_id);
|
||||||
fetchImage(image.path.clone(), image.node_id, image.mime, document_id, identifier);
|
fetchImage(image.path.clone(), image.node_id, image.mime, document_id, identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ impl JsEditorHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log::error!("tauri response: {:?}\n{:?}", error, _message);
|
log::error!("tauri response: {error:?}\n{_message:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ impl JsEditorHandle {
|
||||||
self.dispatch(message);
|
self.dispatch(message);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
(target, val) => Err(Error::new(&format!("Could not update UI\nDetails:\nTarget: {:?}\nValue: {:?}", target, val)).into()),
|
(target, val) => Err(Error::new(&format!("Could not update UI\nDetails:\nTarget: {target:?}\nValue: {val:?}")).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +434,7 @@ impl JsEditorHandle {
|
||||||
let key = translate_key(&name);
|
let key = translate_key(&name);
|
||||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||||
|
|
||||||
trace!("Key down {:?}, name: {}, modifiers: {:?}, key repeat: {}", key, name, modifiers, key_repeat);
|
trace!("Key down {key:?}, name: {name}, modifiers: {modifiers:?}, key repeat: {key_repeat}");
|
||||||
|
|
||||||
let message = InputPreprocessorMessage::KeyDown { key, key_repeat, modifier_keys };
|
let message = InputPreprocessorMessage::KeyDown { key, key_repeat, modifier_keys };
|
||||||
self.dispatch(message);
|
self.dispatch(message);
|
||||||
|
@ -446,7 +446,7 @@ impl JsEditorHandle {
|
||||||
let key = translate_key(&name);
|
let key = translate_key(&name);
|
||||||
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
let modifier_keys = ModifierKeys::from_bits(modifiers).expect("Invalid modifier keys");
|
||||||
|
|
||||||
trace!("Key up {:?}, name: {}, modifiers: {:?}, key repeat: {}", key, name, modifier_keys, key_repeat);
|
trace!("Key up {key:?}, name: {name}, modifiers: {modifier_keys:?}, key repeat: {key_repeat}");
|
||||||
|
|
||||||
let message = InputPreprocessorMessage::KeyUp { key, key_repeat, modifier_keys };
|
let message = InputPreprocessorMessage::KeyUp { key, key_repeat, modifier_keys };
|
||||||
self.dispatch(message);
|
self.dispatch(message);
|
||||||
|
|
|
@ -8,7 +8,7 @@ use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
/// When a panic occurs, notify the user and log the error to the JS console before the backend dies
|
/// When a panic occurs, notify the user and log the error to the JS console before the backend dies
|
||||||
pub fn panic_hook(info: &panic::PanicInfo) {
|
pub fn panic_hook(info: &panic::PanicInfo) {
|
||||||
error!("{}", info);
|
error!("{info}");
|
||||||
|
|
||||||
JS_EDITOR_HANDLES.with(|instances| {
|
JS_EDITOR_HANDLES.with(|instances| {
|
||||||
instances
|
instances
|
||||||
|
@ -68,7 +68,7 @@ impl log::Log for WasmLog {
|
||||||
pub fn translate_key(name: &str) -> Key {
|
pub fn translate_key(name: &str) -> Key {
|
||||||
use Key::*;
|
use Key::*;
|
||||||
|
|
||||||
trace!("Key event received: {}", name);
|
trace!("Key event received: {name}");
|
||||||
|
|
||||||
match name {
|
match name {
|
||||||
// Writing system keys
|
// Writing system keys
|
||||||
|
|
|
@ -32,7 +32,7 @@ fn main() {
|
||||||
.json(&compile_request)
|
.json(&compile_request)
|
||||||
.send()
|
.send()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("response: {:?}", response);
|
println!("response: {response:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_network() -> NodeNetwork {
|
fn add_network() -> NodeNetwork {
|
||||||
|
|
|
@ -41,7 +41,7 @@ async fn post_compile_spirv(State(state): State<Arc<AppState>>, Json(compile_req
|
||||||
|
|
||||||
let path = std::env::var("CARGO_MANIFEST_DIR").unwrap() + "/../gpu-compiler/Cargo.toml";
|
let path = std::env::var("CARGO_MANIFEST_DIR").unwrap() + "/../gpu-compiler/Cargo.toml";
|
||||||
let result = compile_request.compile(state.compile_dir.path().to_str().expect("non utf8 tempdir path"), &path).map_err(|e| {
|
let result = compile_request.compile(state.compile_dir.path().to_str().expect("non utf8 tempdir path"), &path).map_err(|e| {
|
||||||
eprintln!("compilation failed: {}", e);
|
eprintln!("compilation failed: {e}");
|
||||||
StatusCode::INTERNAL_SERVER_ERROR
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
})?;
|
})?;
|
||||||
state.cache.write().unwrap().insert(compile_request, Ok(result.clone()));
|
state.cache.write().unwrap().insert(compile_request, Ok(result.clone()));
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::uuid::{generate_uuid, ManipulatorGroupId};
|
||||||
use crate::{vector::VectorData, Artboard, Color, GraphicElementData, GraphicGroup};
|
use crate::{vector::VectorData, Artboard, Color, GraphicElementData, GraphicGroup};
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
use image::ImageEncoder;
|
|
||||||
pub use quad::Quad;
|
pub use quad::Quad;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
@ -156,7 +156,7 @@ pub fn format_transform_matrix(transform: DAffine2) -> String {
|
||||||
let mut result = "matrix(".to_string();
|
let mut result = "matrix(".to_string();
|
||||||
let cols = transform.to_cols_array();
|
let cols = transform.to_cols_array();
|
||||||
for (index, item) in cols.iter().enumerate() {
|
for (index, item) in cols.iter().enumerate() {
|
||||||
write!(result, "{}", item).unwrap();
|
write!(result, "{item}").unwrap();
|
||||||
if index != cols.len() - 1 {
|
if index != cols.len() - 1 {
|
||||||
result.push_str(", ");
|
result.push_str(", ");
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub struct LogToConsoleNode;
|
||||||
#[node_macro::node_fn(LogToConsoleNode)]
|
#[node_macro::node_fn(LogToConsoleNode)]
|
||||||
fn log_to_console<T: core::fmt::Debug>(value: T) -> T {
|
fn log_to_console<T: core::fmt::Debug>(value: T) -> T {
|
||||||
#[cfg(not(target_arch = "spirv"))]
|
#[cfg(not(target_arch = "spirv"))]
|
||||||
debug!("{:#?}", value);
|
debug!("{value:#?}");
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,13 +190,13 @@ impl Type {
|
||||||
impl core::fmt::Debug for Type {
|
impl core::fmt::Debug for Type {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Generic(arg0) => write!(f, "Generic({})", arg0),
|
Self::Generic(arg0) => write!(f, "Generic({arg0})"),
|
||||||
#[cfg(feature = "type_id_logging")]
|
#[cfg(feature = "type_id_logging")]
|
||||||
Self::Concrete(arg0) => write!(f, "Concrete({}, {:?})", arg0.name, arg0.id),
|
Self::Concrete(arg0) => write!(f, "Concrete({}, {:?})", arg0.name, arg0.id),
|
||||||
#[cfg(not(feature = "type_id_logging"))]
|
#[cfg(not(feature = "type_id_logging"))]
|
||||||
Self::Concrete(arg0) => write!(f, "Concrete({})", arg0.name),
|
Self::Concrete(arg0) => write!(f, "Concrete({})", arg0.name),
|
||||||
Self::Fn(arg0, arg1) => write!(f, "({:?} -> {:?})", arg0, arg1),
|
Self::Fn(arg0, arg1) => write!(f, "({arg0:?} -> {arg1:?})"),
|
||||||
Self::Future(arg0) => write!(f, "Future({:?})", arg0),
|
Self::Future(arg0) => write!(f, "Future({arg0:?})"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,10 +204,10 @@ impl core::fmt::Debug for Type {
|
||||||
impl std::fmt::Display for Type {
|
impl std::fmt::Display for Type {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Type::Generic(name) => write!(f, "{}", name),
|
Type::Generic(name) => write!(f, "{name}"),
|
||||||
Type::Concrete(ty) => write!(f, "{}", ty.name),
|
Type::Concrete(ty) => write!(f, "{}", ty.name),
|
||||||
Type::Fn(input, output) => write!(f, "({} -> {})", input, output),
|
Type::Fn(input, output) => write!(f, "({input} -> {output})"),
|
||||||
Type::Future(ty) => write!(f, "Future<{}>", ty),
|
Type::Future(ty) => write!(f, "Future<{ty}>"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ const OPACITY_PRECISION: usize = 3;
|
||||||
|
|
||||||
fn format_opacity(name: &str, opacity: f32) -> String {
|
fn format_opacity(name: &str, opacity: f32) -> String {
|
||||||
if (opacity - 1.).abs() > 10_f32.powi(-(OPACITY_PRECISION as i32)) {
|
if (opacity - 1.).abs() > 10_f32.powi(-(OPACITY_PRECISION as i32)) {
|
||||||
format!(r#" {}-opacity="{:.precision$}""#, name, opacity, precision = OPACITY_PRECISION)
|
format!(r#" {name}-opacity="{opacity:.OPACITY_PRECISION$}""#)
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ impl Fill {
|
||||||
Self::Solid(color) => format!(r##" fill="#{}"{}"##, color.rgb_hex(), format_opacity("fill", color.a())),
|
Self::Solid(color) => format!(r##" fill="#{}"{}"##, color.rgb_hex(), format_opacity("fill", color.a())),
|
||||||
Self::Gradient(gradient) => {
|
Self::Gradient(gradient) => {
|
||||||
let gradient_id = gradient.render_defs(svg_defs, multiplied_transform, bounds, transformed_bounds);
|
let gradient_id = gradient.render_defs(svg_defs, multiplied_transform, bounds, transformed_bounds);
|
||||||
format!(r##" fill="url('#{}')""##, gradient_id)
|
format!(r##" fill="url('#{gradient_id}')""##)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,7 +533,7 @@ impl PathStyle {
|
||||||
(_, None) => String::new(),
|
(_, None) => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
format!("{}{}", fill_attribute, stroke_attribute)
|
format!("{fill_attribute}{stroke_attribute}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,7 @@ impl Subpath {
|
||||||
(true, true, true) => 'C',
|
(true, true, true) => 'C',
|
||||||
(false, false, true) => 'L',
|
(false, false, true) => 'L',
|
||||||
(_, false, false) => 'Z',
|
(_, false, false) => 'Z',
|
||||||
_ => panic!("Invalid shape {:#?}", self),
|
_ => panic!("Invalid shape {self:#?}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Complete the last curve
|
// Complete the last curve
|
||||||
|
@ -567,7 +567,7 @@ impl From<&Subpath> for BezPath {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[None, None, None] => (PathEl::ClosePath, true),
|
[None, None, None] => (PathEl::ClosePath, true),
|
||||||
_ => panic!("Invalid path element {:#?}", subpath),
|
_ => panic!("Invalid path element {subpath:#?}"),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub fn create_files(metadata: &Metadata, networks: &[ProtoNetwork], compile_dir:
|
||||||
}
|
}
|
||||||
let lib = src.join("lib.rs");
|
let lib = src.join("lib.rs");
|
||||||
let shader = serialize_gpu(networks, io)?;
|
let shader = serialize_gpu(networks, io)?;
|
||||||
eprintln!("{}", shader);
|
eprintln!("{shader}");
|
||||||
std::fs::write(lib, shader)?;
|
std::fs::write(lib, shader)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -531,7 +531,7 @@ where
|
||||||
#[node_macro::node_fn(RenderTextureNode)]
|
#[node_macro::node_fn(RenderTextureNode)]
|
||||||
async fn render_texture_node<'a: 'input, E: 'a + GpuExecutor>(image: ShaderInputFrame<E>, surface: Arc<SurfaceHandle<E::Surface>>, executor: &'a E) -> SurfaceFrame {
|
async fn render_texture_node<'a: 'input, E: 'a + GpuExecutor>(image: ShaderInputFrame<E>, surface: Arc<SurfaceHandle<E::Surface>>, executor: &'a E) -> SurfaceFrame {
|
||||||
let surface_id = surface.surface_id;
|
let surface_id = surface.surface_id;
|
||||||
log::trace!("rendering to surface {:?}", surface_id);
|
log::trace!("rendering to surface {surface_id:?}");
|
||||||
|
|
||||||
executor.create_render_pass(image.shader_input, surface).unwrap();
|
executor.create_render_pass(image.shader_input, surface).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,9 @@ impl DocumentNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_proto_node(mut self) -> ProtoNode {
|
fn resolve_proto_node(mut self) -> ProtoNode {
|
||||||
assert!(!self.inputs.is_empty() || self.manual_composition.is_some(), "Resolving document node {:#?} with no inputs", self);
|
assert!(!self.inputs.is_empty() || self.manual_composition.is_some(), "Resolving document node {self:#?} with no inputs");
|
||||||
let DocumentNodeImplementation::Unresolved(fqn) = self.implementation else {
|
let DocumentNodeImplementation::Unresolved(fqn) = self.implementation else {
|
||||||
unreachable!("tried to resolve not flattened node on resolved node {:?}", self);
|
unreachable!("tried to resolve not flattened node on resolved node {self:?}");
|
||||||
};
|
};
|
||||||
let (input, mut args) = if let Some(ty) = self.manual_composition {
|
let (input, mut args) = if let Some(ty) = self.manual_composition {
|
||||||
(ProtoNodeInput::ShortCircut(ty), ConstructionArgs::Nodes(vec![]))
|
(ProtoNodeInput::ShortCircut(ty), ConstructionArgs::Nodes(vec![]))
|
||||||
|
@ -68,7 +68,7 @@ impl DocumentNode {
|
||||||
let first = self.inputs.remove(0);
|
let first = self.inputs.remove(0);
|
||||||
match first {
|
match first {
|
||||||
NodeInput::Value { tagged_value, .. } => {
|
NodeInput::Value { tagged_value, .. } => {
|
||||||
assert_eq!(self.inputs.len(), 0, "{}, {:?}", &self.name, &self.inputs);
|
assert_eq!(self.inputs.len(), 0, "{}, {:?}", self.name, self.inputs);
|
||||||
(ProtoNodeInput::None, ConstructionArgs::Value(tagged_value))
|
(ProtoNodeInput::None, ConstructionArgs::Value(tagged_value))
|
||||||
}
|
}
|
||||||
NodeInput::Node { node_id, output_index, lambda } => {
|
NodeInput::Node { node_id, output_index, lambda } => {
|
||||||
|
@ -82,9 +82,9 @@ impl DocumentNode {
|
||||||
assert!(!self.inputs.iter().any(|input| matches!(input, NodeInput::Network(_))), "recieved non resolved parameter");
|
assert!(!self.inputs.iter().any(|input| matches!(input, NodeInput::Network(_))), "recieved non resolved parameter");
|
||||||
assert!(
|
assert!(
|
||||||
!self.inputs.iter().any(|input| matches!(input, NodeInput::Value { .. })),
|
!self.inputs.iter().any(|input| matches!(input, NodeInput::Value { .. })),
|
||||||
"recieved value as parameter. inupts: {:#?}, construction_args: {:#?}",
|
"received value as parameter. inputs: {:#?}, construction_args: {:#?}",
|
||||||
&self.inputs,
|
self.inputs,
|
||||||
&args
|
args
|
||||||
);
|
);
|
||||||
|
|
||||||
// If we have one parameter of the type inline, set it as the construction args
|
// If we have one parameter of the type inline, set it as the construction args
|
||||||
|
@ -689,7 +689,7 @@ impl NodeNetwork {
|
||||||
pub fn flatten_with_fns(&mut self, node: NodeId, map_ids: impl Fn(NodeId, NodeId) -> NodeId + Copy, gen_id: impl Fn() -> NodeId + Copy) {
|
pub fn flatten_with_fns(&mut self, node: NodeId, map_ids: impl Fn(NodeId, NodeId) -> NodeId + Copy, gen_id: impl Fn() -> NodeId + Copy) {
|
||||||
self.resolve_extract_nodes();
|
self.resolve_extract_nodes();
|
||||||
let Some((id, mut node)) = self.nodes.remove_entry(&node) else {
|
let Some((id, mut node)) = self.nodes.remove_entry(&node) else {
|
||||||
warn!("The node which was supposed to be flattened does not exist in the network, id {} network {:#?}", node, self);
|
warn!("The node which was supposed to be flattened does not exist in the network, id {node} network {self:#?}");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -804,7 +804,7 @@ impl NodeNetwork {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_id_node(&mut self, id: NodeId) -> Result<(), String> {
|
fn remove_id_node(&mut self, id: NodeId) -> Result<(), String> {
|
||||||
let node = self.nodes.get(&id).ok_or_else(|| format!("Node with id {} does not exist", id))?.clone();
|
let node = self.nodes.get(&id).ok_or_else(|| format!("Node with id {id} does not exist"))?.clone();
|
||||||
if let DocumentNodeImplementation::Unresolved(ident) = &node.implementation {
|
if let DocumentNodeImplementation::Unresolved(ident) = &node.implementation {
|
||||||
if ident.name == "graphene_core::ops::IdNode" {
|
if ident.name == "graphene_core::ops::IdNode" {
|
||||||
assert_eq!(node.inputs.len(), 1, "Id node has more than one input");
|
assert_eq!(node.inputs.len(), 1, "Id node has more than one input");
|
||||||
|
@ -855,7 +855,7 @@ impl NodeNetwork {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
for id in id_nodes {
|
for id in id_nodes {
|
||||||
if let Err(e) = self.remove_id_node(id) {
|
if let Err(e) = self.remove_id_node(id) {
|
||||||
log::warn!("{}", e)
|
log::warn!("{e}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1070,8 +1070,8 @@ mod test {
|
||||||
network.generate_node_paths(&[]);
|
network.generate_node_paths(&[]);
|
||||||
network.flatten_with_fns(1, |self_id, inner_id| self_id * 10 + inner_id, gen_node_id);
|
network.flatten_with_fns(1, |self_id, inner_id| self_id * 10 + inner_id, gen_node_id);
|
||||||
let flat_network = flat_network();
|
let flat_network = flat_network();
|
||||||
println!("{:#?}", flat_network);
|
println!("{flat_network:#?}");
|
||||||
println!("{:#?}", network);
|
println!("{network:#?}");
|
||||||
|
|
||||||
assert_eq!(flat_network, network);
|
assert_eq!(flat_network, network);
|
||||||
}
|
}
|
||||||
|
@ -1131,7 +1131,7 @@ mod test {
|
||||||
let resolved_network = network.into_proto_networks().collect::<Vec<_>>();
|
let resolved_network = network.into_proto_networks().collect::<Vec<_>>();
|
||||||
|
|
||||||
println!("{:#?}", resolved_network[0]);
|
println!("{:#?}", resolved_network[0]);
|
||||||
println!("{:#?}", construction_network);
|
println!("{construction_network:#?}");
|
||||||
assert_eq!(resolved_network[0], construction_network);
|
assert_eq!(resolved_network[0], construction_network);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1248,7 +1248,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn simple_duplicate() {
|
fn simple_duplicate() {
|
||||||
let result = output_duplicate(vec![NodeOutput::new(1, 0)], NodeInput::node(1, 0));
|
let result = output_duplicate(vec![NodeOutput::new(1, 0)], NodeInput::node(1, 0));
|
||||||
println!("{:#?}", result);
|
println!("{result:#?}");
|
||||||
assert_eq!(result.outputs.len(), 1, "The number of outputs should remain as 1");
|
assert_eq!(result.outputs.len(), 1, "The number of outputs should remain as 1");
|
||||||
assert_eq!(result.outputs[0], NodeOutput::new(11, 0), "The outer network output should be from a duplicated inner network");
|
assert_eq!(result.outputs[0], NodeOutput::new(11, 0), "The outer network output should be from a duplicated inner network");
|
||||||
let mut ids = result.nodes.keys().copied().collect::<Vec<_>>();
|
let mut ids = result.nodes.keys().copied().collect::<Vec<_>>();
|
||||||
|
|
|
@ -202,7 +202,7 @@ impl<'a> TaggedValue {
|
||||||
pub fn to_primitive_string(&self) -> String {
|
pub fn to_primitive_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
TaggedValue::None => "()".to_string(),
|
TaggedValue::None => "()".to_string(),
|
||||||
TaggedValue::String(x) => format!("\"{}\"", x),
|
TaggedValue::String(x) => format!("\"{x}\""),
|
||||||
TaggedValue::U32(x) => x.to_string() + "_u32",
|
TaggedValue::U32(x) => x.to_string() + "_u32",
|
||||||
TaggedValue::F32(x) => x.to_string() + "_f32",
|
TaggedValue::F32(x) => x.to_string() + "_f32",
|
||||||
TaggedValue::F64(x) => x.to_string() + "_f64",
|
TaggedValue::F64(x) => x.to_string() + "_f64",
|
||||||
|
|
|
@ -104,8 +104,8 @@ impl core::fmt::Display for ProtoNetwork {
|
||||||
f.write_str("Primary input: ")?;
|
f.write_str("Primary input: ")?;
|
||||||
match &node.input {
|
match &node.input {
|
||||||
ProtoNodeInput::None => f.write_str("None")?,
|
ProtoNodeInput::None => f.write_str("None")?,
|
||||||
ProtoNodeInput::Network(ty) => f.write_fmt(format_args!("Network (type = {:?})", ty))?,
|
ProtoNodeInput::Network(ty) => f.write_fmt(format_args!("Network (type = {ty:?})"))?,
|
||||||
ProtoNodeInput::ShortCircut(ty) => f.write_fmt(format_args!("Lambda (type = {:?})", ty))?,
|
ProtoNodeInput::ShortCircut(ty) => f.write_fmt(format_args!("Lambda (type = {ty:?})"))?,
|
||||||
ProtoNodeInput::Node(_, _) => f.write_str("Node")?,
|
ProtoNodeInput::Node(_, _) => f.write_str("Node")?,
|
||||||
}
|
}
|
||||||
f.write_str("\n")?;
|
f.write_str("\n")?;
|
||||||
|
@ -220,7 +220,7 @@ impl ProtoNodeInput {
|
||||||
pub fn unwrap_node(self) -> NodeId {
|
pub fn unwrap_node(self) -> NodeId {
|
||||||
match self {
|
match self {
|
||||||
ProtoNodeInput::Node(id, _) => id,
|
ProtoNodeInput::Node(id, _) => id,
|
||||||
_ => panic!("tried to unwrap id from non node input \n node: {:#?}", self),
|
_ => panic!("tried to unwrap id from non node input \n node: {self:#?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ impl ProtoNode {
|
||||||
pub fn unwrap_construction_nodes(&self) -> Vec<(NodeId, bool)> {
|
pub fn unwrap_construction_nodes(&self) -> Vec<(NodeId, bool)> {
|
||||||
match &self.construction_args {
|
match &self.construction_args {
|
||||||
ConstructionArgs::Nodes(nodes) => nodes.clone(),
|
ConstructionArgs::Nodes(nodes) => nodes.clone(),
|
||||||
_ => panic!("tried to unwrap nodes from non node construction args \n node: {:#?}", self),
|
_ => panic!("tried to unwrap nodes from non node construction args \n node: {self:#?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,10 +282,7 @@ impl ProtoNetwork {
|
||||||
fn check_ref(&self, ref_id: &NodeId, id: &NodeId) {
|
fn check_ref(&self, ref_id: &NodeId, id: &NodeId) {
|
||||||
assert!(
|
assert!(
|
||||||
self.nodes.iter().any(|(check_id, _)| check_id == ref_id),
|
self.nodes.iter().any(|(check_id, _)| check_id == ref_id),
|
||||||
"Node id:{} has a reference which uses node id:{} which doesn't exist in network {:#?}",
|
"Node id:{id} has a reference which uses node id:{ref_id} which doesn't exist in network {self:#?}"
|
||||||
id,
|
|
||||||
ref_id,
|
|
||||||
self
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +400,7 @@ impl ProtoNetwork {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
if temp_marks.contains(&node_id) {
|
if temp_marks.contains(&node_id) {
|
||||||
return Err(format!("Cycle detected {:#?}, {:#?}", &inwards_edges, &network));
|
return Err(format!("Cycle detected {inwards_edges:#?}, {network:#?}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(dependencies) = inwards_edges.get(&node_id) {
|
if let Some(dependencies) = inwards_edges.get(&node_id) {
|
||||||
|
@ -586,7 +583,7 @@ impl TypingContext {
|
||||||
.ok_or(format!("No implementations found for {:?}. Other implementations found {:?}", node.identifier, self.lookup))?;
|
.ok_or(format!("No implementations found for {:?}. Other implementations found {:?}", node.identifier, self.lookup))?;
|
||||||
|
|
||||||
if matches!(input, Type::Generic(_)) {
|
if matches!(input, Type::Generic(_)) {
|
||||||
return Err(format!("Generic types are not supported as inputs yet {:?} occurred in {:?}", &input, node.identifier));
|
return Err(format!("Generic types are not supported as inputs yet {:?} occurred in {:?}", input, node.identifier));
|
||||||
}
|
}
|
||||||
if parameters.iter().any(|p| {
|
if parameters.iter().any(|p| {
|
||||||
matches!(p,
|
matches!(p,
|
||||||
|
@ -695,7 +692,7 @@ mod test {
|
||||||
fn topological_sort() {
|
fn topological_sort() {
|
||||||
let construction_network = test_network();
|
let construction_network = test_network();
|
||||||
let sorted = construction_network.topological_sort().expect("Error when calling 'topological_sort' on 'construction_network.");
|
let sorted = construction_network.topological_sort().expect("Error when calling 'topological_sort' on 'construction_network.");
|
||||||
println!("{:#?}", sorted);
|
println!("{sorted:#?}");
|
||||||
assert_eq!(sorted, vec![14, 10, 11, 1]);
|
assert_eq!(sorted, vec![14, 10, 11, 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,7 +712,7 @@ mod test {
|
||||||
println!("nodes: {:#?}", construction_network.nodes);
|
println!("nodes: {:#?}", construction_network.nodes);
|
||||||
assert_eq!(sorted, vec![0, 1, 2, 3]);
|
assert_eq!(sorted, vec![0, 1, 2, 3]);
|
||||||
let ids: Vec<_> = construction_network.nodes.iter().map(|(id, _)| *id).collect();
|
let ids: Vec<_> = construction_network.nodes.iter().map(|(id, _)| *id).collect();
|
||||||
println!("{:#?}", ids);
|
println!("{ids:#?}");
|
||||||
println!("nodes: {:#?}", construction_network.nodes);
|
println!("nodes: {:#?}", construction_network.nodes);
|
||||||
assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value");
|
assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value");
|
||||||
assert_eq!(ids, vec![0, 1, 2, 3]);
|
assert_eq!(ids, vec![0, 1, 2, 3]);
|
||||||
|
@ -729,7 +726,7 @@ mod test {
|
||||||
let sorted = construction_network.topological_sort().expect("Error when calling 'topological_sort' on 'construction_network.");
|
let sorted = construction_network.topological_sort().expect("Error when calling 'topological_sort' on 'construction_network.");
|
||||||
assert_eq!(sorted, vec![0, 1, 2, 3]);
|
assert_eq!(sorted, vec![0, 1, 2, 3]);
|
||||||
let ids: Vec<_> = construction_network.nodes.iter().map(|(id, _)| *id).collect();
|
let ids: Vec<_> = construction_network.nodes.iter().map(|(id, _)| *id).collect();
|
||||||
println!("{:#?}", ids);
|
println!("{ids:#?}");
|
||||||
assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value");
|
assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value");
|
||||||
assert_eq!(ids, vec![0, 1, 2, 3]);
|
assert_eq!(ids, vec![0, 1, 2, 3]);
|
||||||
}
|
}
|
||||||
|
@ -738,7 +735,7 @@ mod test {
|
||||||
fn input_resolution() {
|
fn input_resolution() {
|
||||||
let mut construction_network = test_network();
|
let mut construction_network = test_network();
|
||||||
construction_network.resolve_inputs().expect("Error when calling 'resolve_inputs' on 'construction_network.");
|
construction_network.resolve_inputs().expect("Error when calling 'resolve_inputs' on 'construction_network.");
|
||||||
println!("{:#?}", construction_network);
|
println!("{construction_network:#?}");
|
||||||
assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value");
|
assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value");
|
||||||
assert_eq!(construction_network.nodes.len(), 6);
|
assert_eq!(construction_network.nodes.len(), 6);
|
||||||
assert_eq!(construction_network.nodes[5].1.construction_args, ConstructionArgs::Nodes(vec![(3, false), (4, true)]));
|
assert_eq!(construction_network.nodes[5].1.construction_args, ConstructionArgs::Nodes(vec![(3, false), (4, true)]));
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct UpdateLogger {}
|
||||||
|
|
||||||
impl NodeGraphUpdateSender for UpdateLogger {
|
impl NodeGraphUpdateSender for UpdateLogger {
|
||||||
fn send(&self, message: graphene_core::application_io::NodeGraphUpdateMessage) {
|
fn send(&self, message: graphene_core::application_io::NodeGraphUpdateMessage) {
|
||||||
println!("{:?}", message);
|
println!("{message:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
loop {
|
loop {
|
||||||
//println!("executing");
|
//println!("executing");
|
||||||
let _result = (&executor).execute(editor_api.clone()).await?;
|
let _result = (&executor).execute(editor_api.clone()).await?;
|
||||||
//println!("result: {:?}", result);
|
//println!("result: {result:?}");
|
||||||
std::thread::sleep(std::time::Duration::from_millis(16));
|
std::thread::sleep(std::time::Duration::from_millis(16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ mod test {
|
||||||
render_config: graphene_core::application_io::RenderConfig::default(),
|
render_config: graphene_core::application_io::RenderConfig::default(),
|
||||||
};
|
};
|
||||||
let result = (&executor).execute(editor_api.clone()).await.unwrap();
|
let result = (&executor).execute(editor_api.clone()).await.unwrap();
|
||||||
println!("result: {:?}", result);
|
println!("result: {result:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
@ -228,6 +228,6 @@ mod test {
|
||||||
render_config: graphene_core::application_io::RenderConfig::default(),
|
render_config: graphene_core::application_io::RenderConfig::default(),
|
||||||
};
|
};
|
||||||
let result = (&executor).execute(editor_api.clone()).await.unwrap();
|
let result = (&executor).execute(editor_api.clone()).await.unwrap();
|
||||||
println!("result: {:?}", result);
|
println!("result: {result:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ async fn map_gpu<'a: 'input>(image: ImageFrame<Color>, node: DocumentNode, edito
|
||||||
let quantization = crate::quantization::generate_quantization_from_image_frame(&image);
|
let quantization = crate::quantization::generate_quantization_from_image_frame(&image);
|
||||||
#[cfg(not(feature = "quantization"))]
|
#[cfg(not(feature = "quantization"))]
|
||||||
let quantization = QuantizationChannels::default();
|
let quantization = QuantizationChannels::default();
|
||||||
log::debug!("quantization: {:?}", quantization);
|
log::debug!("quantization: {quantization:?}");
|
||||||
|
|
||||||
#[cfg(feature = "image-compare")]
|
#[cfg(feature = "image-compare")]
|
||||||
let img: image::DynamicImage = image::Rgba32FImage::from_raw(image.image.width, image.image.height, bytemuck::cast_vec(image.image.data.clone()))
|
let img: image::DynamicImage = image::Rgba32FImage::from_raw(image.image.width, image.image.height, bytemuck::cast_vec(image.image.data.clone()))
|
||||||
|
@ -163,7 +163,7 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
|
||||||
let compiler = graph_craft::graphene_compiler::Compiler {};
|
let compiler = graph_craft::graphene_compiler::Compiler {};
|
||||||
let inner_network = NodeNetwork::value_network(node);
|
let inner_network = NodeNetwork::value_network(node);
|
||||||
|
|
||||||
log::debug!("inner_network: {:?}", inner_network);
|
log::debug!("inner_network: {inner_network:?}");
|
||||||
let network = NodeNetwork {
|
let network = NodeNetwork {
|
||||||
inputs: vec![2, 1], //vec![0, 1],
|
inputs: vec![2, 1], //vec![0, 1],
|
||||||
#[cfg(feature = "quantization")]
|
#[cfg(feature = "quantization")]
|
||||||
|
@ -285,7 +285,7 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
|
||||||
let canvas = editor_api.application_io.create_surface();
|
let canvas = editor_api.application_io.create_surface();
|
||||||
|
|
||||||
let surface = unsafe { executor.create_surface(canvas) }.unwrap();
|
let surface = unsafe { executor.create_surface(canvas) }.unwrap();
|
||||||
//log::debug!("id: {:?}", surface);
|
//log::debug!("id: {surface:?}");
|
||||||
let surface_id = surface.surface_id;
|
let surface_id = surface.surface_id;
|
||||||
|
|
||||||
let texture = executor.create_texture_buffer(image.image.clone(), TextureBufferOptions::Texture).unwrap();
|
let texture = executor.create_texture_buffer(image.image.clone(), TextureBufferOptions::Texture).unwrap();
|
||||||
|
|
|
@ -79,7 +79,7 @@ fn generate_quantization<const N: usize>(data: Vec<f64>, samples: usize, channel
|
||||||
None => Some(error.clone()),
|
None => Some(error.clone()),
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("Merged: {:?}", merged_error);
|
println!("Merged: {merged_error:?}");
|
||||||
|
|
||||||
let bits = merged_error.as_ref().unwrap().bits.iter().map(|x| x[i]).collect::<Vec<_>>();
|
let bits = merged_error.as_ref().unwrap().bits.iter().map(|x| x[i]).collect::<Vec<_>>();
|
||||||
let model_fit = autoquant::models::OptimizedLin::new(channel_data, 1 << bits[bin_size]);
|
let model_fit = autoquant::models::OptimizedLin::new(channel_data, 1 << bits[bin_size]);
|
||||||
|
|
|
@ -192,7 +192,7 @@ impl ApplicationIo for WasmApplicationIo {
|
||||||
|
|
||||||
fn load_resource(&self, url: impl AsRef<str>) -> Result<ResourceFuture, ApplicationError> {
|
fn load_resource(&self, url: impl AsRef<str>) -> Result<ResourceFuture, ApplicationError> {
|
||||||
let url = url::Url::parse(url.as_ref()).map_err(|_| ApplicationError::InvalidUrl)?;
|
let url = url::Url::parse(url.as_ref()).map_err(|_| ApplicationError::InvalidUrl)?;
|
||||||
log::trace!("Loading resource: {:?}", url);
|
log::trace!("Loading resource: {url:?}");
|
||||||
match url.scheme() {
|
match url.scheme() {
|
||||||
#[cfg(feature = "tokio")]
|
#[cfg(feature = "tokio")]
|
||||||
"file" => {
|
"file" => {
|
||||||
|
@ -219,7 +219,7 @@ impl ApplicationIo for WasmApplicationIo {
|
||||||
"graphite" => {
|
"graphite" => {
|
||||||
let path = url.path();
|
let path = url.path();
|
||||||
let path = path.to_owned();
|
let path = path.to_owned();
|
||||||
log::trace!("Loading local resource: {}", path);
|
log::trace!("Loading local resource: {path}");
|
||||||
let data = self.resources.get(&path).ok_or(ApplicationError::NotFound)?.clone();
|
let data = self.resources.get(&path).ok_or(ApplicationError::NotFound)?.clone();
|
||||||
Ok(Box::pin(async move { Ok(data.clone()) }) as Pin<Box<dyn Future<Output = Result<Arc<[u8]>, _>>>>)
|
Ok(Box::pin(async move { Ok(data.clone()) }) as Pin<Box<dyn Future<Output = Result<Arc<[u8]>, _>>>>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ impl BorrowTree {
|
||||||
ConstructionArgs::Nodes(ids) => {
|
ConstructionArgs::Nodes(ids) => {
|
||||||
let ids: Vec<_> = ids.iter().map(|(id, _)| *id).collect();
|
let ids: Vec<_> = ids.iter().map(|(id, _)| *id).collect();
|
||||||
let construction_nodes = self.node_deps(&ids);
|
let construction_nodes = self.node_deps(&ids);
|
||||||
let constructor = typing_context.constructor(id).ok_or(format!("No constructor found for node {:?}", identifier))?;
|
let constructor = typing_context.constructor(id).ok_or(format!("No constructor found for node {identifier:?}"))?;
|
||||||
let node = constructor(construction_nodes).await;
|
let node = constructor(construction_nodes).await;
|
||||||
let node = NodeContainer::new(node);
|
let node = NodeContainer::new(node);
|
||||||
self.store_node(node, id);
|
self.store_node(node, id);
|
||||||
|
|
|
@ -74,7 +74,7 @@ mod tests {
|
||||||
let compiler = Compiler {};
|
let compiler = Compiler {};
|
||||||
let protograph = compiler.compile_single(network).expect("Graph should be generated");
|
let protograph = compiler.compile_single(network).expect("Graph should be generated");
|
||||||
|
|
||||||
let exec = block_on(DynamicExecutor::new(protograph)).unwrap_or_else(|e| panic!("Failed to create executor: {}", e));
|
let exec = block_on(DynamicExecutor::new(protograph)).unwrap_or_else(|e| panic!("Failed to create executor: {e}"));
|
||||||
|
|
||||||
let result = block_on((&exec).execute(32_u32)).unwrap();
|
let result = block_on((&exec).execute(32_u32)).unwrap();
|
||||||
assert_eq!(result, TaggedValue::U32(33));
|
assert_eq!(result, TaggedValue::U32(33));
|
||||||
|
|
|
@ -206,11 +206,11 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_output_buffer(&self, len: usize, ty: Type, cpu_readable: bool) -> Result<WgpuShaderInput> {
|
fn create_output_buffer(&self, len: usize, ty: Type, cpu_readable: bool) -> Result<WgpuShaderInput> {
|
||||||
log::debug!("Creating output buffer with len: {}", len);
|
log::debug!("Creating output buffer with len: {len}");
|
||||||
let create_buffer = |usage| {
|
let create_buffer = |usage| {
|
||||||
Ok::<_, anyhow::Error>(self.context.device.create_buffer(&BufferDescriptor {
|
Ok::<_, anyhow::Error>(self.context.device.create_buffer(&BufferDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: len as u64 * ty.size().ok_or_else(|| anyhow::anyhow!("Cannot create buffer of type {:?}", ty))? as u64,
|
size: len as u64 * ty.size().ok_or_else(|| anyhow::anyhow!("Cannot create buffer of type {ty:?}"))? as u64,
|
||||||
usage,
|
usage,
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
}))
|
}))
|
||||||
|
@ -290,7 +290,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
||||||
|
|
||||||
let surface = &canvas.as_ref().surface;
|
let surface = &canvas.as_ref().surface;
|
||||||
let surface_caps = surface.get_capabilities(&self.context.adapter);
|
let surface_caps = surface.get_capabilities(&self.context.adapter);
|
||||||
println!("{:?}", surface_caps);
|
println!("{surface_caps:?}");
|
||||||
if surface_caps.formats.is_empty() {
|
if surface_caps.formats.is_empty() {
|
||||||
log::warn!("No surface formats available");
|
log::warn!("No surface formats available");
|
||||||
//return Ok(());
|
//return Ok(());
|
||||||
|
@ -455,7 +455,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
||||||
|
|
||||||
let size = window.surface.inner_size();
|
let size = window.surface.inner_size();
|
||||||
let surface_caps = surface.get_capabilities(&self.context.adapter);
|
let surface_caps = surface.get_capabilities(&self.context.adapter);
|
||||||
println!("{:?}", surface_caps);
|
println!("{surface_caps:?}");
|
||||||
let surface_format = wgpu::TextureFormat::Bgra8Unorm;
|
let surface_format = wgpu::TextureFormat::Bgra8Unorm;
|
||||||
let config = wgpu::SurfaceConfiguration {
|
let config = wgpu::SurfaceConfiguration {
|
||||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||||
|
|
|
@ -116,7 +116,7 @@ fn top_level_impl(input_item: TokenStream) -> syn::Result<TokenStream> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let input_type = &input.ident;
|
let input_type = &input.ident;
|
||||||
let discriminant = call_site_ident(format!("{}Discriminant", input_type));
|
let discriminant = call_site_ident(format!("{input_type}Discriminant"));
|
||||||
|
|
||||||
Ok(quote::quote! {
|
Ok(quote::quote! {
|
||||||
#input
|
#input
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub fn derive_discriminant_impl(input_item: TokenStream) -> syn::Result<TokenStr
|
||||||
};
|
};
|
||||||
is_sub_discriminant.push(true);
|
is_sub_discriminant.push(true);
|
||||||
}
|
}
|
||||||
n => unimplemented!("#[sub_discriminant] on variants with {} fields is not supported (for now)", n),
|
n => unimplemented!("#[sub_discriminant] on variants with {n} fields is not supported (for now)"),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var.fields = Fields::Unit;
|
var.fields = Fields::Unit;
|
||||||
|
|
|
@ -21,7 +21,7 @@ fn parse_hint_helper_attrs(attrs: &[Attribute]) -> syn::Result<(Vec<LitStr>, Vec
|
||||||
// the first value is ok, the other ones should error
|
// the first value is ok, the other ones should error
|
||||||
let after_first = v.into_iter().skip(1);
|
let after_first = v.into_iter().skip(1);
|
||||||
// this call to fold_error_iter will always return Err with a combined error
|
// this call to fold_error_iter will always return Err with a combined error
|
||||||
fold_error_iter(after_first.map(|lit| Err(syn::Error::new(lit.span(), format!("value for key {} was already given", k))))).map(|_: Vec<()>| unreachable!())
|
fold_error_iter(after_first.map(|lit| Err(syn::Error::new(lit.span(), format!("value for key {k} was already given"))))).map(|_: Vec<()>| unreachable!())
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
|
@ -16,6 +16,11 @@ Clone the project:
|
||||||
git clone https://github.com/GraphiteEditor/Graphite.git
|
git clone https://github.com/GraphiteEditor/Graphite.git
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On Debian-based Linux distributions, you may need to install the following packages:
|
||||||
|
```sh
|
||||||
|
sudo apt install libgtk-3-dev libsoup2.4-dev libjavascriptcoregtk-4.0-dev libwebkit2gtk-4.0-dev
|
||||||
|
```
|
||||||
|
|
||||||
Then install the required Node.js packages:
|
Then install the required Node.js packages:
|
||||||
```sh
|
```sh
|
||||||
cd frontend
|
cd frontend
|
||||||
|
|
|
@ -48,7 +48,7 @@ fn parse_t_variant(t_variant: &String, t: f64) -> TValue {
|
||||||
match t_variant.as_str() {
|
match t_variant.as_str() {
|
||||||
"Parametric" => TValue::Parametric(t),
|
"Parametric" => TValue::Parametric(t),
|
||||||
"Euclidean" => TValue::Euclidean(t),
|
"Euclidean" => TValue::Euclidean(t),
|
||||||
_ => panic!("Unexpected TValue string: '{}'", t_variant),
|
_ => panic!("Unexpected TValue string: '{t_variant}'"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ impl WasmBezier {
|
||||||
let tvalue_type = match t_variant.as_str() {
|
let tvalue_type = match t_variant.as_str() {
|
||||||
"Parametric" => TValueType::Parametric,
|
"Parametric" => TValueType::Parametric,
|
||||||
"Euclidean" => TValueType::Euclidean,
|
"Euclidean" => TValueType::Euclidean,
|
||||||
_ => panic!("Unexpected TValue string: '{}'", t_variant),
|
_ => panic!("Unexpected TValue string: '{t_variant}'"),
|
||||||
};
|
};
|
||||||
let table_values: Vec<DVec2> = self.0.compute_lookup_table(Some(steps), Some(tvalue_type));
|
let table_values: Vec<DVec2> = self.0.compute_lookup_table(Some(steps), Some(tvalue_type));
|
||||||
let circles: String = table_values
|
let circles: String = table_values
|
||||||
|
|
|
@ -26,7 +26,7 @@ fn parse_t_variant(t_variant: &String, t: f64) -> SubpathTValue {
|
||||||
match t_variant.as_str() {
|
match t_variant.as_str() {
|
||||||
"GlobalParametric" => SubpathTValue::GlobalParametric(t),
|
"GlobalParametric" => SubpathTValue::GlobalParametric(t),
|
||||||
"GlobalEuclidean" => SubpathTValue::GlobalEuclidean(t),
|
"GlobalEuclidean" => SubpathTValue::GlobalEuclidean(t),
|
||||||
_ => panic!("Unexpected TValue string: '{}'", t_variant),
|
_ => panic!("Unexpected TValue string: '{t_variant}'"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ impl WasmSubpath {
|
||||||
let tvalue_type = match t_variant.as_str() {
|
let tvalue_type = match t_variant.as_str() {
|
||||||
"GlobalParametric" => TValueType::Parametric,
|
"GlobalParametric" => TValueType::Parametric,
|
||||||
"GlobalEuclidean" => TValueType::Euclidean,
|
"GlobalEuclidean" => TValueType::Euclidean,
|
||||||
_ => panic!("Unexpected TValue string: '{}'", t_variant),
|
_ => panic!("Unexpected TValue string: '{t_variant}'"),
|
||||||
};
|
};
|
||||||
let table_values: Vec<DVec2> = self.0.compute_lookup_table(Some(steps), Some(tvalue_type));
|
let table_values: Vec<DVec2> = self.0.compute_lookup_table(Some(steps), Some(tvalue_type));
|
||||||
let circles: String = table_values
|
let circles: String = table_values
|
||||||
|
@ -385,7 +385,7 @@ impl WasmSubpath {
|
||||||
main_subpath.iter().enumerate().for_each(|(index, bezier)| {
|
main_subpath.iter().enumerate().for_each(|(index, bezier)| {
|
||||||
let hue1 = &format!("hsla({}, 100%, 50%, 0.5)", 40 * index);
|
let hue1 = &format!("hsla({}, 100%, 50%, 0.5)", 40 * index);
|
||||||
let hue2 = &format!("hsla({}, 100%, 50%, 0.5)", 40 * (index + 1));
|
let hue2 = &format!("hsla({}, 100%, 50%, 0.5)", 40 * (index + 1));
|
||||||
let gradient_id = &format!("gradient{}", index);
|
let gradient_id = &format!("gradient{index}");
|
||||||
let start = bezier.start();
|
let start = bezier.start();
|
||||||
let end = bezier.end();
|
let end = bezier.end();
|
||||||
let _ = write!(
|
let _ = write!(
|
||||||
|
@ -400,7 +400,7 @@ impl WasmSubpath {
|
||||||
hue2
|
hue2
|
||||||
);
|
);
|
||||||
|
|
||||||
let stroke = &format!("url(#{})", gradient_id);
|
let stroke = &format!("url(#{gradient_id})");
|
||||||
bezier.curve_to_svg(
|
bezier.curve_to_svg(
|
||||||
&mut main_subpath_svg,
|
&mut main_subpath_svg,
|
||||||
CURVE_ATTRIBUTES.to_string().replace(BLACK, stroke).replace("stroke-width=\"2\"", "stroke-width=\"8\""),
|
CURVE_ATTRIBUTES.to_string().replace(BLACK, stroke).replace("stroke-width=\"2\"", "stroke-width=\"8\""),
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub const TEXT_OFFSET_X: f64 = 5.;
|
||||||
pub const TEXT_OFFSET_Y: f64 = 193.;
|
pub const TEXT_OFFSET_Y: f64 = 193.;
|
||||||
|
|
||||||
pub fn wrap_svg_tag(contents: String) -> String {
|
pub fn wrap_svg_tag(contents: String) -> String {
|
||||||
format!("{}{}{}", SVG_OPEN_TAG, contents, SVG_CLOSE_TAG)
|
format!("{SVG_OPEN_TAG}{contents}{SVG_CLOSE_TAG}")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to create an SVG text entity.
|
/// Helper function to create an SVG text entity.
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub fn parse_join(join: i32, miter_limit: f64) -> Join {
|
||||||
0 => Join::Bevel,
|
0 => Join::Bevel,
|
||||||
1 => Join::Miter(Some(miter_limit)),
|
1 => Join::Miter(Some(miter_limit)),
|
||||||
2 => Join::Round,
|
2 => Join::Round,
|
||||||
_ => panic!("Unexpected Join value: '{}'", join),
|
_ => panic!("Unexpected Join value: '{join}'"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,6 @@ pub fn parse_cap(cap: i32) -> Cap {
|
||||||
0 => Cap::Butt,
|
0 => Cap::Butt,
|
||||||
1 => Cap::Round,
|
1 => Cap::Round,
|
||||||
2 => Cap::Square,
|
2 => Cap::Square,
|
||||||
_ => panic!("Unexpected Cap value: '{}'", cap),
|
_ => panic!("Unexpected Cap value: '{cap}'"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue