Skip to main content

Animator

Struct Animator 

Source
pub struct Animator<M, S: AnimationStates> { /* private fields */ }
Expand description

The machine a game poses a draw with: the state it is in, what that state plays, and the fade out of the state it left.

Typed by the mesh it poses, so a draw of another mesh does not take it. ctx.animate runs one and Instance::posed draws in the pose it holds; no clip length and no time of the game’s own crosses either call.

Implementations§

Source§

impl<M, S: AnimationStates> Animator<M, S>

Source

pub fn new() -> Self

A machine in its entry state, at the start of what that state plays reading the default input.

Examples found in repository?
examples/animation.rs (line 668)
659    fn init(_ctx: &mut InitContext<'_, Scene>) -> Result<Self, Error> {
660        Ok(Self {
661            elf_pos: ELF_START,
662            elf_prev: ELF_START,
663            elf_yaw: 0.0,
664            elf_height: 0.0,
665            elf_height_prev: 0.0,
666            jump_speed: 0.0,
667            elf_input: ElfInput::default(),
668            elf_animator: Animator::new(),
669            scrubbed_animator: Animator::new(),
670            butterfly_animator: Animator::new(),
671            hits: 0,
672            in_patch: false,
673            holding: false,
674            camera_yaw: 0.0,
675            camera_pitch: 0.0,
676            last_event: "none yet",
677        })
678    }
679
680    /// Turns the camera by how far the pointer moves sideways and upward,
681    /// [`CAMERA_PITCH_RANGE`] holding how far it tilts.
682    fn steer_camera(&mut self, ctx: &mut FrameContext<'_, Scene>) {
683        self.camera_yaw -= ctx.axis(Axis::CameraYaw);
684        self.camera_pitch = (self.camera_pitch + ctx.axis(Axis::CameraPitch))
685            .clamp(CAMERA_PITCH_RANGE.start, CAMERA_PITCH_RANGE.end);
686    }
687
688    /// Turns `elf_yaw` toward the heading `ctx` reads, relative to the
689    /// camera's own turn, and moves `elf_pos` along it; the speed it moves
690    /// at, a fraction of [`ELF_SPEED`], held at [`WALK_CAP`] until
691    /// `Button::Run` is held.
692    fn advance(&mut self, ctx: &mut TickContext<'_, Scene>) -> f32 {
693        let control = ctx.axis2(Move::Walk).clamp_length_max(1.0);
694        let turn = Quat::from_rotation_y(self.camera_yaw);
695        let heading = turn * Vec3::X * control.x + turn * Vec3::NEG_Z * control.y;
696        let dt = ctx.dt().as_secs_f32();
697        if let Some(direction) = heading.try_normalize() {
698            let wanted = direction.x.atan2(direction.z);
699            let turn = (wanted - self.elf_yaw + core::f32::consts::PI).rem_euclid(TAU)
700                - core::f32::consts::PI;
701            self.elf_yaw += turn.clamp(-TURN_RATE * dt, TURN_RATE * dt);
702        }
703        let cap = if ctx.down(Button::Run) { 1.0 } else { WALK_CAP };
704        self.elf_pos += heading * cap * ELF_SPEED * dt;
705        heading.length() * cap
706    }
707
708    /// Integrates [`Self::elf_height`] under [`GRAVITY`] from
709    /// [`Self::jump_speed`], held at the ground; `true` the tick it
710    /// returns there from above it.
711    fn fall(&mut self, dt: f32) -> bool {
712        let off_ground = self.elf_height > 0.0;
713        self.jump_speed -= GRAVITY * dt;
714        self.elf_height = (self.elf_height + self.jump_speed * dt).max(0.0);
715        if self.elf_height == 0.0 {
716            self.jump_speed = 0.0;
717        }
718        off_ground && self.elf_height == 0.0
719    }
720
721    /// The hurt patch `elf_pos` stands inside, if any.
722    fn patch_underfoot(&self) -> Option<Vec3> {
723        HURT_PATCHES
724            .into_iter()
725            .find(|&patch| self.elf_pos.distance(patch) < HURT_RADIUS)
726    }
727
728    /// Reads the controls and moves the elf, filling [`Self::elf_input`]
729    /// for [`ElfState`] to read.
730    fn tick_elf(&mut self, ctx: &mut TickContext<'_, Scene>) {
731        let grounded = matches!(
732            self.elf_animator.state(),
733            ElfState::Idle | ElfState::Locomotion
734        );
735
736        self.elf_input.speed = self.advance(ctx);
737        self.elf_input.attack = ctx.pressed(Button::Attack);
738        self.elf_input.jump = ctx.pressed(Button::Jump);
739        self.elf_input.dance = ctx.pressed(Button::Dance);
740
741        self.elf_input.near_seat = self.elf_pos.distance(SEAT_POSITION) < SEAT_INTERACT_RADIUS;
742        self.elf_input.interact = ctx.pressed(Button::Interact);
743        if self.elf_input.interact && grounded && self.elf_input.near_seat {
744            self.elf_pos = SEAT_SPOT;
745            self.elf_yaw = SEAT_FACING;
746        }
747
748        let underfoot = self.patch_underfoot();
749        let entered_patch = underfoot.is_some() && !self.in_patch;
750        self.in_patch = underfoot.is_some();
751        self.hits += u32::from(entered_patch);
752        self.elf_input.hit = entered_patch && self.hits < FATAL_HITS;
753        self.elf_input.dying = entered_patch && self.hits >= FATAL_HITS;
754        if entered_patch {
755            self.last_event = match self.elf_input.dying {
756                true => "elf died",
757                false => "elf hit",
758            };
759        }
760    }
761
762    /// Starts a new [`Animator`] over the elf's own state, its position and
763    /// hit count reset with it.
764    fn restart_elf(&mut self) {
765        self.elf_animator = Animator::new();
766        self.elf_pos = ELF_START;
767        self.elf_prev = ELF_START;
768        self.elf_yaw = 0.0;
769        self.elf_height = 0.0;
770        self.elf_height_prev = 0.0;
771        self.jump_speed = 0.0;
772        self.elf_input = ElfInput::default();
773        self.hits = 0;
774        self.in_patch = false;
775        self.last_event = "new elf started";
776    }
Source

