mirror of
https://github.com/emilk/egui.git
synced 2026-06-26 14:49:06 -04:00
egui_inspection: add transport connect/Listener helpers
Add transport::connect (dial + split) and a sync transport::Listener (bind + accept) so both ends of the inspection connection build streams identically without depending on interprocess directly. Plugin now dials via transport::connect. These back the kittest harness moving onto the same local socket as the live plugin.
This commit is contained in:
@@ -30,10 +30,9 @@ use std::sync::{Arc, Mutex, OnceLock};
|
||||
use std::thread;
|
||||
|
||||
use egui::{Context, FullOutput, RawInput};
|
||||
use interprocess::local_socket::{RecvHalf, SendHalf, Stream, prelude::*};
|
||||
|
||||
use crate::INSPECTION_SOCKET_ENV_VAR;
|
||||
use crate::transport::socket_name;
|
||||
use crate::transport::{self, RecvHalf, SendHalf};
|
||||
use crate::protocol::{
|
||||
Capabilities, Frame, FrameScreenshot, HarnessMessage, InspectorCommand, PROTOCOL_VERSION,
|
||||
PeerHello, PeerKind, read_message, write_message,
|
||||
@@ -122,9 +121,8 @@ impl InspectionPlugin {
|
||||
/// # Errors
|
||||
/// When the socket can't be dialed or a thread can't be spawned.
|
||||
pub fn attach(socket: &str, label: Option<String>) -> Result<Self, InspectionError> {
|
||||
let name = socket_name(socket).map_err(InspectionError::Connect)?;
|
||||
let stream = Stream::connect(name).map_err(InspectionError::Connect)?;
|
||||
let (reader_stream, writer_stream) = stream.split();
|
||||
let (reader_stream, writer_stream) =
|
||||
transport::connect(socket).map_err(InspectionError::Connect)?;
|
||||
|
||||
let shared_ctx: SharedCtx = Arc::new(OnceLock::new());
|
||||
|
||||
|
||||
@@ -7,11 +7,15 @@
|
||||
|
||||
use std::io;
|
||||
|
||||
use interprocess::local_socket::Name;
|
||||
use interprocess::local_socket::{ListenerOptions, Name, prelude::*};
|
||||
#[cfg(windows)]
|
||||
use interprocess::local_socket::{GenericNamespaced, ToNsName as _};
|
||||
use interprocess::local_socket::GenericNamespaced;
|
||||
#[cfg(not(windows))]
|
||||
use interprocess::local_socket::{GenericFilePath, ToFsName as _};
|
||||
use interprocess::local_socket::GenericFilePath;
|
||||
|
||||
/// The two halves of a connected local-socket stream, re-exported so consumers build
|
||||
/// reader/writer threads without depending on `interprocess` directly.
|
||||
pub use interprocess::local_socket::{RecvHalf, SendHalf};
|
||||
|
||||
/// Build a platform-appropriate local-socket [`Name`] from the env-var string produced by
|
||||
/// [`generate_socket_target`].
|
||||
@@ -68,3 +72,42 @@ pub fn generate_socket_target() -> io::Result<SocketTarget> {
|
||||
Ok(SocketTarget { name })
|
||||
}
|
||||
}
|
||||
|
||||
/// Dial an already-listening inspection socket and split the stream into read / write halves.
|
||||
///
|
||||
/// The connector side of the connection: the live plugin, or the kittest harness when
|
||||
/// [`crate::INSPECTION_SOCKET_ENV_VAR`] is set.
|
||||
///
|
||||
/// # Errors
|
||||
/// When `raw` isn't a valid local-socket name, or the socket can't be dialed.
|
||||
pub fn connect(raw: &str) -> io::Result<(RecvHalf, SendHalf)> {
|
||||
use interprocess::local_socket::Stream;
|
||||
let stream = Stream::connect(socket_name(raw)?)?;
|
||||
Ok(stream.split())
|
||||
}
|
||||
|
||||
/// A bound synchronous local-socket listener — the listener side of the connection (kittest
|
||||
/// harness in spawn mode, where it binds and then spawns an inspector pointed at the socket).
|
||||
///
|
||||
/// The MCP server uses the tokio listener directly; this sync wrapper exists for the
|
||||
/// thread-based kittest harness.
|
||||
pub struct Listener(interprocess::local_socket::Listener);
|
||||
|
||||
impl Listener {
|
||||
/// Bind a listener at the given target name (from [`generate_socket_target`]).
|
||||
///
|
||||
/// # Errors
|
||||
/// When `raw` isn't a valid local-socket name, or the socket can't be bound.
|
||||
pub fn bind(raw: &str) -> io::Result<Self> {
|
||||
let listener = ListenerOptions::new().name(socket_name(raw)?).create_sync()?;
|
||||
Ok(Self(listener))
|
||||
}
|
||||
|
||||
/// Block until a peer connects, then split the accepted stream into read / write halves.
|
||||
///
|
||||
/// # Errors
|
||||
/// When accepting the inbound connection fails.
|
||||
pub fn accept(&self) -> io::Result<(RecvHalf, SendHalf)> {
|
||||
Ok(self.0.accept()?.split())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user