Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions crates/ark/src/comm_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ use serde::de::DeserializeOwned;
use serde::Serialize;
use stdext::result::ResultExt;

use crate::console::Console;

/// Context provided to `CommHandler` methods, giving access to the outgoing
/// channel and close-request mechanism. In the future, we'll provide access to
/// more of the Console state, such as the currently active environment.
/// channel, close-request mechanism, and the Console singleton (via
/// `console()`). Through the Console, handlers can reach runtime state such
/// as the graphics device context.
#[derive(Debug)]
pub struct CommHandlerContext {
pub outgoing_tx: CommOutgoingTx,
Expand Down Expand Up @@ -56,6 +59,11 @@ impl CommHandlerContext {
};
self.outgoing_tx.send(CommMsg::Data(json)).log_err();
}

/// Access the Console singleton (the R runtime).
pub(crate) fn console(&self) -> &Console {
Console::get()
}
}

/// Trait for comm handlers that run synchronously on the R thread.
Expand Down
5 changes: 4 additions & 1 deletion crates/ark/src/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ use crate::lsp::state_handlers::ConsoleInputs;
use crate::modules;
use crate::modules::ARK_ENVS;
use crate::plots::graphics_device;
use crate::plots::graphics_device::GraphicsDeviceNotification;
use crate::plots::graphics_device::DeviceContext;
use crate::r_task;
use crate::r_task::BoxFuture;
use crate::r_task::RTask;
Expand Down Expand Up @@ -334,4 +334,7 @@ pub(crate) struct Console {

/// Comm handlers registered on the R thread (keyed by comm ID).
comms: HashMap<String, ConsoleComm>,

/// Graphics device state (plot recording, rendering, comm management).
device_context: DeviceContext,
}
26 changes: 12 additions & 14 deletions crates/ark/src/console/console_repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,6 @@ impl Console {
dap: Arc<Mutex<Dap>>,
session_mode: SessionMode,
default_repos: DefaultRepos,
graphics_device_rx: AsyncUnboundedReceiver<GraphicsDeviceNotification>,
console_notification_rx: AsyncUnboundedReceiver<ConsoleNotification>,
) {
// Set the main thread ID.
Expand Down Expand Up @@ -481,17 +480,16 @@ impl Console {
}
});

// Initialize the GD context on this thread.
// Perform R-side graphics device initialization (register as
// interactive, spawn notification listener). The `DeviceContext`
// itself is already created as part of `Console::new()`.
//
// Note that we do it after init is complete to avoid deadlocking
// integration tests by spawning an async task. The deadlock is caused
// by https://github.com/posit-dev/ark/blob/bd827e735970ca17102aeddfbe2c3ccf26950a36/crates/ark/src/r_task.rs#L261.
// We should be able to remove this escape hatch in `r_task()` by
// instantiating an `Console` in unit tests as well.
graphics_device::init_graphics_device(
console.comm_event_tx.clone(),
console.iopub_tx().clone(),
graphics_device_rx,
);
graphics_device::init_graphics_device();

// Now that R has started and libr and ark have fully initialized, run site and user
// level R profiles, in that order
Expand Down Expand Up @@ -589,6 +587,8 @@ impl Console {
dap: Arc<Mutex<Dap>>,
session_mode: SessionMode,
) -> Self {
let device_context = DeviceContext::new(iopub_tx.clone());

Self {
r_request_rx,
comm_event_tx,
Expand Down Expand Up @@ -634,6 +634,7 @@ impl Console {
read_console_shutdown: Cell::new(false),
debug_filter: ConsoleFilter::new(),
comms: HashMap::new(),
device_context,
}
}

Expand Down Expand Up @@ -685,6 +686,10 @@ impl Console {
&self.comm_event_tx
}

pub(crate) fn device_context(&self) -> &DeviceContext {
&self.device_context
}

/// Run a closure while capturing console output.
/// Returns the closure's result paired with any captured output.
pub(crate) fn with_capture<T>(f: impl FnOnce() -> T) -> (T, String) {
Expand Down Expand Up @@ -2235,13 +2240,6 @@ impl Console {
// might end up being executed on the LSP thread.
// https://github.com/rstudio/positron/issues/431
unsafe { R_RunPendingFinalizers() };

// Check for Positron render requests.
//
// TODO: This should move to a spawned task that'd be woken up by
// incoming messages on plot comms. This way we'll prevent the delays
// introduced by timeout-based event polling.
graphics_device::on_process_idle_events();
}

pub(super) fn eval_env(&self) -> RObject {
Expand Down
Loading