Skip to content

Commit

Permalink
Ability to change the execution environment between design and live. (#…
Browse files Browse the repository at this point in the history
…6341)

Integrate the UI for electing the Execution Environment with the Language Server and unify existing uses. Implements  #5930 + actual integration instead of just mocking it.

https://user-images.githubusercontent.com/1428930/232919438-6e1e295a-34fe-4756-86a4-5f5d8f718fa0.mp4

# Important Notes
The console output is only emitted as part of the `INFO` level. A better check would be to look at the messages sent to the backend in the developer console.
  • Loading branch information
MichaelMauderer authored Apr 25, 2023
1 parent 115e9b4 commit 0d84a60
Show file tree
Hide file tree
Showing 30 changed files with 605 additions and 252 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@
quickly understand each button's function.
- [File associations are created on Windows and macOS][6077]. This allows
opening Enso files by double-clicking them in the file explorer.
- [The IDE UI element for selecting the execution mode of the project is now
sending messages to the backend.][6341].

#### EnsoGL (rendering engine)

Expand Down Expand Up @@ -194,6 +196,7 @@
[5895]: https://github.com/enso-org/enso/pull/6130
[6035]: https://github.com/enso-org/enso/pull/6035
[6097]: https://github.com/enso-org/enso/pull/6097
[6097]: https://github.com/enso-org/enso/pull/6341

#### Enso Standard Library

Expand Down
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion app/gui/controller/engine-protocol/src/language_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ trait API {

/// Restart the program execution.
#[MethodInput=RecomputeInput, rpc_name="executionContext/recompute"]
fn recompute(&self, context_id: ContextId, invalidated_expressions: InvalidatedExpressions) -> ();
fn recompute(&self, context_id: ContextId, invalidated_expressions: InvalidatedExpressions, mode: Option<ExecutionEnvironment>) -> ();

/// Obtain the full suggestions database.
#[MethodInput=GetSuggestionsDatabaseInput, rpc_name="search/getSuggestionsDatabase"]
Expand Down Expand Up @@ -205,6 +205,11 @@ trait API {
/// VCS snapshot if no `commit_id` is provided.
#[MethodInput=VcsRestoreInput, rpc_name="vcs/restore"]
fn restore_vcs(&self, root: Path, commit_id: Option<String>) -> response::RestoreVcs;

/// Set the execution environment of the context for future evaluations.
#[MethodInput=SetModeInput, rpc_name="executionContext/setExecutionEnvironment"]
fn set_execution_environment(&self, context_id: ContextId, execution_environment: ExecutionEnvironment) -> ();

}}


Expand Down
66 changes: 66 additions & 0 deletions app/gui/controller/engine-protocol/src/language_server/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,72 @@ pub struct LibraryComponentGroup {
}



// =============================
// === Execution Environment ===
// =============================

/// The execution environment which controls the global execution of functions with side effects.
///
/// For more information, see
/// https://github.com/enso-org/design/blob/main/epics/basic-libraries/write-action-control/design.md.
#[derive(Hash, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Display)]
pub enum ExecutionEnvironment {
/// Allows editing the graph, but the `Output` context is disabled, so it prevents accidental
/// changes.
Design,
/// Unrestricted, live editing of data.
Live,
}

impl Default for ExecutionEnvironment {
fn default() -> Self {
ExecutionEnvironment::Design
}
}

impl ExecutionEnvironment {
/// List all available execution environments.
pub fn list_all() -> Vec<Self> {
vec![ExecutionEnvironment::Design, ExecutionEnvironment::Live]
}

/// List all available execution environments as ImStrings. Useful for UI.
pub fn list_all_as_imstrings() -> Vec<ImString> {
Self::list_all().iter().map(|env| (*env).into()).collect()
}
}

impl From<ExecutionEnvironment> for ImString {
fn from(env: ExecutionEnvironment) -> Self {
ImString::new(env.to_string())
}
}

impl TryFrom<&str> for ExecutionEnvironment {
type Error = ();

fn try_from(value: &str) -> core::result::Result<Self, Self::Error> {
match value.to_lowercase().as_str() {
"design" => Ok(ExecutionEnvironment::Design),
"live" => Ok(ExecutionEnvironment::Live),
_ => Err(()),
}
}
}

