Use a new algorithm for placement of new nodes in cases when:
- a) there is no selected node, and the `TAB` key is pressed while the mouse pointer is near an existing node (especially in an area below an existing node);
- b) a connection is dragged out from an existing node and dropped near the node (especially in an area below the node).
In both cases mentioned above, the new node will now be placed in a location suggested by an internal algorithm, aligned to existing nodes. Specifically, the placement algorithm used is similar to when pressing `TAB` with a node selected.
For more details, see: https://www.pivotaltracker.com/story/show/181076066
# Important Notes
- Visible visualizations enabled with the "eye icon" button are treated as part of a node. (In case of nodes with errors, visualizations are not visible, and are not treated as part of a node.)
[ci no changelog needed]
This PR adds a few simple unit tests for GraphEditor, that can be used as an example of native Unit Tests.
Covered:
1. Creating nodes
- By internal API
- By using a TAB shortcut
- By using (+) button
- By dropping edge
2. Connecting two nodes with an edge
Some APIs were extended to allow their testing.
Usage of `glyph::System` in `text/component/area` was disabled by conditional compilation, as this code can't be used in native code due to JS dependencies.
* Profiling application details
Add enough profiling to account for every missed frame during startup.
See https://www.pivotaltracker.com/story/show/181499507
* Build ActiveInterval hierarchy in profiler_data
* update doctests / await_!
* docs/formatting/naming
* more graph modes
* increase WASM size
Due to new render-profile-flamegraph scene. We should remove these from the main release WASM blob one way or another.
* lint
* fix a test
* Organization (feedback)
* Add @wdanilo to Cargo.lock CODEOWNERS
As discussed after my previous PR got stuck waiting for Cargo.lock review.
* fix doctests
* Update docs. Removed a limitation.
@akavel spotted a compilation error, when building test for graph_editor crate. The cause was that:
* prelude without serde still added serde derivatives in im_string_newtype
* and the graph_editor needs serde from prelude anyway (because it wants to have serializable ImStrings).
In this PR two things are implemented:
1. Node Searcher zoom factor (and therefore its size) is fixed no matter how you move the main camera. The node searcher is also positioned directly below currently edited node at all times.
2. Node growth/shrink animation when you start/finish node editing. After animation end the edited node zoom factor is also fixed and matches the zoom factor of the node searcher.
See attached video with different ways of editing/creating nodes:
https://user-images.githubusercontent.com/6566674/157348758-2880aa2b-494d-46e6-8eee-a22be84081ed.mp4
#### Technical details
1. Added several additional scene layers for separate rendering: `node_searcher`, `node_searcher_text`, `edited_node`, `edited_node_text`. Searcher is always rendered by `node_searcher` camera, edited node moves between its usual layers and `edited_node` layer. Because text rendering uses different API, all node components were modified to support change of the layer.
2. Also added `node_searcher` DOM layer, because documentation is implemented as a DOM object.
3. Added two FRP endpoints for `ensogl::Animation`: `on_end` and `set_value`. These endpoints are useful while implementing growth/shrink animation.
4. Added FRP endpoints for the `Camera2d`: `position` and `zoom` outputs. This allows to synchronize cameras easily using FRP networks.
5. Growth/shrink animation implemented in GraphEditor by blending two animations, similar to Node Snapping implementation. However, shrinking animation is a bit tricky to implement correctly, as we must always return node back to the `main` scene layer after editing is done.
* Creating a new node with the (+) button (#3278)
[The Task](https://www.pivotaltracker.com/story/show/180887253)
A new (+) button on the left-bottom corner appeared. It may be clicked to open searcher in the middle of the scene, as an alternative to tab key.
https://user-images.githubusercontent.com/3919101/154514279-7972ed6a-0203-47cb-9a09-82dba948cf2f.mp4
* The window_control_buttons::common was extracted to separate crate `ensogl-component-button` almost without change.
* This includes a severe refactoring of adding nodes in general in the Graph Editor. The whole responsibility of adding new nodes (and starting their editing) was moved to Graph Editor - the Project View only reacts for GE events to show searcher properly.
* The status bar was moved from the bottom-left corner to the middle-top of the scene. It does not collide with (+) button, and plays "notification" role anyway.
* The `interface` debug scene was buggy. The problem was with one expression's span-tree. When I replaced it, the scene works.
* I've removed "new searcher" API, as it is completely outdated.
* I've changed code owners of integration tests to GUI team, as it is the team writing mostly the integration tests (int rust)
* Fix regression #181528359
* Add docs & remove unused function
* Fix & enable native Rust tests
* Fix formatting
Co-authored-by: Adam Obuchowicz <adam.obuchowicz@enso.org>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
[ci no changelog needed]
This PR reverts commit [0836ce741d](0836ce741d) because of the spotted regression:
To reproduce:
1. Open a default project.
2. Without doing anything else, cmd + click on any node to edit it.
3. Abort editing by pressing escape.
4. Top-most node disappears (it is actually removed from scene)
If you start editing the bottom node - you will also see a visible regression in node searcher's position.
See thread https://discord.com/channels/401396655599124480/950730235719065620/950731247909478410 for details.
Add an API to create a flame graph from profiling data. Also adds a demo scene showcasing the functionality that generates some profiling data by measuring dummy function calls and rendering a flame graph for the dummy data (see video for the result).
Not that the functionality is not yet exposed user-facing in the GUI itself, but only as API and demo scene, therefore [ci no changelog needed]
https://user-images.githubusercontent.com/1428930/155118977-ecac0628-777c-48bd-9aa7-30ee6aef1976.mp4
# Important Notes
* Change from the initial design: labels are shown on the flame graph instead of as a tooltip. This is because tooltips are currently only implemented in the graph editor and would require some additional refactoring (probably taking the better part of a day).
* re-instated the behaviour that logs are shown in the JS console if development mode is active.
API for storing metadata.
See: https://www.pivotaltracker.com/story/show/181149277
# Important Notes
**New APIs**:
- Storing metadata is implemented with `profiler::MetadataLogger`.
- A full metadata storage/retrieval example is in [the top-level doctests](https://github.com/enso-org/enso/blob/wip/kw/profiling-metadata-api/lib/rust/profiler/data/src/lib.rs) for profiler::data, a crate which implements an API for profiling data consumers (it abstracts away the low-level details of the event log, and checks its invariants in the process) [after review of this new API here I'll open a PR to add it to the design doc].
**Implementation**:
- `profiler::Event` is parameterized by a metadata type, so that different types of metadata can be dependency-injected into it.
- A data consumer defines its metadata type as an enum of all the kinds of metadata it is interested in.
- Producing the metadata enum is accomplished without defining its type (which would require dependencies from around the app): A `MetadataLogger` internally use a serialization helper `Variant` to serialize its variant of the metadata enum without knowledge of the other possible variants.
**Performance impact**: still in the low ns/measurement range, comparable to pushing to a vec.
*Note*: `LocalVecBuilder` is currently present under the name `Log`, which is accurate but probably too overloaded. I'd like to find the right name for it, document it with examples, and move it to its own crate under data-structures, but I don't want doing that to hold up this PR.
[The Task](https://www.pivotaltracker.com/story/show/180887253)
A new (+) button on the left-bottom corner appeared. It may be clicked to open searcher in the middle of the scene, as an alternative to tab key.
https://user-images.githubusercontent.com/3919101/154514279-7972ed6a-0203-47cb-9a09-82dba948cf2f.mp4
# Important Notes
* The window_control_buttons::common was extracted to separate crate `ensogl-component-button` almost without change.
* This includes a severe refactoring of adding nodes in general in the Graph Editor. The whole responsibility of adding new nodes (and starting their editing) was moved to Graph Editor - the Project View only reacts for GE events to show searcher properly.
* The status bar was moved from the bottom-left corner to the middle-top of the scene. It does not collide with (+) button, and plays "notification" role anyway.
* The `interface` debug scene was buggy. The problem was with one expression's span-tree. When I replaced it, the scene works.
* I've removed "new searcher" API, as it is completely outdated.
* I've changed code owners of integration tests to GUI team, as it is the team writing mostly the integration tests (int rust)
[Task link](#181181203).
This is a reincarnation of PR [3273](https://github.com/enso-org/enso/pull/3273).
The maximum zoom factor of Graph Editor is limited to 1.0x. It is not possible to zoom in from the default camera position.
Debug Mode (activated with `ctrl-shift-d` shortcut) allows to zoom up to 100.0x (the previous behavior of Graph Editor).
If you enable Debug Mode, then zoom in and disable Debug Mode - you won't see the immediate change of zoom factor back to 1.0x. But it will "jump" (with animation) back once you make a zoom in/out event with your controls.
Video:
https://user-images.githubusercontent.com/6566674/154037310-1d166737-353e-4ae6-aca1-f7840571ab16.mp4
# Important Notes
This is a reincarnation of PR [3273](https://github.com/enso-org/enso/pull/3273). There are two changes since that PR:
1. Fixed bug with GeoMap zooming described [here](https://github.com/enso-org/enso/pull/3290). This is done by restricting `ZoomEvent` API so that it will never contain `amount` which is equal to `0.0`.
2. A few refactoring changes from https://github.com/enso-org/enso/pull/3289 to simplify code a bit.
This change makes EnsoGL runtime stats be always collected, even when EnsoGL `Monitor` panel is not visible. Those stats are intended to be used in the future by a profiling framework.
**Performance impact:** Continuous collection of stats introduces an overhead of two Web Performance API `now()` calls in each frame of the main rendering loop, plus a small number of simple arithmetic calculations. This is assumed to be a negligible and acceptable overhead.
#### Visuals
A screenshot of the Monitor panel in full `ide` after applying the PR, taken in IDE built with `./run dist`:
<img width="991" alt="Screenshot 2022-02-14 at 16 11 42" src="https://user-images.githubusercontent.com/273837/153891378-8a2fb333-34ce-46ce-99df-7d796817310c.png">
A recording, also in IDE built with `./run dist`; note that FPS is impacted by the act of recording itself:
https://user-images.githubusercontent.com/273837/154104016-49a12e23-1210-4477-9743-ec1611e5b4ed.movhttps://www.pivotaltracker.com/story/show/181093601
# Important Notes
- Responsibility for controlling how `Stats` gathering and calculation is performed at various points in the main rendering loop was removed from `Monitor` - the `Monitor`'s purpose is only to display existing data, it should not influence how the data is collected.
- Two previously existing distinct `Monitor` structs were merged into one, to avoid confusion; after previous refactorings, the remaining `stats::Monitor` did not have much useful code anyway.
- In `stats` package, refactoring was done, to make `StatsData` a "dumb", data-only type, and to move the logic related to stats collection and frame tracking to other helper types.
[ci no changelog needed]
Fix the `scroll-area` example scene, so that a red circle inside the scroll area, and a gray rounded rectangle representing the background of the scroll area, are now both visible.
Previously, adding just a `Sprite` (instead of a corresponding `SpriteSystem`) to the scene resulted in the underlying `Symbol` not being added to a visible `Layer`. (Notably, `Sprite::display_object()` is not the same as `Sprite::symbol.display_object()`.)
https://www.pivotaltracker.com/story/show/180459079
This reverts commit e69e8078c3.
The removed code (stats aggregation and `stats` demo scene) will not be needed by the profiling framework, as discussed on chat.
(reverts changes introduced as part of https://www.pivotaltracker.com/story/show/181093920)
* profiling instrumentation
* Support native testing with mock impl of `mod js`
* Add benchmarks
* Wrapper: support methods.
* `#[profile]`: work in any context
* feature-gate lineno info that breaks IDE
* Support async; more docs; add perf analysis
* docs & formatting
This change adds utility code for calculating summaries from multiple samples (snapshots) of EnsoGL runtime stats values.
This internal feature is expected to be used by Enso IDE performance profiling tools, which are planned to be added in the near future.
https://www.pivotaltracker.com/story/show/181093920
A demo scene named `stats` was added, showcasing how to perform calculations using the new tools. Currently, the summary calculations in the scene work only when the EnsoGL stats Monitor Panel is visible; this is planned to be improved in a future task (https://www.pivotaltracker.com/story/show/181093601).
- Note: the stats aggregation code is intended to be later used in Enso IDE's main rendering loop, so it needs to have very good performance characteristics.
- Due to that, `Accumulator` was designed to only use simple addition arithmetic, and be constant-memory once created.
Fix EnsoGL runtime statistics collection and processing, so that all values in a single vertical slice of the Monitor Panel graph (accessible through `control-option-tilde` shortcut) represent stats for the same animation/rendering frame.
Before the change, for any vertical slice of the graph, the FPS value was shown for the previous (`i - 1`) rendering frame, whereas the other values were shown for the current (`i`) rendering frame.
The alignment of the stats will become even more important in the future, when the values will be included in more detailed profiling reports, which is planned.
The GUI that is impacted (if in a subtle way) by the changed code is the performance monitor panel, accessible with a `ctrl-option-tilde` keyboard shortcut in the IDE.
https://www.pivotaltracker.com/story/show/181140499
The goal of this change is to decouple the code calculating EnsoGL runtime stats (notably, FPS, frame time, and WASM memory usage) from `Sampler` trait implementations (this trait is intended only to be responsible for post-processing stats data for display/view purposes).
Apart from the general improvement in separation of responsibilities, a longer-term goal for this change is to make it possible to access all the stats in any code that doesn't need the `Sampler` functionalities (expected to be needed for https://www.pivotaltracker.com/story/show/181093832 and https://www.pivotaltracker.com/story/show/181093601).
The main loop's code is performance-critical, and this has implications
on tasks design and planning. Knowing this earlier would help me avoid
some major workflow inefficiencies while working on tasks touching this
code.
The old JS-based Welcome Screen was removed and replaced with the Rusty one.
Co-authored-by: Adam Obuchowicz <adam.obuchowicz@enso.org>
Co-authored-by: Adam Obuchowicz <adam.obuchowicz@luna-lang.org>