Skip to content

Commit 527070c

Browse files
authored
Merge branch 'GraphiteEditor:master' into master
2 parents 16b6fc8 + 8055e85 commit 527070c

5 files changed

Lines changed: 61 additions & 27 deletions

File tree

.github/workflows/build-pr-command.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
# Command should be limited to core team members (those in the organization) for security.
1313
# From the GitHub Actions docs:
1414
# author_association = 'MEMBER': Author is a member of the organization that owns the repository.
15-
if: github.event.issue.pull_request && github.event.comment.body == '!build' && github.event.comment.author_association == 'MEMBER'
15+
if: github.event.issue.pull_request && (github.event.comment.body == '!build' || github.event.comment.body == '!build-profiling') && github.event.comment.author_association == 'MEMBER'
1616
runs-on: self-hosted
1717
permissions:
1818
contents: read
@@ -67,12 +67,23 @@ jobs:
6767
export INDEX_HTML_HEAD_REPLACEMENT=""
6868
sed -i "s|<!-- INDEX_HTML_HEAD_REPLACEMENT -->|$INDEX_HTML_HEAD_REPLACEMENT|" frontend/index.html
6969
70+
- name: ⌨ Set build command based on comment
71+
id: build_command
72+
run: |
73+
if [[ "${{ github.event.comment.body }}" == "!build" ]]; then
74+
echo "command=build" >> $GITHUB_OUTPUT
75+
elif [[ "${{ github.event.comment.body }}" == "!build-profiling" ]]; then
76+
echo "command=build-profiling" >> $GITHUB_OUTPUT
77+
else
78+
echo "command=print-building-help" >> $GITHUB_OUTPUT
79+
fi
80+
7081
- name: 🌐 Build Graphite web code
7182
env:
7283
NODE_ENV: production
7384
run: |
7485
cd frontend
75-
mold -run npm run build
86+
mold -run npm run ${{ steps.build_command.outputs.command }}
7687
7788
- name: 📤 Publish to Cloudflare Pages
7889
id: cloudflare