impl ExecutionEnvironment {
/// Returns whether the output context is enabled for this execution environment.
pub fn output_context_enabled(&self) -> bool {
match self {
Self::Design => false,
Self::Live => true,
}
}
}



// ======================
// === Test Utilities ===
// ======================
Expand Down
1 change: 1 addition & 0 deletions app/gui/docs/product/shortcuts.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ broken and require further investigation.
| <kbd>escape</kbd> | Cancel current action. For example, drop currently dragged connection. |
| <kbd>cmd</kbd>+<kbd>shift</kbd>+<kbd>t</kbd> | Terminate the program execution |
| <kbd>cmd</kbd>+<kbd>shift</kbd>+<kbd>r</kbd> | Re-execute the program |
| <kbd>cmd</kbd>+<kbd>shift</kbd>+<kbd>e</kbd> | Toggle the execution environment between Live and Design. |

#### Navigation

Expand Down
10 changes: 10 additions & 0 deletions app/gui/src/controller/graph/executed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::model::execution_context::VisualizationId;
use crate::model::execution_context::VisualizationUpdateData;

use double_representation::name::QualifiedName;
use engine_protocol::language_server::ExecutionEnvironment;
use engine_protocol::language_server::MethodPointer;
use span_tree::generate::context::CalledMethodInfo;
use span_tree::generate::context::Context;
Expand Down Expand Up @@ -355,6 +356,15 @@ impl Handle {
self.graph.borrow().disconnect(connection, self)
}
}

/// Set the execution environment.
pub async fn set_execution_environment(
&self,
execution_environment: ExecutionEnvironment,
) -> FallibleResult {
self.execution_ctx.set_execution_environment(execution_environment).await?;
Ok(())
}
}


Expand Down
8 changes: 8 additions & 0 deletions app/gui/src/model/execution_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use double_representation::identifier::Identifier;
use double_representation::name::project;
use double_representation::name::QualifiedName;
use engine_protocol::language_server;
use engine_protocol::language_server::ExecutionEnvironment;
use engine_protocol::language_server::ExpressionUpdate;
use engine_protocol::language_server::ExpressionUpdatePayload;
use engine_protocol::language_server::MethodPointer;
Expand Down Expand Up @@ -503,6 +504,13 @@ pub trait API: Debug {

/// Adjust method pointers after the project rename action.
fn rename_method_pointers(&self, old_project_name: String, new_project_name: String);

/// Set the execution environment of the context.
#[allow(clippy::needless_lifetimes)]
fn set_execution_environment<'a>(
&'a self,
execution_environment: ExecutionEnvironment,
) -> BoxFuture<'a, FallibleResult>;
}

// Note: Needless lifetimes
Expand Down
14 changes: 14 additions & 0 deletions app/gui/src/model/execution_context/plain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::model::execution_context::Visualization;
use crate::model::execution_context::VisualizationId;
use crate::model::execution_context::VisualizationUpdateData;

use engine_protocol::language_server::ExecutionEnvironment;
use engine_protocol::language_server::MethodPointer;
use engine_protocol::language_server::VisualisationConfiguration;
use futures::future::LocalBoxFuture;
Expand Down Expand Up @@ -61,6 +62,8 @@ pub struct ExecutionContext {
pub is_ready: crate::sync::Synchronized<bool>,
/// Component groups defined in libraries imported into the execution context.
pub component_groups: RefCell<Rc<Vec<ComponentGroup>>>,
/// Execution environment of the context.
pub execution_environment: Cell<ExecutionEnvironment>,
}

impl ExecutionContext {
Expand All @@ -72,13 +75,15 @@ impl ExecutionContext {
let computed_value_info_registry = default();
let is_ready = default();
let component_groups = default();
let execution_environment = default();
Self {
entry_point,
stack,
visualizations,
computed_value_info_registry,
is_ready,
component_groups,
execution_environment,
}
}

Expand Down Expand Up @@ -273,6 +278,15 @@ impl model::execution_context::API for ExecutionContext {
local_call.definition = update_method_pointer(&mut local_call.definition)
});
}

fn set_execution_environment(
&self,
environment: ExecutionEnvironment,
) -> BoxFuture<FallibleResult> {
info!("Setting execution environment to {environment:?}.");
self.execution_environment.set(environment);
futures::future::ready(Ok(())).boxed_local()
}
}


