1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00

Remove the as_any fns

This commit is contained in:
lucasmerlin
2026-04-23 16:58:19 +02:00
parent e318a72717
commit 65ce0efa2f
3 changed files with 13 additions and 36 deletions

View File

@@ -220,19 +220,22 @@ impl<'a, State: 'static> Harness<'a, State> {
pub fn plugin<P: Plugin<State>>(&self) -> Option<&P> { pub fn plugin<P: Plugin<State>>(&self) -> Option<&P> {
self.plugins self.plugins
.iter() .iter()
.find_map(|p| p.as_any().downcast_ref::<P>()) .find_map(|p| (&**p as &dyn std::any::Any).downcast_ref::<P>())
} }
/// Mutably borrow a registered plugin by type. /// Mutably borrow a registered plugin by type.
pub fn plugin_mut<P: Plugin<State>>(&mut self) -> Option<&mut P> { pub fn plugin_mut<P: Plugin<State>>(&mut self) -> Option<&mut P> {
self.plugins self.plugins
.iter_mut() .iter_mut()
.find_map(|p| p.as_any_mut().downcast_mut::<P>()) .find_map(|p| (&mut **p as &mut dyn std::any::Any).downcast_mut::<P>())
} }
/// Remove and return the first plugin of the given type. /// Remove and return the first plugin of the given type.
pub fn take_plugin<P: Plugin<State>>(&mut self) -> Option<Box<P>> { pub fn take_plugin<P: Plugin<State>>(&mut self) -> Option<Box<P>> {
let idx = self.plugins.iter().position(|p| p.as_any().is::<P>())?; let idx = self
.plugins
.iter()
.position(|p| (&**p as &dyn std::any::Any).is::<P>())?;
let boxed = self.plugins.remove(idx); let boxed = self.plugins.remove(idx);
let raw: *mut dyn Plugin<State> = Box::into_raw(boxed); let raw: *mut dyn Plugin<State> = Box::into_raw(boxed);
// SAFETY: `is::<P>()` confirmed the concrete type is `P`. Fat-to-thin pointer // SAFETY: `is::<P>()` confirmed the concrete type is `P`. Fat-to-thin pointer

View File

@@ -22,11 +22,15 @@ use crate::{ExceededMaxStepsError, Harness};
/// fn after_step(&mut self, _harness: &mut Harness<'_, S>) { /// fn after_step(&mut self, _harness: &mut Harness<'_, S>) {
/// // ... /// // ...
/// } /// }
/// fn as_any(&self) -> &dyn std::any::Any { self }
/// fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self }
/// } /// }
/// ``` /// ```
/// ///
/// # Downcasting
///
/// [`Any`] is a supertrait, so [`Harness::plugin`] / [`Harness::plugin_mut`] /
/// [`Harness::take_plugin`] downcast registered plugins back to their concrete type via
/// trait upcasting. No boilerplate needed on your end.
///
/// # Re-entrancy /// # Re-entrancy
/// ///
/// Plugin hooks receive `&mut Harness`. Calling [`Harness::step`] / [`Harness::run`] / /// Plugin hooks receive `&mut Harness`. Calling [`Harness::step`] / [`Harness::run`] /
@@ -35,7 +39,7 @@ use crate::{ExceededMaxStepsError, Harness};
/// harness from inside a hook — e.g. an inspector that blocks on user input — use /// harness from inside a hook — e.g. an inspector that blocks on user input — use
/// [`Harness::advance_frame`] instead. /// [`Harness::advance_frame`] instead.
#[expect(unused_variables, reason = "default no-op impls")] #[expect(unused_variables, reason = "default no-op impls")]
pub trait Plugin<State = ()>: Send + 'static { pub trait Plugin<State = ()>: Send + Any {
/// Called once at the start of every `run()` / `try_run()` / `try_run_realtime()` / /// Called once at the start of every `run()` / `try_run()` / `try_run_realtime()` /
/// `run_ok()` invocation, before the first step. /// `run_ok()` invocation, before the first step.
fn before_run(&mut self, harness: &mut Harness<'_, State>) {} fn before_run(&mut self, harness: &mut Harness<'_, State>) {}
@@ -85,12 +89,6 @@ pub trait Plugin<State = ()>: Send + 'static {
/// called [`install_panic_hook`]. Without the hook, the variant still flips to /// called [`install_panic_hook`]. Without the hook, the variant still flips to
/// `Fail` but both fields are `None`. /// `Fail` but both fields are `None`.
fn on_test_result(&mut self, harness: &mut Harness<'_, State>, result: TestResult<'_>) {} fn on_test_result(&mut self, harness: &mut Harness<'_, State>, result: TestResult<'_>) {}
/// Downcast support — implement as `self`.
fn as_any(&self) -> &dyn Any;
/// Downcast support — implement as `self`.
fn as_any_mut(&mut self) -> &mut dyn Any;
} }
/// Location of a panic — a `std::panic::Location` stripped of its borrow so it can be /// Location of a panic — a `std::panic::Location` stripped of its borrow so it can be

View File

@@ -71,12 +71,6 @@ impl<S> Plugin<S> for CountingPlugin {
TestResult::Fail { .. } => "on_test_result:fail", TestResult::Fail { .. } => "on_test_result:fail",
}); });
} }
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
} }
/// Lifecycle ordering: a simple run+drop cycle fires the expected hooks in order. /// Lifecycle ordering: a simple run+drop cycle fires the expected hooks in order.
@@ -141,12 +135,6 @@ fn advance_frame_skips_hooks() {
h.advance_frame(); h.advance_frame();
} }
} }
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
} }
let log: Log = Arc::default(); let log: Log = Arc::default();
@@ -188,12 +176,6 @@ fn mid_dispatch_registration_is_deferred() {
h.add_plugin(latecomer); h.add_plugin(latecomer);
} }
} }
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
} }
let log: Log = Arc::default(); let log: Log = Arc::default();
@@ -263,12 +245,6 @@ fn reentrant_step_panics_in_debug() {
// Forbidden: step from inside a hook. // Forbidden: step from inside a hook.
h.step(); h.step();
} }
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
} }
let mut harness = Harness::builder().with_plugin(Misbehaver).build_ui(|ui| { let mut harness = Harness::builder().with_plugin(Misbehaver).build_ui(|ui| {