editor/src/messages/portfolio/document/document_message_handler.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,6 @@ impl DocumentMessageHandler {
11211121
let mut space = 0;
11221122
for layer_node in folder.children(self.metadata()) {
11231123
data.push(layer_node.to_node());
1124-
info!("Pushed child");
11251124
space += 1;
11261125
if layer_node.has_children(self.metadata()) {
11271126
path.push(layer_node.to_node());

editor/src/node_graph_executor.rs

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub struct NodeRuntime {
5757
pub(crate) click_targets: HashMap<NodeId, Vec<ClickTarget>>,
5858
pub(crate) transforms: HashMap<NodeId, DAffine2>,
5959
pub(crate) upstream_transforms: HashMap<NodeId, DAffine2>,
60+
graph_hash: Option<u64>,
6061
canvas_cache: HashMap<Vec<LayerId>, SurfaceId>,
6162
}
6263

@@ -124,6 +125,7 @@ impl NodeRuntime {
124125
canvas_cache: HashMap::new(),
125126
click_targets: HashMap::new(),
126127
transforms: HashMap::new(),
128+
graph_hash: None,
127129
upstream_transforms: HashMap::new(),
128130
}
129131
}
@@ -151,8 +153,10 @@ impl NodeRuntime {
151153
}) => {
152154
let (result, monitor_nodes) = self.execute_network(&path, graph, transform, viewport_resolution).await;
153155
let mut responses = VecDeque::new();
154-
self.update_thumbnails(&path, &monitor_nodes, &mut responses);
155-
self.update_upstream_transforms(&monitor_nodes);
156+
if let Some(ref monitor_nodes) = monitor_nodes {
157+
self.update_thumbnails(&path, monitor_nodes, &mut responses);
158+
self.update_upstream_transforms(monitor_nodes);
159+
}
156160
let response = GenerationResponse {
157161
generation_id,
158162
result,
@@ -169,7 +173,7 @@ impl NodeRuntime {
169173
}
170174
}
171175

172-
async fn execute_network<'a>(&'a mut self, path: &[LayerId], graph: NodeNetwork, transform: DAffine2, viewport_resolution: UVec2) -> (Result<TaggedValue, String>, MonitorNodes) {
176+
async fn execute_network<'a>(&'a mut self, path: &[LayerId], graph: NodeNetwork, transform: DAffine2, viewport_resolution: UVec2) -> (Result<TaggedValue, String>, Option<MonitorNodes>) {
173177
if self.wasm_io.is_none() {
174178
self.wasm_io = Some(WasmApplicationIo::new().await);
175179
}
@@ -198,27 +202,41 @@ impl NodeRuntime {
198202
// Required to ensure that the appropriate protonodes are reinserted when the Editor API changes.
199203
let mut graph_input_hash = DefaultHasher::new();
200204
editor_api.font_cache.hash(&mut graph_input_hash);
205+
let font_hash_code = graph_input_hash.finish();
206+
graph.hash(&mut graph_input_hash);
207+
let hash_code = graph_input_hash.finish();
208+
209+
if self.graph_hash != Some(hash_code) {
210+
self.graph_hash = None;
211+
}
201212

202-
let scoped_network = wrap_network_in_scope(graph, graph_input_hash.finish());
213+
let mut cached_monitor_nodes = None;
203214

204-
let monitor_nodes = scoped_network
205-
.recursive_nodes()
206-
.filter(|(_, node)| node.implementation == DocumentNodeImplementation::proto("graphene_core::memo::MonitorNode<_, _, _>"))
207-
.map(|(_, node)| node.path.clone().unwrap_or_default())
208-
.collect::<Vec<_>>();
215+
if self.graph_hash.is_none() {
216+
let scoped_network = wrap_network_in_scope(graph, font_hash_code);
209217

210-
// We assume only one output
211-
assert_eq!(scoped_network.outputs.len(), 1, "Graph with multiple outputs not yet handled");
212-
let c = Compiler {};
213-
let proto_network = match c.compile_single(scoped_network) {
214-
Ok(network) => network,
215-
Err(e) => return (Err(e), monitor_nodes),
216-
};
218+
let monitor_nodes = scoped_network
219+
.recursive_nodes()
220+
.filter(|(_, node)| node.implementation == DocumentNodeImplementation::proto("graphene_core::memo::MonitorNode<_, _, _>"))
221+
.map(|(_, node)| node.path.clone().unwrap_or_default())
222+
.collect::<Vec<_>>();
223+
224+
// We assume only one output
225+
assert_eq!(scoped_network.outputs.len(), 1, "Graph with multiple outputs not yet handled");
226+
let c = Compiler {};
227+
let proto_network = match c.compile_single(scoped_network) {
228+
Ok(network) => network,
229+
Err(e) => return (Err(e), Some(monitor_nodes)),
230+
};
231+
232+
assert_ne!(proto_network.nodes.len(), 0, "No protonodes exist?");
233+
if let Err(e) = self.executor.update(proto_network).await {
234+
error!("Failed to update executor:\n{e}");
235+
return (Err(e), Some(monitor_nodes));
236+
}
217237

218-
assert_ne!(proto_network.nodes.len(), 0, "No protonodes exist?");
219-
if let Err(e) = self.executor.update(proto_network).await {
220-
error!("Failed to update executor:\n{e}");
221-
return (Err(e), monitor_nodes);
238+
cached_monitor_nodes = Some(monitor_nodes);
239+
self.graph_hash = Some(hash_code);
222240
}
223241

224242
use graph_craft::graphene_compiler::Executor;
@@ -231,7 +249,7 @@ impl NodeRuntime {
231249
};
232250
let result = match result {
233251
Ok(value) => value,
234-
Err(e) => return (Err(e), monitor_nodes),
252+
Err(e) => return (Err(e), cached_monitor_nodes),
235253
};
236254

237255
if let TaggedValue::SurfaceFrame(SurfaceFrame { surface_id, transform: _ }) = result {
@@ -244,7 +262,7 @@ impl NodeRuntime {
244262
}
245263
}
246264
}
247-
(Ok(result), monitor_nodes)
265+
(Ok(result), cached_monitor_nodes)
248266
}
249267

250268
/// Recomputes the thumbnails for the layers in the graph, modifying the state and updating the UI.

frontend/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88
"scripts": {
99
"start": "npm run build-wasm && concurrently -k -n \"VITE,RUST\" \"vite\" \"npm run watch:wasm\" || (npm run print-building-help && exit 1)",
1010
"profiling": "npm run build-wasm-profiling && concurrently -k -n \"VITE,RUST\" \"vite\" \"npm run watch:wasm-profiling\" || (npm run print-building-help && exit 1)",
11+
"build": "npm run build-wasm-prod && vite build || (npm run print-building-help && exit 1)",
12+
"build-profiling": "npm run build-wasm-profiling && vite build || (npm run print-building-help && exit 1)",
1113
"lint": "eslint .",
1214
"lint-fix": "eslint . --fix",
13-
"build": "npm run build-wasm-prod && vite build || (npm run print-building-help && exit 1)",
15+
"--------------------": "",
1416
"build-wasm": "wasm-pack build ./wasm --dev --target=web",
1517
"build-wasm-profiling": "wasm-pack build ./wasm --profiling --target=web",
1618
"build-wasm-prod": "wasm-pack build ./wasm --release --target=web",
1719
"tauri": "echo 'Make sure you build the wasm binary for tauri using `npm run tauri:build-wasm`' && vite",
1820
"tauri:build-wasm": "wasm-pack build ./wasm --release --target=web -- --features tauri",
1921
"watch:wasm": "cargo watch --postpone --watch-when-idle --workdir=wasm --shell \"wasm-pack build . --dev --target=web -- --color=always\"",
2022
"watch:wasm-profiling": "cargo watch --postpone --watch-when-idle --workdir=wasm --shell \"wasm-pack build . --profiling --target=web -- --color=always\"",
21-
"--------------------": "",
2223
"print-building-help": "echo 'Graphite project failed to build. Did you remember to `npm install` the dependencies in `/frontend`?'",
2324
"print-linting-help": "echo 'Graphite project had lint errors, or may have otherwise failed. In the latter case, did you remember to `npm install` the dependencies in `/frontend`?'"
2425
},

frontend/src-tauri/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
use std::{fs, path::PathBuf};
2+
13
fn main() {
4+
// Directory required for compilation, but not tracked by git if empty.
5+
let dist_dir: PathBuf = ["..", "dist"].iter().collect();
6+
fs::create_dir_all(dist_dir).unwrap();
27
tauri_build::build()
38
}

0 commit comments

Comments
 (0)