pub fn state(&self) -> S

The state it is in, which is the state being faded into while a fade runs.

Examples found in repository?
examples/animation.rs (line 732)
730    fn tick_elf(&mut self, ctx: &mut TickContext<'_, Scene>) {
731        let grounded = matches!(
732            self.elf_animator.state(),
733            ElfState::Idle | ElfState::Locomotion
734        );
735
736        self.elf_input.speed = self.advance(ctx);
737        self.elf_input.attack = ctx.pressed(Button::Attack);
738        self.elf_input.jump = ctx.pressed(Button::Jump);
739        self.elf_input.dance = ctx.pressed(Button::Dance);
740
741        self.elf_input.near_seat = self.elf_pos.distance(SEAT_POSITION) < SEAT_INTERACT_RADIUS;
742        self.elf_input.interact = ctx.pressed(Button::Interact);
743        if self.elf_input.interact && grounded && self.elf_input.near_seat {
744            self.elf_pos = SEAT_SPOT;
745            self.elf_yaw = SEAT_FACING;
746        }
747
748        let underfoot = self.patch_underfoot();
749        let entered_patch = underfoot.is_some() && !self.in_patch;
750        self.in_patch = underfoot.is_some();
751        self.hits += u32::from(entered_patch);
752        self.elf_input.hit = entered_patch && self.hits < FATAL_HITS;
753        self.elf_input.dying = entered_patch && self.hits >= FATAL_HITS;
754        if entered_patch {
755            self.last_event = match self.elf_input.dying {
756                true => "elf died",
757                false => "elf hit",
758            };
759        }
760    }
761
762    /// Starts a new [`Animator`] over the elf's own state, its position and
763    /// hit count reset with it.
764    fn restart_elf(&mut self) {
765        self.elf_animator = Animator::new();
766        self.elf_pos = ELF_START;
767        self.elf_prev = ELF_START;
768        self.elf_yaw = 0.0;
769        self.elf_height = 0.0;
770        self.elf_height_prev = 0.0;
771        self.jump_speed = 0.0;
772        self.elf_input = ElfInput::default();
773        self.hits = 0;
774        self.in_patch = false;
775        self.last_event = "new elf started";
776    }
777
778    fn panel(&self, ctx: &mut FrameContext<'_, Scene>) {
779        let state = match self.elf_animator.state() {
780            ElfState::Idle => "idle",
781            ElfState::Locomotion if self.elf_input.speed > WALK_CAP => "running",
782            ElfState::Locomotion => "walking",
783            ElfState::Attack => "attacking",
784            ElfState::Hit => "hit",
785            ElfState::Death => "dead",
786            ElfState::SitDown => "sitting down",
787            ElfState::Sit => "sitting",
788            ElfState::StandUp => "standing up",
789            ElfState::Jump => "jumping",
790            ElfState::Dance => "dancing",
791        };
792        ctx.ui(|ui| {
793            egui::Frame::new()
794                .fill(egui::Color32::from_black_alpha(PANEL_BACKDROP))
795                .inner_margin(PANEL_PADDING)
796                .corner_radius(f32::from(PANEL_PADDING))
797                .show(ui, |ui| {
798                    ui.heading(panel_text(format!("elf is {state}")));
799                    ui.label(panel_text(format!(
800                        "hits taken {} of the {} red patches hurt for, {}",
801                        self.hits, FATAL_HITS, self.last_event
802                    )));
803                    ui.label(panel_text(match self.elf_animator.transitioning() {
804                        true => "fading between clips",
805                        false => "one clip playing",
806                    }));
807                    ui.add_space(f32::from(PANEL_PADDING));
808                    egui::Grid::new("controls").show(ui, |ui| {
809                        for (key, does) in CONTROLS {
810                            ui.label(panel_text(key));
811                            ui.label(panel_text(does));
812                            ui.end_row();
813                        }
814                    });
815                });
816        });
817    }
818
819    /// A prompt over the seat, each hurt patch, and the scrubbed elf,
820    /// naming what a player finds there; the seat's own prompt names the
821    /// live binding of `Button::Interact` by its own name, not one fixed
822    /// in the code, and is absent while the elf sits on it.
823    fn draw_prompts(&self, ctx: &mut FrameContext<'_, Scene>, camera: Camera) {
824        let sit_key = ctx
825            .bindings(Button::Interact)
826            .into_iter()
827            .next()
828            .map_or_else(|| "interact".to_owned(), |binding| binding.to_string());
829        let sit = ctx.text_layout(
830            &format!("{sit_key} sits"),
831            egui::FontId::proportional(PROMPT_SIZE),
832        );
833        let hurts = ctx.text_layout("hurts", egui::FontId::proportional(PROMPT_SIZE));
834        let walk_closer = ctx.text_layout("walk closer", egui::FontId::proportional(PROMPT_SIZE));
835
836        let mut prompts = vec![(
837            SCRUBBED_ELF_POSITION + Vec3::Y * (ELF_HEIGHT + PROMPT_LIFT),
838            walk_closer,
839        )];
840        if !self.elf_animator.state().seated() {
841            prompts.push((
842                SEAT_POSITION + Vec3::Y * (SEAT_HEAD_HEIGHT + PROMPT_LIFT),
843                sit,
844            ));
845        }
846        prompts.extend(HURT_PATCHES.map(|patch| (patch + Vec3::Y * PROMPT_LIFT, hurts.clone())));
847
848        let window_size = ctx.window_size();
849        let pixels_per_point = ctx.pixels_per_point();
850        ctx.ui(|ui| {
851            let painter = ui.painter();
852            for (point, galley) in prompts {
853                let Some(pixel) = camera.pixel_of(point, window_size) else {
854                    continue;
855                };
856                let at = logical(pixel, pixels_per_point);
857                let ink = galley.mesh_bounds;
858                let pos = egui::pos2(at.x - ink.center().x, at.y - ink.center().y);
859                let backdrop = egui::Rect::from_center_size(
860                    at,
861                    ink.size() + egui::Vec2::splat(PROMPT_PADDING * 2.0),
862                );
863                painter.rect_filled(
864                    backdrop,
865                    PROMPT_PADDING,
866                    egui::Color32::from_black_alpha(PANEL_BACKDROP),
867                );
868                painter.galley(pos, galley, PANEL_TEXT_COLOR);
869            }
870        });
871    }
Source