Expand Down
23 changes: 22 additions & 1 deletion app/gui/src/model/execution_context/synchronized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::model::execution_context::VisualizationId;
use crate::model::execution_context::VisualizationUpdateData;

use engine_protocol::language_server;
use engine_protocol::language_server::ExecutionEnvironment;



Expand Down Expand Up @@ -298,7 +299,11 @@ impl model::execution_context::API for ExecutionContext {
async move {
self.language_server
.client
.recompute(&self.id, &language_server::InvalidatedExpressions::All)
.recompute(
&self.id,
&language_server::InvalidatedExpressions::All,
&Some(self.model.execution_environment.get()),
)
.await?;
Ok(())
}
Expand All @@ -308,6 +313,22 @@ impl model::execution_context::API for ExecutionContext {
fn rename_method_pointers(&self, old_project_name: String, new_project_name: String) {
self.model.rename_method_pointers(old_project_name, new_project_name);
}

fn set_execution_environment(
&self,
execution_environment: ExecutionEnvironment,
) -> BoxFuture<FallibleResult> {
self.model.execution_environment.set(execution_environment);
async move {
info!("Setting execution environment to {execution_environment:?}.");
self.language_server
.client
.set_execution_environment(&self.id, &execution_environment)
.await?;
Ok(())
}
.boxed_local()
}
}

impl Drop for ExecutionContext {
Expand Down
2 changes: 1 addition & 1 deletion app/gui/src/presenter/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ use crate::presenter::graph::state::State;
use double_representation::context_switch::Context;
use double_representation::context_switch::ContextSwitch;
use double_representation::context_switch::ContextSwitchExpression;
use engine_protocol::language_server::ExecutionEnvironment;
use engine_protocol::language_server::SuggestionId;
use enso_frp as frp;
use futures::future::LocalBoxFuture;
use ide_view as view;
use ide_view::graph_editor::component::node as node_view;
use ide_view::graph_editor::component::visualization as visualization_view;
use ide_view::graph_editor::EdgeEndpoint;
use view::graph_editor::ExecutionEnvironment;
use view::graph_editor::WidgetUpdates;


Expand Down
31 changes: 25 additions & 6 deletions app/gui/src/presenter/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::executor::global::spawn_stream_handler;
use crate::presenter;
use crate::presenter::graph::ViewNodeId;

use engine_protocol::language_server::ExecutionEnvironment;
use enso_frp as frp;
use ensogl::system::js;
use ide_view as view;
Expand Down Expand Up @@ -287,6 +288,24 @@ impl Model {
view.show_graph_editor();
})
}

fn execution_environment_changed(
&self,
execution_environment: &ide_view::execution_environment_selector::ExecutionEnvironment,
) {
if let Ok(execution_environment) = execution_environment.as_str().try_into() {
let graph_controller = self.graph_controller.clone_ref();
executor::global::spawn(async move {
if let Err(err) =
graph_controller.set_execution_environment(execution_environment).await
{
error!("Error setting execution environment: {err}");
}
});
} else {
error!("Invalid execution environment: {execution_environment:?}");
}
}
}


Expand Down Expand Up @@ -385,22 +404,22 @@ impl Project {
eval_ view.execution_context_restart(model.execution_context_restart());

view.set_read_only <+ view.toggle_read_only.map(f_!(model.toggle_read_only()));
eval graph_view.execution_environment((env) model.execution_environment_changed(env));
}

let graph_controller = self.model.graph_controller.clone_ref();

self.init_analytics()
.init_execution_modes()
.init_execution_environments()
.setup_notification_handler()
.attach_frp_to_values_computed_notifications(graph_controller, values_computed)
}

/// Initialises execution modes. Currently a dummy implementqation to be replaced during
/// implementation of #5930.
fn init_execution_modes(self) -> Self {
/// Initialises execution environment.
fn init_execution_environments(self) -> Self {
let graph = &self.model.view.graph();
let entries = Rc::new(vec!["design".to_string(), "live".to_string()]);
graph.set_available_execution_modes(entries);
let entries = Rc::new(ExecutionEnvironment::list_all_as_imstrings());
graph.set_available_execution_environments(entries);
self
}

Expand Down
Loading

0 comments on commit 0d84a60

Please sign in to comment.