diff --git a/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-linux.xml b/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-linux.xml
index 0bec8612bd87..7d80334bfd6c 100644
--- a/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-linux.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-linux.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-component-list-panel-view [wasm, linux]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/component-list-panel-view"
+ folderName="🚥 GUI view/examples/component-list-panel-view"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-macos.xml b/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-macos.xml
index fffd236bc5ae..70fd649ad61e 100644
--- a/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-macos.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-macos.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-component-list-panel-view [wasm, macos]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/component-list-panel-view"
+ folderName="🚥 GUI view/examples/component-list-panel-view"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-windows.xml b/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-windows.xml
index 7647ed1e5fcf..bc3a11d930f2 100644
--- a/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-windows.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm-windows.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-component-list-panel-view [wasm, windows]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/component-list-panel-view"
+ folderName="🚥 GUI view/examples/component-list-panel-view"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm.xml b/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm.xml
index 18962ce9b030..efc9f96f5052 100644
--- a/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-component-list-panel-view-wasm.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-component-list-panel-view [wasm]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/component-list-panel-view"
+ folderName="🚥 GUI view/examples/component-list-panel-view"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-icons-wasm-linux.xml b/.idea/runConfigurations/clippy-debug-scene-icons-wasm-linux.xml
index 7591018f99af..83585e355095 100644
--- a/.idea/runConfigurations/clippy-debug-scene-icons-wasm-linux.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-icons-wasm-linux.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-icons [wasm, linux]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/icons"
+ folderName="🚥 GUI view/examples/icons"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-icons-wasm-macos.xml b/.idea/runConfigurations/clippy-debug-scene-icons-wasm-macos.xml
index 4cb8dd1ce758..d38c9dbf7d69 100644
--- a/.idea/runConfigurations/clippy-debug-scene-icons-wasm-macos.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-icons-wasm-macos.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-icons [wasm, macos]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/icons"
+ folderName="🚥 GUI view/examples/icons"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-icons-wasm-windows.xml b/.idea/runConfigurations/clippy-debug-scene-icons-wasm-windows.xml
index 81f5a717198a..3101e13ae4f6 100644
--- a/.idea/runConfigurations/clippy-debug-scene-icons-wasm-windows.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-icons-wasm-windows.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-icons [wasm, windows]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/icons"
+ folderName="🚥 GUI view/examples/icons"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-icons-wasm.xml b/.idea/runConfigurations/clippy-debug-scene-icons-wasm.xml
index 80c4d47e115d..c33a5652007f 100644
--- a/.idea/runConfigurations/clippy-debug-scene-icons-wasm.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-icons-wasm.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-icons [wasm]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/icons"
+ folderName="🚥 GUI view/examples/icons"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-interface-wasm-linux.xml b/.idea/runConfigurations/clippy-debug-scene-interface-wasm-linux.xml
index 3fda64b7c772..53020837f386 100644
--- a/.idea/runConfigurations/clippy-debug-scene-interface-wasm-linux.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-interface-wasm-linux.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-interface [wasm, linux]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/interface"
+ folderName="🚥 GUI view/examples/interface"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-interface-wasm-macos.xml b/.idea/runConfigurations/clippy-debug-scene-interface-wasm-macos.xml
index 0957659d6b76..5ea31d67d5de 100644
--- a/.idea/runConfigurations/clippy-debug-scene-interface-wasm-macos.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-interface-wasm-macos.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-interface [wasm, macos]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/interface"
+ folderName="🚥 GUI view/examples/interface"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-interface-wasm-windows.xml b/.idea/runConfigurations/clippy-debug-scene-interface-wasm-windows.xml
index 58b55ac0b0d8..8d0243196d57 100644
--- a/.idea/runConfigurations/clippy-debug-scene-interface-wasm-windows.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-interface-wasm-windows.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-interface [wasm, windows]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/interface"
+ folderName="🚥 GUI view/examples/interface"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-interface-wasm.xml b/.idea/runConfigurations/clippy-debug-scene-interface-wasm.xml
index 2de12565f1d6..1db0ca8d2f35 100644
--- a/.idea/runConfigurations/clippy-debug-scene-interface-wasm.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-interface-wasm.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-interface [wasm]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/interface"
+ folderName="🚥 GUI view/examples/interface"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-linux.xml b/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-linux.xml
index 17d6e3b55f8b..48ca407fd15c 100644
--- a/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-linux.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-linux.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-text-grid-visualization [wasm, linux]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/text-grid-visualization"
+ folderName="🚥 GUI view/examples/text-grid-visualization"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-macos.xml b/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-macos.xml
index 701bebdc3339..66b2cd6c342e 100644
--- a/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-macos.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-macos.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-text-grid-visualization [wasm, macos]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/text-grid-visualization"
+ folderName="🚥 GUI view/examples/text-grid-visualization"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-windows.xml b/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-windows.xml
index cec1f76063fb..c490b76bd4f4 100644
--- a/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-windows.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm-windows.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-text-grid-visualization [wasm, windows]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/text-grid-visualization"
+ folderName="🚥 GUI view/examples/text-grid-visualization"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm.xml b/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm.xml
index fee11326b395..eb0cfca20390 100644
--- a/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-text-grid-visualization-wasm.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-text-grid-visualization [wasm]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/text-grid-visualization"
+ folderName="🚥 GUI view/examples/text-grid-visualization"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-linux.xml b/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-linux.xml
index 7ccb2f2d734b..444bc83743fd 100644
--- a/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-linux.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-linux.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-visualization [wasm, linux]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/visualization"
+ folderName="🚥 GUI view/examples/visualization"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-macos.xml b/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-macos.xml
index a459c1825cbd..7d02ab8a3e55 100644
--- a/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-macos.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-macos.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-visualization [wasm, macos]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/visualization"
+ folderName="🚥 GUI view/examples/visualization"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-windows.xml b/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-windows.xml
index 4948525dbe5e..a8584e8f26a3 100644
--- a/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-windows.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-visualization-wasm-windows.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-visualization [wasm, windows]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/visualization"
+ folderName="🚥 GUI view/examples/visualization"
>
diff --git a/.idea/runConfigurations/clippy-debug-scene-visualization-wasm.xml b/.idea/runConfigurations/clippy-debug-scene-visualization-wasm.xml
index 5fa5540ca49b..748d67b96a3e 100644
--- a/.idea/runConfigurations/clippy-debug-scene-visualization-wasm.xml
+++ b/.idea/runConfigurations/clippy-debug-scene-visualization-wasm.xml
@@ -5,7 +5,7 @@
name="clippy/debug-scene-visualization [wasm]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/visualization"
+ folderName="🚥 GUI view/examples/visualization"
>
diff --git a/.idea/runConfigurations/clippy-enso-debug-scene-wasm-linux.xml b/.idea/runConfigurations/clippy-enso-debug-scene-wasm-linux.xml
index fb6937175aa8..e9f4aab3d499 100644
--- a/.idea/runConfigurations/clippy-enso-debug-scene-wasm-linux.xml
+++ b/.idea/runConfigurations/clippy-enso-debug-scene-wasm-linux.xml
@@ -5,7 +5,7 @@
name="clippy/enso-debug-scene [wasm, linux]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene"
+ folderName="🚥 GUI view/examples"
>
diff --git a/.idea/runConfigurations/clippy-enso-debug-scene-wasm-macos.xml b/.idea/runConfigurations/clippy-enso-debug-scene-wasm-macos.xml
index d4c1bcfbb547..5af448dee27d 100644
--- a/.idea/runConfigurations/clippy-enso-debug-scene-wasm-macos.xml
+++ b/.idea/runConfigurations/clippy-enso-debug-scene-wasm-macos.xml
@@ -5,7 +5,7 @@
name="clippy/enso-debug-scene [wasm, macos]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene"
+ folderName="🚥 GUI view/examples"
>
diff --git a/.idea/runConfigurations/clippy-enso-debug-scene-wasm-windows.xml b/.idea/runConfigurations/clippy-enso-debug-scene-wasm-windows.xml
index 0e591365b8a2..2a775cc59921 100644
--- a/.idea/runConfigurations/clippy-enso-debug-scene-wasm-windows.xml
+++ b/.idea/runConfigurations/clippy-enso-debug-scene-wasm-windows.xml
@@ -5,7 +5,7 @@
name="clippy/enso-debug-scene [wasm, windows]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene"
+ folderName="🚥 GUI view/examples"
>
diff --git a/.idea/runConfigurations/clippy-enso-debug-scene-wasm.xml b/.idea/runConfigurations/clippy-enso-debug-scene-wasm.xml
index b2cffe3e47e9..fd2e311f6f5d 100644
--- a/.idea/runConfigurations/clippy-enso-debug-scene-wasm.xml
+++ b/.idea/runConfigurations/clippy-enso-debug-scene-wasm.xml
@@ -5,7 +5,7 @@
name="clippy/enso-debug-scene [wasm]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene"
+ folderName="🚥 GUI view/examples"
>
diff --git a/.idea/runConfigurations/doc-test-debug-scene-component-list-panel-view-native.xml b/.idea/runConfigurations/doc-test-debug-scene-component-list-panel-view-native.xml
index c33f35e017a5..6ef3f01d3182 100644
--- a/.idea/runConfigurations/doc-test-debug-scene-component-list-panel-view-native.xml
+++ b/.idea/runConfigurations/doc-test-debug-scene-component-list-panel-view-native.xml
@@ -5,7 +5,7 @@
name="doc-test/debug-scene-component-list-panel-view [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/component-list-panel-view"
+ folderName="🚥 GUI view/examples/component-list-panel-view"
>
diff --git a/.idea/runConfigurations/doc-test-debug-scene-icons-native.xml b/.idea/runConfigurations/doc-test-debug-scene-icons-native.xml
index 62fe1d22efa8..06083d94f045 100644
--- a/.idea/runConfigurations/doc-test-debug-scene-icons-native.xml
+++ b/.idea/runConfigurations/doc-test-debug-scene-icons-native.xml
@@ -5,7 +5,7 @@
name="doc-test/debug-scene-icons [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/icons"
+ folderName="🚥 GUI view/examples/icons"
>
diff --git a/.idea/runConfigurations/doc-test-debug-scene-interface-native.xml b/.idea/runConfigurations/doc-test-debug-scene-interface-native.xml
index cfc19f8625a0..ba37bb71b196 100644
--- a/.idea/runConfigurations/doc-test-debug-scene-interface-native.xml
+++ b/.idea/runConfigurations/doc-test-debug-scene-interface-native.xml
@@ -5,7 +5,7 @@
name="doc-test/debug-scene-interface [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/interface"
+ folderName="🚥 GUI view/examples/interface"
>
diff --git a/.idea/runConfigurations/doc-test-debug-scene-text-grid-visualization-native.xml b/.idea/runConfigurations/doc-test-debug-scene-text-grid-visualization-native.xml
index 21b229309bc3..52413f81c259 100644
--- a/.idea/runConfigurations/doc-test-debug-scene-text-grid-visualization-native.xml
+++ b/.idea/runConfigurations/doc-test-debug-scene-text-grid-visualization-native.xml
@@ -5,7 +5,7 @@
name="doc-test/debug-scene-text-grid-visualization [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/text-grid-visualization"
+ folderName="🚥 GUI view/examples/text-grid-visualization"
>
diff --git a/.idea/runConfigurations/doc-test-debug-scene-visualization-native.xml b/.idea/runConfigurations/doc-test-debug-scene-visualization-native.xml
index fcd721cc1b1f..ffd52df3da94 100644
--- a/.idea/runConfigurations/doc-test-debug-scene-visualization-native.xml
+++ b/.idea/runConfigurations/doc-test-debug-scene-visualization-native.xml
@@ -5,7 +5,7 @@
name="doc-test/debug-scene-visualization [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/visualization"
+ folderName="🚥 GUI view/examples/visualization"
>
diff --git a/.idea/runConfigurations/doc-test-enso-debug-scene-native.xml b/.idea/runConfigurations/doc-test-enso-debug-scene-native.xml
index 5ce6d68f6a84..42d9e7620956 100644
--- a/.idea/runConfigurations/doc-test-enso-debug-scene-native.xml
+++ b/.idea/runConfigurations/doc-test-enso-debug-scene-native.xml
@@ -5,7 +5,7 @@
name="doc-test/enso-debug-scene [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene"
+ folderName="🚥 GUI view/examples"
>
diff --git a/.idea/runConfigurations/test-debug-scene-component-list-panel-view-native.xml b/.idea/runConfigurations/test-debug-scene-component-list-panel-view-native.xml
index 37deabe81c5b..6abe6ad07360 100644
--- a/.idea/runConfigurations/test-debug-scene-component-list-panel-view-native.xml
+++ b/.idea/runConfigurations/test-debug-scene-component-list-panel-view-native.xml
@@ -5,7 +5,7 @@
name="test/debug-scene-component-list-panel-view [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/component-list-panel-view"
+ folderName="🚥 GUI view/examples/component-list-panel-view"
>
diff --git a/.idea/runConfigurations/test-debug-scene-icons-native.xml b/.idea/runConfigurations/test-debug-scene-icons-native.xml
index 7ba574edfba5..6b9f2b80a58c 100644
--- a/.idea/runConfigurations/test-debug-scene-icons-native.xml
+++ b/.idea/runConfigurations/test-debug-scene-icons-native.xml
@@ -5,7 +5,7 @@
name="test/debug-scene-icons [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/icons"
+ folderName="🚥 GUI view/examples/icons"
>
diff --git a/.idea/runConfigurations/test-debug-scene-interface-native.xml b/.idea/runConfigurations/test-debug-scene-interface-native.xml
index b0964576f53e..711317b7a6f9 100644
--- a/.idea/runConfigurations/test-debug-scene-interface-native.xml
+++ b/.idea/runConfigurations/test-debug-scene-interface-native.xml
@@ -5,7 +5,7 @@
name="test/debug-scene-interface [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/interface"
+ folderName="🚥 GUI view/examples/interface"
>
diff --git a/.idea/runConfigurations/test-debug-scene-text-grid-visualization-native.xml b/.idea/runConfigurations/test-debug-scene-text-grid-visualization-native.xml
index f2a3d562381b..91ed3362e7cf 100644
--- a/.idea/runConfigurations/test-debug-scene-text-grid-visualization-native.xml
+++ b/.idea/runConfigurations/test-debug-scene-text-grid-visualization-native.xml
@@ -5,7 +5,7 @@
name="test/debug-scene-text-grid-visualization [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/text-grid-visualization"
+ folderName="🚥 GUI view/examples/text-grid-visualization"
>
diff --git a/.idea/runConfigurations/test-debug-scene-visualization-native.xml b/.idea/runConfigurations/test-debug-scene-visualization-native.xml
index 047bec1902fb..21dd42b146dc 100644
--- a/.idea/runConfigurations/test-debug-scene-visualization-native.xml
+++ b/.idea/runConfigurations/test-debug-scene-visualization-native.xml
@@ -5,7 +5,7 @@
name="test/debug-scene-visualization [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene/visualization"
+ folderName="🚥 GUI view/examples/visualization"
>
diff --git a/.idea/runConfigurations/test-enso-debug-scene-native.xml b/.idea/runConfigurations/test-enso-debug-scene-native.xml
index dc51619de249..61a4e2cb4188 100644
--- a/.idea/runConfigurations/test-enso-debug-scene-native.xml
+++ b/.idea/runConfigurations/test-enso-debug-scene-native.xml
@@ -5,7 +5,7 @@
name="test/enso-debug-scene [native]"
type="CargoCommandRunConfiguration"
factoryName="Cargo Command"
- folderName="🚥 GUI view/debug_scene"
+ folderName="🚥 GUI view/examples"
>
diff --git a/Cargo.lock b/Cargo.lock
index 825cf6df505c..c68803847a53 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2616,6 +2616,7 @@ dependencies = [
"ensogl-text-embedded-fonts",
"enum_dispatch",
"failure",
+ "futures 0.3.26",
"itertools",
"js-sys",
"nalgebra",
diff --git a/Cargo.toml b/Cargo.toml
index edd028090a0c..e80115f9db8a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,8 +1,11 @@
[workspace]
resolver = "2"
# Listing only the "root" crates of each app/library. All path dependencies are included in the workspace automatically.
-# If you want to add sub crate (like `app/gui/config` or `lib/rust/ensogl/example`), just add it as a path dependency
+# If you want to add sub crate (like `app/gui/config` or `lib/rust/ensogl/examples`), just add it as a path dependency
# where plausible.
+# Any GUI functionality that is not used by the main entry point should be defined somewhere with `examples` in the
+# path, e.g. `lib/rust/ensogl/examples`, or `app/gui/view/examples`; this is used to optimize the application for
+# loading the IDE.
members = [
"app/gui",
"app/gui/language/parser",
diff --git a/app/gui/Cargo.toml b/app/gui/Cargo.toml
index 1361dab8cd06..8629e92f6c5b 100644
--- a/app/gui/Cargo.toml
+++ b/app/gui/Cargo.toml
@@ -14,7 +14,7 @@ enso-config = { path = "config" }
enso-callback = { path = "../../lib/rust/callback" }
enso-data-structures = { path = "../../lib/rust/data-structures" }
enso-debug-api = { path = "../../lib/rust/debug-api" }
-enso-debug-scene = { path = "view/debug_scene" }
+enso-debug-scene = { path = "view/examples" }
enso-frp = { path = "../../lib/rust/frp" }
enso-prelude = { path = "../../lib/rust/prelude" }
enso-profiler = { path = "../../lib/rust/profiler" }
@@ -25,7 +25,7 @@ enso-text = { path = "../../lib/rust/text" }
enso-web = { path = "../../lib/rust/web" }
enso-suggestion-database = { path = "suggestion-database" }
ensogl = { path = "../../lib/rust/ensogl" }
-ensogl-examples = { path = "../../lib/rust/ensogl/example" }
+ensogl-examples = { path = "../../lib/rust/ensogl/examples" }
ensogl-component = { path = "../../lib/rust/ensogl/component" }
ensogl-text-msdf = { path = "../../lib/rust/ensogl/component/text/src/font/msdf" }
ensogl-hardcoded-theme = { path = "../../lib/rust/ensogl/app/theme/hardcoded" }
diff --git a/app/gui/docs/CONTRIBUTING.md b/app/gui/docs/CONTRIBUTING.md
index 068d7266298c..d4f04fcaef47 100644
--- a/app/gui/docs/CONTRIBUTING.md
+++ b/app/gui/docs/CONTRIBUTING.md
@@ -210,7 +210,7 @@ below:
- **Selective mode** In order to compile only part of the project, and thus
drastically shorten the incremental compile time, you are advised to use the
selective compilation mode by passing the `--crate-path` option to the `build`
- or `watch` command, e.g. `./run ide watch --crate-path ensogl/example` to
+ or `watch` command, e.g. `./run ide watch --crate-path ensogl/examples` to
compile only the renderer-related example scenes. Please note, that in order
to run a scene in a web-browser, the scene has to be compiled and has to
expose a public function with a name starting with `entry_point_`. Thus, if
diff --git a/app/gui/src/model/undo_redo.rs b/app/gui/src/model/undo_redo.rs
index f4d1b408c4af..f4be92bd37dc 100644
--- a/app/gui/src/model/undo_redo.rs
+++ b/app/gui/src/model/undo_redo.rs
@@ -132,7 +132,7 @@ impl Drop for Transaction {
urm.push_to(Stack::Undo, self.frame.borrow().clone());
urm.clear(Stack::Redo);
} else {
- info!(
+ debug!(
"Dropping the ignored transaction '{}' without pushing a frame to repository.",
self.name()
)
diff --git a/app/gui/view/debug_scene/Cargo.toml b/app/gui/view/examples/Cargo.toml
similarity index 100%
rename from app/gui/view/debug_scene/Cargo.toml
rename to app/gui/view/examples/Cargo.toml
diff --git a/app/gui/view/debug_scene/component-list-panel-view/Cargo.toml b/app/gui/view/examples/component-list-panel-view/Cargo.toml
similarity index 100%
rename from app/gui/view/debug_scene/component-list-panel-view/Cargo.toml
rename to app/gui/view/examples/component-list-panel-view/Cargo.toml
diff --git a/app/gui/view/debug_scene/component-list-panel-view/src/lib.rs b/app/gui/view/examples/component-list-panel-view/src/lib.rs
similarity index 100%
rename from app/gui/view/debug_scene/component-list-panel-view/src/lib.rs
rename to app/gui/view/examples/component-list-panel-view/src/lib.rs
diff --git a/app/gui/view/debug_scene/documentation/Cargo.toml b/app/gui/view/examples/documentation/Cargo.toml
similarity index 100%
rename from app/gui/view/debug_scene/documentation/Cargo.toml
rename to app/gui/view/examples/documentation/Cargo.toml
diff --git a/app/gui/view/debug_scene/documentation/src/lib.rs b/app/gui/view/examples/documentation/src/lib.rs
similarity index 100%
rename from app/gui/view/debug_scene/documentation/src/lib.rs
rename to app/gui/view/examples/documentation/src/lib.rs
diff --git a/app/gui/view/debug_scene/icons/Cargo.toml b/app/gui/view/examples/icons/Cargo.toml
similarity index 100%
rename from app/gui/view/debug_scene/icons/Cargo.toml
rename to app/gui/view/examples/icons/Cargo.toml
diff --git a/app/gui/view/debug_scene/icons/src/lib.rs b/app/gui/view/examples/icons/src/lib.rs
similarity index 100%
rename from app/gui/view/debug_scene/icons/src/lib.rs
rename to app/gui/view/examples/icons/src/lib.rs
diff --git a/app/gui/view/debug_scene/interface/Cargo.toml b/app/gui/view/examples/interface/Cargo.toml
similarity index 100%
rename from app/gui/view/debug_scene/interface/Cargo.toml
rename to app/gui/view/examples/interface/Cargo.toml
diff --git a/app/gui/view/debug_scene/interface/src/lib.rs b/app/gui/view/examples/interface/src/lib.rs
similarity index 100%
rename from app/gui/view/debug_scene/interface/src/lib.rs
rename to app/gui/view/examples/interface/src/lib.rs
diff --git a/app/gui/view/debug_scene/src/lib.rs b/app/gui/view/examples/src/lib.rs
similarity index 100%
rename from app/gui/view/debug_scene/src/lib.rs
rename to app/gui/view/examples/src/lib.rs
diff --git a/app/gui/view/debug_scene/text-grid-visualization/Cargo.toml b/app/gui/view/examples/text-grid-visualization/Cargo.toml
similarity index 100%
rename from app/gui/view/debug_scene/text-grid-visualization/Cargo.toml
rename to app/gui/view/examples/text-grid-visualization/Cargo.toml
diff --git a/app/gui/view/debug_scene/text-grid-visualization/src/lib.rs b/app/gui/view/examples/text-grid-visualization/src/lib.rs
similarity index 100%
rename from app/gui/view/debug_scene/text-grid-visualization/src/lib.rs
rename to app/gui/view/examples/text-grid-visualization/src/lib.rs
diff --git a/app/gui/view/debug_scene/visualization/Cargo.toml b/app/gui/view/examples/visualization/Cargo.toml
similarity index 100%
rename from app/gui/view/debug_scene/visualization/Cargo.toml
rename to app/gui/view/examples/visualization/Cargo.toml
diff --git a/app/gui/view/debug_scene/visualization/src/lib.rs b/app/gui/view/examples/visualization/src/lib.rs
similarity index 100%
rename from app/gui/view/debug_scene/visualization/src/lib.rs
rename to app/gui/view/examples/visualization/src/lib.rs
diff --git a/app/gui/view/src/project.rs b/app/gui/view/src/project.rs
index afc30fb58319..775e8e9c9895 100644
--- a/app/gui/view/src/project.rs
+++ b/app/gui/view/src/project.rs
@@ -467,6 +467,7 @@ impl View {
};
let scene = app.display.default_scene.clone_ref();
+ scene.begin_shader_initialization();
let model = Model::new(app);
let frp = Frp::new();
let network = &frp.network;
diff --git a/build/intellij-run-config-gen/src/main.rs b/build/intellij-run-config-gen/src/main.rs
index ba174311698f..f642189b1b4e 100644
--- a/build/intellij-run-config-gen/src/main.rs
+++ b/build/intellij-run-config-gen/src/main.rs
@@ -83,7 +83,7 @@ const DIR_BLACK_LIST: &[&str] = &["target", "dist"];
const FOLDER_TO_HEADER_MAP: &[(&str, &str, usize)] = &[
("build/", "🚧 Build", 10),
("tools/", "🔨 Tools", 9),
- ("lib/rust/ensogl/example/", "🧸 Example", 4),
+ ("lib/rust/ensogl/examples/", "🧸 Example", 4),
("lib/rust/ensogl/", "🎨 EnsoGl", 6),
("lib/rust/ensogl", "🎨 EnsoGl", 0),
("lib/rust/parser/", "👓 Parser", 7),
diff --git a/lib/rust/ensogl/core/Cargo.toml b/lib/rust/ensogl/core/Cargo.toml
index 136f61c2a59e..b7fc1bd06932 100644
--- a/lib/rust/ensogl/core/Cargo.toml
+++ b/lib/rust/ensogl/core/Cargo.toml
@@ -31,6 +31,7 @@ bitflags = { version = "1.3.2" }
console_error_panic_hook = { workspace = true }
enum_dispatch = { version = "0.3.6" }
failure = { workspace = true }
+futures = { workspace = true }
Inflector = { version = "0.11.4" }
itertools = { workspace = true }
js-sys = { workspace = true }
diff --git a/lib/rust/ensogl/core/src/display/scene.rs b/lib/rust/ensogl/core/src/display/scene.rs
index 91cf84d9a8af..dd348fd205c2 100644
--- a/lib/rust/ensogl/core/src/display/scene.rs
+++ b/lib/rust/ensogl/core/src/display/scene.rs
@@ -716,6 +716,7 @@ pub struct SceneData {
pub frp: Frp,
pub pointer_position_changed: Rc>,
pub shader_compiler: shader::compiler::Controller,
+ initial_shader_compilation: Rc>,
display_mode: Rc>,
extensions: Extensions,
disable_context_menu: Rc,
@@ -766,6 +767,7 @@ impl SceneData {
let context_lost_handler = default();
let pointer_position_changed = default();
let shader_compiler = default();
+ let initial_shader_compilation = default();
Self {
display_object,
display_mode,
@@ -789,6 +791,7 @@ impl SceneData {
frp,
pointer_position_changed,
shader_compiler,
+ initial_shader_compilation,
extensions,
disable_context_menu,
}
@@ -1047,6 +1050,59 @@ impl Scene {
pub fn extension(&self) -> T {
self.extensions.get(self)
}
+
+ /// Begin any preparation necessary to render, e.g. compilation of shaders. Returns when the
+ /// scene is ready to start being displayed.
+ #[profile(Task)]
+ pub async fn prepare_to_render(&self) {
+ match self.initial_shader_compilation.get() {
+ TaskState::Unstarted => {
+ self.begin_shader_initialization();
+ self.next_shader_compiler_idle().await;
+ self.initial_shader_compilation.set(TaskState::Completed);
+ }
+ TaskState::Running => self.next_shader_compiler_idle().await,
+ TaskState::Completed => (),
+ }
+ }
+
+ /// Begin compiling shaders.
+ #[profile(Task)]
+ pub fn begin_shader_initialization(&self) {
+ if self.initial_shader_compilation.get() != TaskState::Unstarted {
+ return;
+ }
+ world::SHAPES_DEFINITIONS.with_borrow(|shapes| {
+ for shape in shapes.iter().filter(|shape| shape.is_main_application_shape()) {
+ // Instantiate shape so that its shader program will be submitted to the
+ // shader compiler. The runtime compiles the shaders in background threads,
+ // and starting early ensures they will be ready when we want to render
+ // them.
+ let _shape = (shape.cons)();
+ }
+ });
+ self.initial_shader_compilation.set(TaskState::Running);
+ }
+
+ /// Wait until the next time the compiler goes from busy to idle. If the compiler is already
+ /// idle, this will complete during the next shader-compiler run.
+ pub async fn next_shader_compiler_idle(&self) {
+ if let Some(context) = &*self.context.borrow() {
+ // Ensure the callback will be run if the queue is already idle.
+ context.shader_compiler.submit_probe_job();
+ } else {
+ return;
+ };
+ // Register a callback that triggers a future, and await it.
+ let (sender, receiver) = futures::channel::oneshot::channel();
+ let sender = Box::new(RefCell::new(Some(sender)));
+ let _handle = self.shader_compiler.on_idle(move || {
+ if let Some(sender) = sender.take() {
+ sender.send(()).unwrap();
+ }
+ });
+ receiver.await.unwrap();
+ }
}
impl system::gpu::context::Display for Scene {
@@ -1168,6 +1224,17 @@ impl<'t> DomPath for &'t str {
}
+// === Initial shader compilation state ===
+
+#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
+enum TaskState {
+ #[default]
+ Unstarted,
+ Running,
+ Completed,
+}
+
+
// ==================
// === Test Utils ===
diff --git a/lib/rust/ensogl/core/src/display/scene/layer.rs b/lib/rust/ensogl/core/src/display/scene/layer.rs
index b4a427ebd847..b054a732e4a8 100644
--- a/lib/rust/ensogl/core/src/display/scene/layer.rs
+++ b/lib/rust/ensogl/core/src/display/scene/layer.rs
@@ -19,7 +19,6 @@ use crate::display::symbol::SymbolId;
use enso_data_structures::dependency_graph::DependencyGraph;
use enso_shapely::shared;
use smallvec::alloc::collections::BTreeSet;
-use std::any::TypeId;
@@ -1143,8 +1142,8 @@ shared! { ShapeSystemRegistry
/// the same type on the same layer. Read the docs of [`ShapeProxy`] to learn more.
#[derive(Default,Debug)]
pub struct ShapeSystemRegistryData {
- shape_system_map : HashMap<(TypeId, ShapeSystemFlavor),ShapeSystemRegistryEntry>,
- shape_system_flavors: HashMap>,
+ shape_system_map : HashMap<(ShapeSystemId, ShapeSystemFlavor),ShapeSystemRegistryEntry>,
+ shape_system_flavors: HashMap>,
}
impl {
@@ -1184,7 +1183,7 @@ impl {
// Intentional short-circuit - avoid computing `total_system_instances` when we know there
// are still more instances in the currently processed entry.
- let no_more_instances = entry_is_empty && self.total_system_instances(*system_id) == 0;
+ let no_more_instances = entry_is_empty && self.total_system_instances(system_id) == 0;
(no_more_instances, system_id, PhantomData)
}
@@ -1198,7 +1197,7 @@ impl ShapeSystemRegistryData {
where
S: Shape,
{
- let id = TypeId::of::();
+ let id = ShapeSystemId::of::();
self.shape_system_map.get_mut(&(id, flavor)).and_then(|t| {
let shape_system = t.shape_system.downcast_mut::>();
let instance_count = &mut t.instance_count;
@@ -1217,7 +1216,7 @@ impl ShapeSystemRegistryData {
where
S: Shape,
{
- let id = TypeId::of::();
+ let id = ShapeSystemId::of::();
let flavor = S::flavor(data);
let system = ShapeSystem::::new(data);
let any = Box::new(system);
@@ -1229,7 +1228,7 @@ impl ShapeSystemRegistryData {
}
/// Get total number of shape instances from shape systems of given type and all flavors.
- fn total_system_instances(&self, system_id: TypeId) -> usize {
+ fn total_system_instances(&self, system_id: ShapeSystemId) -> usize {
let Some(flavors) = self.shape_system_flavors.get(&system_id) else { return 0 };
flavors.iter().map(|f| self.shape_system_map[&(system_id, *f)].instance_count).sum()
}
diff --git a/lib/rust/ensogl/core/src/display/shape/primitive/system.rs b/lib/rust/ensogl/core/src/display/shape/primitive/system.rs
index 47205d84f0a7..7e6c435e8350 100644
--- a/lib/rust/ensogl/core/src/display/shape/primitive/system.rs
+++ b/lib/rust/ensogl/core/src/display/shape/primitive/system.rs
@@ -82,9 +82,19 @@ use super::def;
// === ShapeSystemId ===
// =====================
-newtype_prim_no_default_no_display! {
- /// The ID of a user generated shape system.
- ShapeSystemId(std::any::TypeId);
+/// The ID of a user generated shape system.
+#[derive(Copy, Clone, CloneRef, Eq, Hash, Ord, PartialOrd, PartialEq, Debug)]
+pub struct ShapeSystemId {
+ type_id: std::any::TypeId,
+}
+
+impl ShapeSystemId {
+ /// Return an identifier unique to the given [`Shape`] type.
+ #[inline(always)]
+ pub fn of() -> Self {
+ let type_id = std::any::TypeId::of::();
+ Self { type_id }
+ }
}
@@ -249,8 +259,8 @@ pub struct ShapeSystemStandardData {
impl ShapeSystem {
/// The ID of this shape system.
- pub const fn id() -> ShapeSystemId {
- ShapeSystemId::new(std::any::TypeId::of::())
+ pub fn id() -> ShapeSystemId {
+ ShapeSystemId::of::()
}
/// Reference to the underlying sprite system.
@@ -445,8 +455,10 @@ impl ShapeSystemModel {
if let Some(shader) = crate::display::world::PRECOMPILED_SHADERS
.with_borrow(|map| map.get(*self.definition_path).cloned())
{
- let code = crate::display::shader::builder::CodeTemplate::new("", shader.fragment, "");
+ let code = crate::display::shader::builder::CodeTemplate::from_main(&shader.fragment);
self.material.borrow_mut().set_code(code);
+ let code = crate::display::shader::builder::CodeTemplate::from_main(&shader.vertex);
+ self.geometry_material.borrow_mut().set_code(code);
} else {
if !display::world::with_context(|t| t.run_mode.get().is_shader_extraction()) {
let path = *self.definition_path;
@@ -632,7 +644,7 @@ macro_rules! _shape_old {
// =============
/// The type of the shape. It also contains the parameters of the shape. The parameters
- /// are stored in this type in order to simplify bounds for utlities managing shape
+ /// are stored in this type in order to simplify bounds for utilities managing shape
/// systems. For example, if we would like to handle any shape with given parameters,
/// we will be processing [`ShapeSystem`] and we can add bounds to [`S`] to reflect
/// what parameters it should contain.
@@ -788,7 +800,7 @@ macro_rules! _shape {
// =============
/// The type of the shape. It also contains the parameters of the shape. The parameters
- /// are stored in this type in order to simplify bounds for utlities managing shape
+ /// are stored in this type in order to simplify bounds for utilities managing shape
/// systems. For example, if we would like to handle any shape with given parameters,
/// we will be processing [`ShapeSystem`] and we can add bounds to [`S`] to reflect
/// what parameters it should contain.
@@ -874,7 +886,14 @@ macro_rules! _shape {
#[before_main]
pub fn register_shape() {
$crate::display::world::SHAPES_DEFINITIONS.with(|shapes| {
- shapes.borrow_mut().push(Box::new(|| Box::new(View::new())));
+ let definition_path = Shape::definition_path();
+ let cons = Box::new(|| {
+ let view: Box =
+ Box::new(View::new());
+ view
+ });
+ let def = $crate::display::world::ShapeDefinition { definition_path, cons };
+ shapes.borrow_mut().push(def);
});
}
diff --git a/lib/rust/ensogl/core/src/display/symbol/gpu.rs b/lib/rust/ensogl/core/src/display/symbol/gpu.rs
index 06c8babf7a3f..7c68954af2af 100644
--- a/lib/rust/ensogl/core/src/display/symbol/gpu.rs
+++ b/lib/rust/ensogl/core/src/display/symbol/gpu.rs
@@ -409,15 +409,16 @@ impl Symbol {
&self,
global_variables: &UniformScope,
) -> Vec {
- let mut vars = self.shader.collect_variables();
- for binding in &mut vars {
- let scope = self.lookup_variable(&binding.name, global_variables);
- if scope.is_none() {
- warn!("Unable to bind variable '{}' to geometry buffer.", binding.name);
- }
- binding.scope = scope;
- }
- vars
+ self.shader
+ .collect_variables()
+ .map(|(name, decl)| {
+ let scope = self.lookup_variable(&name, global_variables);
+ if scope.is_none() {
+ warn!("Unable to bind variable '{name}' to geometry buffer.");
+ }
+ shader::VarBinding::new(name, decl, scope)
+ })
+ .collect()
}
/// Runs the provided function in a context of active program and active VAO. After the function
diff --git a/lib/rust/ensogl/core/src/display/symbol/gpu/shader.rs b/lib/rust/ensogl/core/src/display/symbol/gpu/shader.rs
index 04440ceb97c8..dfe4564a7401 100644
--- a/lib/rust/ensogl/core/src/display/symbol/gpu/shader.rs
+++ b/lib/rust/ensogl/core/src/display/symbol/gpu/shader.rs
@@ -62,7 +62,7 @@ pub struct ShaderData {
geometry_material : Material,
surface_material : Material,
program : Rc>>,
- shader_compiler_job : Option,
+ shader_compiler_job : Option,
dirty : Dirty,
stats : Stats,
profiler : Option,
@@ -122,9 +122,10 @@ impl {
/// Get the shader code in GLSL 310 format. The shader parameters will not be bound to any
/// particular mesh and thus this code can be used for optimization purposes only.
pub fn abstract_shader_code_in_glsl_310(&self) -> crate::system::gpu::shader::Code {
- let bindings = self.collect_variables().into_iter().map(|mut binding| {
- binding.scope = Some(ScopeType::Mesh(crate::display::symbol::geometry::primitive::mesh::ScopeType::Instance));
- binding
+ let bindings = self.collect_variables().map(|(name, decl)| {
+ let instance = crate::display::symbol::geometry::primitive::mesh::ScopeType::Instance;
+ let scope = Some(ScopeType::Mesh(instance));
+ VarBinding::new(name, decl, scope)
}).collect_vec();
self.gen_gpu_code(glsl::Version::V310, &bindings)
}
@@ -196,19 +197,19 @@ impl {
}
fn cancel_previous_shader_compiler_job_and_use_new_one
- (&mut self, handler: shader_compiler::JobHandler) {
+ (&mut self, handler: shader_compiler::JobHandle) {
// Dropping the previous handler.
self.shader_compiler_job = Some(handler);
}
/// Traverses the shader definition and collects all attribute names.
- pub fn collect_variables(&self) -> Vec {
- let mut out = vec![];
- let vars = self.geometry_material.inputs().iter().chain(self.surface_material.inputs());
- for (name,decl) in vars {
- out.push(VarBinding::new(name.clone(), decl.clone(), None));
- }
- out
+ pub fn collect_variables(&self) -> impl Iterator- {
+ let geometry_inputs = self.geometry_material.inputs().iter();
+ let surface_inputs = self.surface_material.inputs().iter();
+ geometry_inputs.chain(surface_inputs)
+ .map(|(name, declaration)| (name.clone(), declaration.clone()))
+ .collect_vec()
+ .into_iter()
}
}}
diff --git a/lib/rust/ensogl/core/src/display/symbol/gpu/shader/builder.rs b/lib/rust/ensogl/core/src/display/symbol/gpu/shader/builder.rs
index 2418d00a35db..21ac8e6c9158 100644
--- a/lib/rust/ensogl/core/src/display/symbol/gpu/shader/builder.rs
+++ b/lib/rust/ensogl/core/src/display/symbol/gpu/shader/builder.rs
@@ -512,15 +512,19 @@ impl ShaderBuilder {
}
}
+pub const INPUT_PREFIX: &str = "input_";
+pub const OUTPUT_PREFIX: &str = "output_";
+pub const VERTEX_PREFIX: &str = "vertex_";
+
pub fn mk_out_name(s: S) -> String {
- format!("output_{}", s.as_ref())
+ format!("{OUTPUT_PREFIX}{}", s.as_ref())
}
pub fn mk_vertex_name(s: S) -> String {
- format!("vertex_{}", s.as_ref())
+ format!("{VERTEX_PREFIX}{}", s.as_ref())
}
pub fn mk_fragment_name(s: S) -> String {
- format!("input_{}", s.as_ref())
+ format!("{INPUT_PREFIX}{}", s.as_ref())
}
pub fn mk_uniform_name(s: S) -> String {
- format!("input_{}", s.as_ref())
+ format!("{INPUT_PREFIX}{}", s.as_ref())
}
diff --git a/lib/rust/ensogl/core/src/display/world.rs b/lib/rust/ensogl/core/src/display/world.rs
index ffd097946a64..33ded1212d21 100644
--- a/lib/rust/ensogl/core/src/display/world.rs
+++ b/lib/rust/ensogl/core/src/display/world.rs
@@ -87,6 +87,25 @@ fn init_context() {
/// A constructor of view of some specific shape.
pub type ShapeCons = Box Box>;
+/// The definition of shapes created with the `shape!` macro.
+#[derive(Derivative)]
+#[derivative(Debug)]
+pub struct ShapeDefinition {
+ /// Location in the source code that the shape was defined.
+ pub definition_path: &'static str,
+ /// A constructor of single shape view.
+ #[derivative(Debug = "ignore")]
+ pub cons: ShapeCons,
+}
+
+impl ShapeDefinition {
+ /// Return `true` if it is possible that this shape is used by the main application.
+ pub fn is_main_application_shape(&self) -> bool {
+ // Shapes defined in `examples` directories are not used in the main application.
+ !self.definition_path.contains("/examples/")
+ }
+}
+
/// The definition of shapes created with the `cached_shape!` macro.
#[derive(Derivative)]
#[derivative(Debug)]
@@ -101,7 +120,7 @@ pub struct CachedShapeDefinition {
thread_local! {
/// All shapes defined with the `shape!` macro. They will be populated on the beginning of
/// program execution, before the `main` function is called.
- pub static SHAPES_DEFINITIONS: RefCell> = default();
+ pub static SHAPES_DEFINITIONS: RefCell> = default();
/// All shapes defined with the `cached_shape!` macro. They will be populated on the beginning
/// of program execution, before the `main` function is called.
@@ -116,12 +135,9 @@ thread_local! {
/// A precompiled shader definition. It contains the main function body for the vertex and fragment
/// shaders.
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, Deref)]
#[allow(missing_docs)]
-pub struct PrecompiledShader {
- pub vertex: String,
- pub fragment: String,
-}
+pub struct PrecompiledShader(shader::Code);
thread_local! {
/// List of all precompiled shaders. They are registered here before main entry point is run by
@@ -168,7 +184,8 @@ fn extract_shaders_from_js(value: JsValue) -> Result<(), JsValue> {
let fragment_field = web::Reflect::get(&value, &"fragment".into())?;
let vertex: String = vertex_field.dyn_into::()?.into();
let fragment: String = fragment_field.dyn_into::()?.into();
- let precompiled_shader = PrecompiledShader { vertex, fragment };
+ let vertex = strip_instance_declarations(&vertex);
+ let precompiled_shader = PrecompiledShader(shader::Code { vertex, fragment });
debug!("Registering precompiled shaders for '{key}'.");
PRECOMPILED_SHADERS.with_borrow_mut(move |map| {
map.insert(key, precompiled_shader);
@@ -177,12 +194,45 @@ fn extract_shaders_from_js(value: JsValue) -> Result<(), JsValue> {
Ok(())
}
+/// Remove initial instance variable declarations.
+///
+/// When pre-compiling vertex shaders we don't have full information about inputs, and instead treat
+/// all inputs as instance variables. After the program has been optimized, we need to strip these
+/// imprecise declarations so they don't conflict with the real declarations we add when building
+/// the shader.
+fn strip_instance_declarations(input: &str) -> String {
+ let mut code = String::with_capacity(input.len());
+ let mut preamble_ended = false;
+ let input_prefix = display::symbol::gpu::shader::builder::INPUT_PREFIX;
+ let vertex_prefix = display::symbol::gpu::shader::builder::VERTEX_PREFIX;
+ for line in input.lines() {
+ // Skip lines as long as they match the `input_foo = vertex_foo` pattern.
+ if !preamble_ended {
+ let trimmed = line.trim_start();
+ if trimmed.is_empty() {
+ continue;
+ }
+ let mut parts = trimmed.split(' ');
+ if let Some(part) = parts.next() && part.starts_with(input_prefix)
+ && let Some(part) = parts.next() && part == "="
+ && let Some(part) = parts.next() && part.starts_with(vertex_prefix)
+ && let None = parts.next() {
+ continue;
+ }
+ }
+ preamble_ended = true;
+ code.push_str(line);
+ code.push('\n');
+ }
+ code
+}
+
fn gather_shaders() -> HashMap<&'static str, shader::Code> {
with_context(|t| t.run_mode.set(RunMode::ShaderExtraction));
let mut map = HashMap::new();
SHAPES_DEFINITIONS.with(|shapes| {
- for shape_cons in shapes.borrow().iter() {
- let shape = shape_cons();
+ for shape in shapes.borrow().iter() {
+ let shape = (shape.cons)();
let path = shape.definition_path();
let code = shape.abstract_shader_code_in_glsl_310();
map.insert(path, code);
@@ -272,6 +322,7 @@ impl<'t> From<&'t World> for &'t Scene {
}
+
// ===========
// === FRP ===
// ===========
@@ -283,6 +334,7 @@ crate::define_endpoints_2! {
}
+
// =========================
// === WorldDataWithLoop ===
// =========================
diff --git a/lib/rust/ensogl/core/src/gui/component.rs b/lib/rust/ensogl/core/src/gui/component.rs
index 5aff02adce3f..5abfd5583ebf 100644
--- a/lib/rust/ensogl/core/src/gui/component.rs
+++ b/lib/rust/ensogl/core/src/gui/component.rs
@@ -168,8 +168,6 @@ impl ShapeViewModel
{
self.add_to_scene_layer(scene, &layer)
}
} else {
- // Bug in clippy: https://github.com/rust-lang/rust-clippy/issues/9763
- #[allow(clippy::explicit_auto_deref)]
let (shape, _) = scene.layers.DETACHED.instantiate(&*self.data.borrow());
self.shape.swap(&shape);
}
@@ -189,8 +187,6 @@ impl ShapeViewModel {
}
impl ShapeViewModel {
- // Clippy error: https://github.com/rust-lang/rust-clippy/issues/9763
- #[allow(clippy::explicit_auto_deref)]
fn add_to_scene_layer(&self, scene: &Scene, layer: &scene::Layer) {
let (shape, instance) = layer.instantiate(&*self.data.borrow());
scene.pointer_target_registry.insert(instance.global_instance_id, self.events.clone_ref());
@@ -200,8 +196,6 @@ impl ShapeViewModel {
}
impl ShapeViewModel {
- // Clippy error: https://github.com/rust-lang/rust-clippy/issues/9763
- #[allow(clippy::explicit_auto_deref)]
fn unregister_existing_mouse_targets(&self) {
for global_instance_id in mem::take(&mut *self.pointer_targets.borrow_mut()) {
scene().pointer_target_registry.remove(global_instance_id);
@@ -234,8 +228,8 @@ impl display::Object for ShapeView {
struct WidgetData {
app: Application,
display_object: display::object::Instance,
- frp: std::mem::ManuallyDrop,
- model: std::mem::ManuallyDrop>,
+ frp: mem::ManuallyDrop,
+ model: mem::ManuallyDrop>,
}
impl WidgetData {
@@ -248,8 +242,8 @@ impl WidgetData {
Self {
app: app.clone_ref(),
display_object,
- frp: std::mem::ManuallyDrop::new(frp),
- model: std::mem::ManuallyDrop::new(model),
+ frp: mem::ManuallyDrop::new(frp),
+ model: mem::ManuallyDrop::new(model),
}
}
}
@@ -261,8 +255,8 @@ impl Drop for WidgetData {
// This is clearly the case, because the structure will be soon dropped anyway.
#[allow(unsafe_code)]
unsafe {
- let frp = std::mem::ManuallyDrop::take(&mut self.frp);
- let model = std::mem::ManuallyDrop::take(&mut self.model);
+ let frp = mem::ManuallyDrop::take(&mut self.frp);
+ let model = mem::ManuallyDrop::take(&mut self.model);
self.app.display.collect_garbage(frp);
self.app.display.collect_garbage(model);
}
diff --git a/lib/rust/ensogl/core/src/system/gpu/context/extension.rs b/lib/rust/ensogl/core/src/system/gpu/context/extension.rs
index 99afed4981c7..87f733caab78 100644
--- a/lib/rust/ensogl/core/src/system/gpu/context/extension.rs
+++ b/lib/rust/ensogl/core/src/system/gpu/context/extension.rs
@@ -6,6 +6,7 @@ use crate::system::gpu::data::GlEnum;
use web_sys::WebGl2RenderingContext;
use web_sys::WebGlProgram;
+use web_sys::WebGlShader;
@@ -68,11 +69,21 @@ impl KhrParallelShaderCompile {
/// Asynchronously check if the job is ready. Returns [`None`] if it was impossible to get this
/// information. This can happen during context loss or driver failure.
- pub fn is_ready(
+ pub fn is_program_ready(
&self,
context: &WebGl2RenderingContext,
program: &WebGlProgram,
) -> Option {
context.get_program_parameter(program, *self.completion_status_khr).as_bool()
}
+
+ /// Asynchronously check if the job is ready. Returns [`None`] if it was impossible to get this
+ /// information. This can happen during context loss or driver failure.
+ pub fn is_shader_ready(
+ &self,
+ context: &WebGl2RenderingContext,
+ program: &WebGlShader,
+ ) -> Option {
+ context.get_shader_parameter(program, *self.completion_status_khr).as_bool()
+ }
}
diff --git a/lib/rust/ensogl/core/src/system/gpu/data/buffer.rs b/lib/rust/ensogl/core/src/system/gpu/data/buffer.rs
index a0a8d2b83d46..5318d0dbcd93 100644
--- a/lib/rust/ensogl/core/src/system/gpu/data/buffer.rs
+++ b/lib/rust/ensogl/core/src/system/gpu/data/buffer.rs
@@ -280,7 +280,7 @@ impl BufferData {
/// Upload the provided data range to the GPU buffer. In case the local buffer was resized,
/// it will be re-created on the GPU.
fn upload_data(&mut self, opt_range: &Option>) {
- info_span!("Uploading buffer data.").in_scope(|| {
+ debug_span!("Uploading buffer data.").in_scope(|| {
self.stats.inc_data_upload_count();
match opt_range {
None => self.replace_gpu_buffer(),
diff --git a/lib/rust/ensogl/core/src/system/gpu/shader.rs b/lib/rust/ensogl/core/src/system/gpu/shader.rs
index 76a937702c17..4d05c1b63fc0 100644
--- a/lib/rust/ensogl/core/src/system/gpu/shader.rs
+++ b/lib/rust/ensogl/core/src/system/gpu/shader.rs
@@ -60,7 +60,7 @@ impl ToGlEnum for Type {
/// Abstractions for shader sources (vertex and fragment one).
#[allow(missing_docs)]
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct Sources {
pub vertex: Vertex,
pub fragment: Fragment,
@@ -72,6 +72,38 @@ pub type Code = Sources;
/// Shader sources as compiled shaders that are not linked yet.
pub type CompiledCode = Sources, Shader>;
+impl Sources {
+ /// Apply [`Into::into`] to the [`vertex`] and [`fragment`] elements and return the result.
+ pub fn into(self) -> Sources
+ where
+ V: Into,
+ F: Into, {
+ let Sources { vertex, fragment } = self;
+ let vertex = vertex.into();
+ let fragment = fragment.into();
+ Sources { vertex, fragment }
+ }
+
+ /// Return references to the [`vertex`] and [`fragment`] elements.
+ pub fn as_ref(&self) -> Sources<&V, &F> {
+ let Sources { vertex, fragment } = self;
+ let vertex = &vertex;
+ let fragment = &fragment;
+ Sources { vertex, fragment }
+ }
+}
+
+impl Sources {
+ /// Apply a function to the [`vertex`] and [`fragment`] elements and return the result.
+ pub fn map(self, f: F) -> Sources
+ where F: Fn(VF) -> VF1 {
+ let Sources { vertex, fragment } = self;
+ let vertex = f(vertex);
+ let fragment = f(fragment);
+ Sources { vertex, fragment }
+ }
+}
+
// ==============
diff --git a/lib/rust/ensogl/core/src/system/gpu/shader/compiler.rs b/lib/rust/ensogl/core/src/system/gpu/shader/compiler.rs
index acc0c6cd36d2..7a40613d7070 100644
--- a/lib/rust/ensogl/core/src/system/gpu/shader/compiler.rs
+++ b/lib/rust/ensogl/core/src/system/gpu/shader/compiler.rs
@@ -67,7 +67,7 @@ const FRAME_TIME_THRESHOLD: Duration = (1000.0 / FPS_THRESHOLD).ms();
/// a crude form of backpressure by blocking until all pending jobs complete. We are not sure if it
/// is a feature or a bug. To learn more about our findings so far, see:
/// https://github.com/enso-org/enso/pull/3378#issuecomment-1090958946
-const MAX_PARALLEL_COMPILE_JOBS: usize = 2;
+const MAX_PARALLEL_COMPILE_JOBS: usize = 16;
@@ -76,16 +76,17 @@ const MAX_PARALLEL_COMPILE_JOBS: usize = 2;
// ===========
/// Compiler job. After the job is created it can be either transformed to another job, or, in case
-/// that was the final job, the [`handler`] callback will be called. See the documentation of the
+/// that was the final job, the [`on_ready`] callback will be called. See the documentation of the
/// [`Compiler`] to learn more.
#[derive(Derivative, Deref)]
#[derivative(Debug)]
pub struct Job {
#[derivative(Debug = "ignore")]
- on_ready: Box,
+ on_ready: Option>,
#[deref]
input: T,
- handler: WeakJobHandler,
+ /// A cancellation handle. If none is present, the job cannot be cancelled.
+ handle: Option,
/// A key used to cache the compiled program that this job is making progress on. When the job
/// is finished or failed, the program or failure status is stored in the cache under this key.
cache_key: ShaderCacheKey,
@@ -95,42 +96,47 @@ pub struct Job {
impl Job {
fn map_input(self, f: impl FnOnce(T) -> S) -> Job {
let on_ready = self.on_ready;
- let handler = self.handler;
+ let handle = self.handle;
let input = f(self.input);
let profiler = self.profiler;
let cache_key = self.cache_key;
- Job { on_ready, input, handler, profiler, cache_key }
+ Job { on_ready, input, handle, profiler, cache_key }
+ }
+
+ /// Return whether the job has been cancelled (by its handle being dropped).
+ fn is_cancelled(&self) -> bool {
+ self.handle.as_ref().map(|handle| !handle.exists()).unwrap_or_default()
}
}
-/// A handler to a job. After the handler is dropped, the job is invalidated and will no longer be
+/// A handle to a job. After the handle is dropped, the job is invalidated and will no longer be
/// scheduled for evaluation.
#[derive(Debug, Clone, CloneRef)]
-pub struct JobHandler {
+pub struct JobHandle {
rc: Rc<()>,
}
-/// A weak version of [`JobHandler`].
+/// A weak version of [`JobHandle`].
#[derive(Debug, Clone, CloneRef)]
-pub struct WeakJobHandler {
+pub struct WeakJobHandle {
weak: Weak<()>,
}
-impl JobHandler {
+impl JobHandle {
/// Constructor.
fn new() -> Self {
Self { rc: default() }
}
- /// Get weak reference to this handler.
- pub fn downgrade(&self) -> WeakJobHandler {
+ /// Get weak reference to this handle.
+ pub fn downgrade(&self) -> WeakJobHandle {
let weak = Rc::downgrade(&self.rc);
- WeakJobHandler { weak }
+ WeakJobHandle { weak }
}
}
-impl WeakJobHandler {
- /// Check whether the handler was dropped.
+impl WeakJobHandle {
+ /// Check whether the handle was dropped.
pub fn exists(&self) -> bool {
self.weak.strong_count() > 0
}
@@ -138,16 +144,16 @@ impl WeakJobHandler {
-// ==================
-// === KhrProgram ===
-// ==================
+// ===============
+// === WithKhr ===
+// ===============
/// A program together with the [`KhrParallelShaderCompile`] extension. Used as one of the
/// [`Compiler`] jobs to provide nice API.
#[derive(Debug)]
-struct KhrProgram {
+struct WithKhr {
khr: KhrParallelShaderCompile,
- program: shader::Program,
+ program: T,
}
@@ -173,16 +179,17 @@ pub enum Progress {
/// Compiler job queues. See the documentation of [`Compiler`] to learn more.
#[derive(Debug, Default)]
pub struct Jobs {
- compile: Vec>,
- link: Vec>,
- read_cache: Vec>,
- khr_completion_check: Vec>,
- link_check: Vec>,
+ compile: Vec, Option>>>,
+ compile_poll: Vec>>,
+ compile_check: Vec>,
+ link: Vec>,
+ link_poll: Vec>>,
+ link_check: Vec>,
}
/// Compiles and links GL shader programs, asynchronously. The compiler works in the following way:
/// 1. A new shader code is submitted with the [`submit`] method. A new job is created in the
-/// [`Jobs::compile`] queue and the job handler is returned to the user.
+/// [`Jobs::compile`] queue and the job handle is returned to the user.
///
/// 2. The following pseudo-algorithm is performed:
/// ```text
@@ -214,6 +221,7 @@ struct CompilerData {
jobs: Jobs,
cache: ShaderCache,
performance: web::Performance,
+ callbacks: Vec,
}
impl Compiler {
@@ -222,14 +230,32 @@ impl Compiler {
Self { cell: RefCell::new(CompilerData::new(context)) }
}
- /// Submit shader for compilation.
- pub fn submit(
+ /// Submit shader for compilation. The job will be cancelled if the returned handle is dropped.
+ #[must_use]
+ pub fn submit(
&self,
input: shader::Code,
profiler: profiler::Debug,
on_ready: F,
- ) -> JobHandler {
- self.cell.borrow_mut().submit(input, profiler, on_ready)
+ ) -> JobHandle {
+ let strong_handle = JobHandle::new();
+ let handle = strong_handle.downgrade();
+ let on_ready: Box = Box::new(on_ready);
+ self.cell.borrow_mut().submit(input.into(), profiler, on_ready.into(), handle.into());
+ strong_handle
+ }
+
+ /// Submit a shader for compilation, without awaiting its completion.
+ pub fn submit_background_job(&self, input: shader::Sources | | |