pub fn entered(&self, state: S) -> bool

Whether a transition into state started the last time animate ran it.

Examples found in repository?
examples/animation.rs (line 900)
882    fn tick(&mut self, ctx: &mut TickContext<'_, Scene>) {
883        self.elf_prev = self.elf_pos;
884        self.elf_height_prev = self.elf_height;
885
886        if ctx.pressed(Button::Restart) {
887            self.restart_elf();
888        }
889        if ctx.pressed(Button::Hold) {
890            self.holding = true;
891        }
892        if ctx.pressed(Button::Release) {
893            self.holding = false;
894        }
895
896        self.elf_input.landed = self.fall(ctx.dt().as_secs_f32());
897        self.tick_elf(ctx);
898        ctx.animate(Elf, &mut self.elf_animator, &self.elf_input);
899
900        if self.elf_animator.entered(ElfState::Jump) {
901            self.jump_speed = JUMP_LAUNCH_SPEED;
902        }
903        if self.elf_animator.left(ElfState::StandUp) {
904            self.last_event = "elf stood up";
905        }
906        if self.elf_animator.entered(ElfState::Sit) {
907            self.last_event = "elf sat down";
908        }
909        if self.elf_animator.entered(ElfState::Death) {
910            self.last_event = "elf died";
911        }
912
913        let scrubbed_input = ScrubbedInput {
914            settled: settled_at(self.elf_pos.distance(SCRUBBED_ELF_POSITION)),
915        };
916        ctx.animate(Elf, &mut self.scrubbed_animator, &scrubbed_input);
917        ctx.animate(Butterfly, &mut self.butterfly_animator, &());
918    }
Source

pub fn left(&self, state: S) -> bool

Whether a transition out of state started the last time animate ran it.

Examples found in repository?
examples/animation.rs (line 903)
882    fn tick(&mut self, ctx: &mut TickContext<'_, Scene>) {
883        self.elf_prev = self.elf_pos;
884        self.elf_height_prev = self.elf_height;
885
886        if ctx.pressed(Button::Restart) {
887            self.restart_elf();
888        }
889        if ctx.pressed(Button::Hold) {
890            self.holding = true;
891        }
892        if ctx.pressed(Button::Release) {
893            self.holding = false;
894        }
895
896        self.elf_input.landed = self.fall(ctx.dt().as_secs_f32());
897        self.tick_elf(ctx);
898        ctx.animate(Elf, &mut self.elf_animator, &self.elf_input);
899
900        if self.elf_animator.entered(ElfState::Jump) {
901            self.jump_speed = JUMP_LAUNCH_SPEED;
902        }
903        if self.elf_animator.left(ElfState::StandUp) {
904            self.last_event = "elf stood up";
905        }
906        if self.elf_animator.entered(ElfState::Sit) {
907            self.last_event = "elf sat down";
908        }
909        if self.elf_animator.entered(ElfState::Death) {
910            self.last_event = "elf died";
911        }
912
913        let scrubbed_input = ScrubbedInput {
914            settled: settled_at(self.elf_pos.distance(SCRUBBED_ELF_POSITION)),
915        };
916        ctx.animate(Elf, &mut self.scrubbed_animator, &scrubbed_input);
917        ctx.animate(Butterfly, &mut self.butterfly_animator, &());
918    }
Source

pub fn transitioning(&self) -> bool

Whether a fade out of the state it left was still running the last time animate ran it.

Examples found in repository?
examples/animation.rs (line 803)
778    fn panel(&self, ctx: &mut FrameContext<'_, Scene>) {
779        let state = match self.elf_animator.state() {
780            ElfState::Idle => "idle",
781            ElfState::Locomotion if self.elf_input.speed > WALK_CAP => "running",
782            ElfState::Locomotion => "walking",
783            ElfState::Attack => "attacking",
784            ElfState::Hit => "hit",
785            ElfState::Death => "dead",
786            ElfState::SitDown => "sitting down",
787            ElfState::Sit => "sitting",
788            ElfState::StandUp => "standing up",
789            ElfState::Jump => "jumping",
790            ElfState::Dance => "dancing",
791        };
792        ctx.ui(|ui| {
793            egui::Frame::new()
794                .fill(egui::Color32::from_black_alpha(PANEL_BACKDROP))
795                .inner_margin(PANEL_PADDING)
796                .corner_radius(f32::from(PANEL_PADDING))
797                .show(ui, |ui| {
798                    ui.heading(panel_text(format!("elf is {state}")));
799                    ui.label(panel_text(format!(
800                        "hits taken {} of the {} red patches hurt for, {}",
801                        self.hits, FATAL_HITS, self.last_event
802                    )));
803                    ui.label(panel_text(match self.elf_animator.transitioning() {
804                        true => "fading between clips",
805                        false => "one clip playing",
806                    }));
807                    ui.add_space(f32::from(PANEL_PADDING));
808                    egui::Grid::new("controls").show(ui, |ui| {
809                        for (key, does) in CONTROLS {
810                            ui.label(panel_text(key));
811                            ui.label(panel_text(does));
812                            ui.end_row();
813                        }
814                    });
815                });
816        });
817    }
Source

pub fn hold(&mut self)

Holds what it plays where it is, until resume.

Required if you want a paused game to leave every mesh in the pose it is drawn in: the span between this call and the resume counts for nothing, so each motion runs on from where it was held.

Source

pub fn resume(&mut self)

Plays on from where hold left it.

Trait Implementations§

Source§

impl<M, S: AnimationStates> Clone for Animator<M, S>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<M, S: AnimationStates> Debug for Animator<M, S>

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

The state it is in and whether it is still fading out of the one it left.

Source§

impl<M, S: AnimationStates> Default for Animator<M, S>

Source§

fn default() -> Self

A machine in its entry state; see Animator::new.

Auto Trait Implementations§

§

impl<M, S> Freeze for Animator<M, S>
where S: Freeze, Option<Change<S>>: Freeze, PhantomData<fn() -> M>: Freeze,

§

impl<M, S> RefUnwindSafe for Animator<M, S>

§

impl<M, S> Send for Animator<M, S>
where S: Send, Option<Change<S>>: Send, PhantomData<fn() -> M>: Send,

§

impl<M, S> Sync for Animator<M, S>
where S: Sync, Option<Change<S>>: Sync, PhantomData<fn() -> M>: Sync,

§

impl<M, S> Unpin for Animator<M, S>
where S: Unpin, Option<Change<S>>: Unpin, PhantomData<fn() -> M>: Unpin,

§

impl<M, S> UnsafeUnpin for Animator<M, S>
where S: UnsafeUnpin, Option<Change<S>>: UnsafeUnpin, PhantomData<fn() -> M>: UnsafeUnpin,

§

impl<M, S> UnwindSafe for Animator<M, S>
where S: UnwindSafe, Option<Change<S>>: UnwindSafe, PhantomData<fn() -> M>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> SerializableAny for T
where T: 'static + Any + Clone + for<'a> Send + Sync,

Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more