Struct thin_engine::prelude::InputMap
source · pub struct InputMap<const BINDS: usize> {
pub binds: [Vec<Input>; BINDS],
pub pressing: [bool; BINDS],
pub pressed: [bool; BINDS],
pub released: [bool; BINDS],
pub mouse_scroll: f32,
pub mouse_move: Vec2,
pub mouse_pos: Vec2,
pub other_pressed: Option<Input>,
pub text_typed: Option<String>,
}
Expand description
you can use anything that implements the Into<usize>
trait as an action, but it’s recommended
to use an action enum which derives ToUsize
. input_map!
macro reduces the boilerplate of
this function
#[derive(ToUsize)] // could also manualy implement Into<usize>
enum Actions{
Debug,
Left,
Right,
Click
}
use winit::{event::*, keyboard::KeyCode, event_loop::*, window::Window};
use winit_input_map::*;
use Actions::*;
let mut input = InputMap::new([ // doesnt have to be in the same order as the enum
(Debug, vec![Input::keycode(KeyCode::Space)]),
(Click, vec![Input::Mouse(MouseButton::Left)]),
(Left, vec![Input::keycode(KeyCode::ArrowLeft), Input::keycode(KeyCode::KeyA)]),
(Right, vec![Input::keycode(KeyCode::ArrowRight), Input::keycode(KeyCode::KeyD)]),
]);
let event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
event_loop.run(|event, target|{
input.update(&event);
match &event {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { target.exit() },
Event::AboutToWait => {
if input.pressed(Debug) { println!("pressed {:?}", input.binds(Debug)) }
if input.pressing(Right) || input.pressing(Left) {
println!("axis: {}", input.axis(Right, Left))
}
if input.mouse_move != (0.0, 0.0) {
println!("mouse moved: {:?} and is now at {:?}", input.mouse_move, input.mouse_pos)
}
if input.released(Click) { println!("released {:?}", input.binds(Click)) }
std::thread::sleep(std::time::Duration::from_millis(100));
//put at end of loop because were done with inputs this loop.
input.init();
}
_ => ()
}
}).unwrap();
Fields§
§binds: [Vec<Input>; BINDS]
§pressing: [bool; BINDS]
§pressed: [bool; BINDS]
§released: [bool; BINDS]
§mouse_scroll: f32
the amount the scroll wheel has changed
mouse_move: Vec2
§mouse_pos: Vec2
§other_pressed: Option<Input>
last input even if it isnt in the binds. useful for rebinding.
text_typed: Option<String>
the text typed this loop. useful for typing
Implementations§
source§impl<const BINDS: usize> InputMap<BINDS>
impl<const BINDS: usize> InputMap<BINDS>
sourcepub fn new(binds: [(impl Into<usize>, Vec<Input>); BINDS]) -> InputMap<BINDS>
pub fn new(binds: [(impl Into<usize>, Vec<Input>); BINDS]) -> InputMap<BINDS>
create new input system. recommended to use an action enum which implements the
Into<usize>
trait. the input_map!
macro reduces boilerplate.
use Action::*;
use input::*;
use winit::keyboard::KeyCode;
#[derive(ToUsize)]
enum Action {
Forward,
Back,
Left,
Right
}
//doesnt have to be the same ordered as the enum.
let mut input = Input::new([
(vec![Input::keycode(KeyCode::KeyW)], Forward),
(vec![Input::keycode(KeyCode::KeyA)], Left),
(vec![Input::keycode(KeyCode::KeyS)], Back),
(vec![Input::keycode(KeyCode::KeyD)], Right)
]);
sourcepub fn empty() -> InputMap<0>
pub fn empty() -> InputMap<0>
use if you dont want to have any action. will still have access to everythin else
sourcepub fn update(&mut self, event: &Event<()>)
pub fn update(&mut self, event: &Event<()>)
updates the input using a winit event. make sure to call input.init()
when your done with
the input this loop.
use winit::{event::*, window::Window, event_loop::EventLoop};
use winit_input_map::InputMap;
let mut event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
let mut input = input_map!();
event_loop.run(|event, target|{
input.update(&event);
match &event{
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => target.exit(),
Event::AboutToWait => input.init(),
_ => ()
}
});
sourcepub fn init(&mut self)
pub fn init(&mut self)
initialise input. use when your done with input this loop. required to be called for
everything except pressing
and mouse_pos
to work properly.
use winit::{event::*, window::Window, event_loop::EventLoop};
use winit_input_map::InputMap;
let mut event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
let mut input = input_map!();
event_loop.run(|event, target| {
input.update(&event);
match &event{
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => target.exit(),
Event::AboutToWait => input.init(),
_ => ()
}
});
sourcepub fn binds(&mut self, action: impl Into<usize>) -> &mut Vec<Input>
pub fn binds(&mut self, action: impl Into<usize>) -> &mut Vec<Input>
get binds of action. same as self.binds[action.into()]
sourcepub fn pressing(&self, action: impl Into<usize>) -> bool
pub fn pressing(&self, action: impl Into<usize>) -> bool
checks if action is being pressed currently. same as self.pressing[action.into()]
sourcepub fn pressed(&self, action: impl Into<usize>) -> bool
pub fn pressed(&self, action: impl Into<usize>) -> bool
checks if action was just pressed. same as self.pressed[action.into()]
Examples found in repository?
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
fn main() {
use Action::*;
let (event_loop, window, display) = thin_engine::set_up().unwrap();
window.set_title("Walk Test");
let _ = window.set_cursor_grab(CursorGrabMode::Locked);
window.set_cursor_visible(false);
let mut input = input_map!(
(Jump, KeyCode::Space),
(Exit, KeyCode::Escape),
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Forward, KeyCode::ArrowUp, KeyCode::KeyW),
(Back, KeyCode::ArrowDown, KeyCode::KeyS)
);
let (indices, verts, norms) = mesh!(
&display, &teapot::INDICES, &teapot::VERTICES, &teapot::NORMALS
);
let draw_parameters = DrawParameters {
backface_culling: draw_parameters::BackfaceCullingMode::CullClockwise,
..params::alias_3d()
};
let program = Program::from_source(
&display, shaders::VERTEX,
"#version 140
out vec4 colour;
in vec3 v_normal;
uniform vec3 light;
const vec3 albedo = vec3(0.1, 1.0, 0.3);
void main(){
float light_level = dot(light, v_normal);
colour = vec4(albedo * light_level, 1.0);
}", None,
).unwrap();
let mut pos = vec3(0.0, 0.0, -30.0);
let mut rot = vec2(0.0, 0.0);
let mut gravity = 0.0;
const DELTA: f32 = 0.016;
thin_engine::run(event_loop, &mut input, |input, target| {
display.resize(window.inner_size().into());
let mut frame = display.draw();
let view = Mat4::view_matrix_3d(frame.get_dimensions(), 1.0, 1024.0, 0.1);
//handle gravity and jump
gravity += DELTA * 9.5;
if input.pressed(Jump) {
gravity = -10.0;
}
//set camera rotation
rot += input.mouse_move.scale(DELTA * 2.0);
rot.y = rot.y.clamp(-PI / 2.0, PI / 2.0);
let rx = Quaternion::from_y_rot(rot.x);
let ry = Quaternion::from_x_rot(rot.y);
let rot = rx * ry;
//move player based on view and gravity
let x = input.axis(Right, Left);
let y = input.axis(Forward, Back);
let move_dir = vec3(x, 0.0, y).normalise();
pos += move_dir.transform(&Mat3::from_rot(rx)).scale(5.0 * DELTA);
pos.y = (pos.y - gravity * DELTA).max(0.0);
if input.pressed(Exit) { target.exit() }
frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
//draw teapot
frame.draw(
(&verts, &norms), &indices,
&program, &uniform! {
view: view,
model: Mat4::from_scale(Vec3::splat(0.1)),
camera: Mat4::from_inverse_transform(pos, Vec3::ONE, rot),
light: vec3(1.0, -0.9, -1.0).normalise()
},
&draw_parameters,
).unwrap();
frame.finish().unwrap();
thread::sleep(Duration::from_millis(16));
}).unwrap();
}
More examples
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
fn main() {
use Action::*;
let (event_loop, window, display) = thin_engine::set_up().unwrap();
window.set_title("FXAA Test");
let _ = window.set_cursor_grab(CursorGrabMode::Locked);
window.set_cursor_visible(false);
let mut colour = ResizableTexture2D::default();
let mut depth = ResizableDepthTexture2D::default();
let mut input = input_map!(
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Forward, KeyCode::ArrowUp, KeyCode::KeyW),
(Back, KeyCode::ArrowDown, KeyCode::KeyS),
(FXAA, KeyCode::KeyF),
(Jump, KeyCode::Space)
);
let (screen_indices, verts, uvs) = mesh!(
&display, &screen::INDICES, &screen::VERTICES, &screen::UVS
);
let screen_mesh = (&verts, &uvs);
let (indices, verts, norms) = mesh!(
&display, &teapot::INDICES, &teapot::VERTICES, &teapot::NORMALS
);
let teapot_mesh = (&verts, &norms);
let draw_parameters = DrawParameters {
backface_culling: draw_parameters::BackfaceCullingMode::CullClockwise,
..params::alias_3d()
};
let mut fxaa_on = true;
let program = Program::from_source(
&display, shaders::VERTEX,
"#version 140
out vec4 colour;
in vec3 v_normal;
uniform vec3 light;
uniform mat4 camera;
uniform vec3 ambient;
uniform vec3 albedo;
uniform float shine;
void main() {
vec3 camera_dir = inverse(mat3(camera)) * vec3(0, 0, -1);
vec3 half_dir = normalize(camera_dir + light);
float specular = pow(max(dot(half_dir, v_normal), 0.0), shine);
float light_level = max(dot(light, v_normal), 0.0);
colour = vec4(albedo * light_level + ambient + vec3(specular), 1.0);
}", None
).unwrap();
let normal = Program::from_source(
&display, shaders::SCREEN_VERTEX,
"#version 140
in vec2 uv;
uniform sampler2D tex;
out vec4 colour;
void main() {
colour = texture(tex, uv);
}", None
).unwrap();
let fxaa = shaders::fxaa_shader(&display).unwrap();
let mut pos = vec3(0.0, 0.0, -30.0);
let mut rot = vec2(0.0, 0.0);
const DELTA: f32 = 0.016;
thin_engine::run(event_loop, &mut input, |input, _| {
// using a small resolution to show the effect.
// `let size = window.inner_size().into();`
// can be used instead to set resolution to window size
let size = (380, 216);
display.resize(size);
depth.resize_to_display(&display);
colour.resize_to_display(&display);
//press f to toggle FXAA
if input.pressed(FXAA) { fxaa_on = !fxaa_on }
let colour = colour.texture.as_ref().unwrap();
let depth = depth.texture.as_ref().unwrap();
let mut frame = SimpleFrameBuffer::with_depth_buffer(
&display, colour, depth
).unwrap();
let view = Mat4::view_matrix_3d(size, 1.0, 1024.0, 0.1);
//set camera rotation
rot += input.mouse_move.scale(DELTA * 2.0);
rot.y = rot.y.clamp(-PI / 2.0, PI / 2.0);
let rx = Quaternion::from_y_rot(rot.x);
let ry = Quaternion::from_x_rot(rot.y);
let rot = rx * ry;
//move player based on view
let x = input.axis(Right, Left);
let y = input.axis(Forward, Back);
let move_dir = vec3(x, 0.0, y).normalise().scale(5.0*DELTA);
pos += move_dir.transform(&Mat3::from_rot(rx));
frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
//draw teapot
frame.draw(
teapot_mesh, &indices,
&program, &uniform! {
view: view,
model: Mat4::from_scale(Vec3::splat(0.1)),
camera: Mat4::from_inverse_transform(pos, Vec3::ONE, rot),
light: vec3(0.1, 0.25, -1.0).normalise(),
albedo: vec3(0.5, 0.1, 0.4),
ambient: vec3(0.0, 0.05, 0.1),
shine: 50.0f32,
},
&draw_parameters,
).unwrap();
let mut frame = display.draw();
frame.draw(
screen_mesh, &screen_indices, if fxaa_on { &fxaa } else { &normal },
&shaders::fxaa_uniforms(colour), &DrawParameters::default()
).unwrap();
frame.finish().unwrap();
thread::sleep(Duration::from_millis(16));
}).unwrap();
}
sourcepub fn released(&self, action: impl Into<usize>) -> bool
pub fn released(&self, action: impl Into<usize>) -> bool
checks if action was just released. same as self.released[action.into()]
sourcepub fn axis(&self, pos: impl Into<usize>, neg: impl Into<usize>) -> f32
pub fn axis(&self, pos: impl Into<usize>, neg: impl Into<usize>) -> f32
returns 1.0 if pos is pressed, -1.0 if neg is pressed or 0.0 if either pos and neg or nothing is pressed. usefull for movement controls.
let move_dir = (input.axis(Right, Left), input.axis(Up, Down));
Examples found in repository?
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
fn main() {
use Action::*;
let (event_loop, window, display) = thin_engine::set_up().unwrap();
window.set_title("Walk Test");
let _ = window.set_cursor_grab(CursorGrabMode::Locked);
window.set_cursor_visible(false);
let mut input = input_map!(
(Jump, KeyCode::Space),
(Exit, KeyCode::Escape),
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Forward, KeyCode::ArrowUp, KeyCode::KeyW),
(Back, KeyCode::ArrowDown, KeyCode::KeyS)
);
let (indices, verts, norms) = mesh!(
&display, &teapot::INDICES, &teapot::VERTICES, &teapot::NORMALS
);
let draw_parameters = DrawParameters {
backface_culling: draw_parameters::BackfaceCullingMode::CullClockwise,
..params::alias_3d()
};
let program = Program::from_source(
&display, shaders::VERTEX,
"#version 140
out vec4 colour;
in vec3 v_normal;
uniform vec3 light;
const vec3 albedo = vec3(0.1, 1.0, 0.3);
void main(){
float light_level = dot(light, v_normal);
colour = vec4(albedo * light_level, 1.0);
}", None,
).unwrap();
let mut pos = vec3(0.0, 0.0, -30.0);
let mut rot = vec2(0.0, 0.0);
let mut gravity = 0.0;
const DELTA: f32 = 0.016;
thin_engine::run(event_loop, &mut input, |input, target| {
display.resize(window.inner_size().into());
let mut frame = display.draw();
let view = Mat4::view_matrix_3d(frame.get_dimensions(), 1.0, 1024.0, 0.1);
//handle gravity and jump
gravity += DELTA * 9.5;
if input.pressed(Jump) {
gravity = -10.0;
}
//set camera rotation
rot += input.mouse_move.scale(DELTA * 2.0);
rot.y = rot.y.clamp(-PI / 2.0, PI / 2.0);
let rx = Quaternion::from_y_rot(rot.x);
let ry = Quaternion::from_x_rot(rot.y);
let rot = rx * ry;
//move player based on view and gravity
let x = input.axis(Right, Left);
let y = input.axis(Forward, Back);
let move_dir = vec3(x, 0.0, y).normalise();
pos += move_dir.transform(&Mat3::from_rot(rx)).scale(5.0 * DELTA);
pos.y = (pos.y - gravity * DELTA).max(0.0);
if input.pressed(Exit) { target.exit() }
frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
//draw teapot
frame.draw(
(&verts, &norms), &indices,
&program, &uniform! {
view: view,
model: Mat4::from_scale(Vec3::splat(0.1)),
camera: Mat4::from_inverse_transform(pos, Vec3::ONE, rot),
light: vec3(1.0, -0.9, -1.0).normalise()
},
&draw_parameters,
).unwrap();
frame.finish().unwrap();
thread::sleep(Duration::from_millis(16));
}).unwrap();
}
More examples
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
fn main() {
use Action::*;
let (event_loop, window, display) = thin_engine::set_up().unwrap();
window.set_title("FXAA Test");
let _ = window.set_cursor_grab(CursorGrabMode::Locked);
window.set_cursor_visible(false);
let mut colour = ResizableTexture2D::default();
let mut depth = ResizableDepthTexture2D::default();
let mut input = input_map!(
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Forward, KeyCode::ArrowUp, KeyCode::KeyW),
(Back, KeyCode::ArrowDown, KeyCode::KeyS),
(FXAA, KeyCode::KeyF),
(Jump, KeyCode::Space)
);
let (screen_indices, verts, uvs) = mesh!(
&display, &screen::INDICES, &screen::VERTICES, &screen::UVS
);
let screen_mesh = (&verts, &uvs);
let (indices, verts, norms) = mesh!(
&display, &teapot::INDICES, &teapot::VERTICES, &teapot::NORMALS
);
let teapot_mesh = (&verts, &norms);
let draw_parameters = DrawParameters {
backface_culling: draw_parameters::BackfaceCullingMode::CullClockwise,
..params::alias_3d()
};
let mut fxaa_on = true;
let program = Program::from_source(
&display, shaders::VERTEX,
"#version 140
out vec4 colour;
in vec3 v_normal;
uniform vec3 light;
uniform mat4 camera;
uniform vec3 ambient;
uniform vec3 albedo;
uniform float shine;
void main() {
vec3 camera_dir = inverse(mat3(camera)) * vec3(0, 0, -1);
vec3 half_dir = normalize(camera_dir + light);
float specular = pow(max(dot(half_dir, v_normal), 0.0), shine);
float light_level = max(dot(light, v_normal), 0.0);
colour = vec4(albedo * light_level + ambient + vec3(specular), 1.0);
}", None
).unwrap();
let normal = Program::from_source(
&display, shaders::SCREEN_VERTEX,
"#version 140
in vec2 uv;
uniform sampler2D tex;
out vec4 colour;
void main() {
colour = texture(tex, uv);
}", None
).unwrap();
let fxaa = shaders::fxaa_shader(&display).unwrap();
let mut pos = vec3(0.0, 0.0, -30.0);
let mut rot = vec2(0.0, 0.0);
const DELTA: f32 = 0.016;
thin_engine::run(event_loop, &mut input, |input, _| {
// using a small resolution to show the effect.
// `let size = window.inner_size().into();`
// can be used instead to set resolution to window size
let size = (380, 216);
display.resize(size);
depth.resize_to_display(&display);
colour.resize_to_display(&display);
//press f to toggle FXAA
if input.pressed(FXAA) { fxaa_on = !fxaa_on }
let colour = colour.texture.as_ref().unwrap();
let depth = depth.texture.as_ref().unwrap();
let mut frame = SimpleFrameBuffer::with_depth_buffer(
&display, colour, depth
).unwrap();
let view = Mat4::view_matrix_3d(size, 1.0, 1024.0, 0.1);
//set camera rotation
rot += input.mouse_move.scale(DELTA * 2.0);
rot.y = rot.y.clamp(-PI / 2.0, PI / 2.0);
let rx = Quaternion::from_y_rot(rot.x);
let ry = Quaternion::from_x_rot(rot.y);
let rot = rx * ry;
//move player based on view
let x = input.axis(Right, Left);
let y = input.axis(Forward, Back);
let move_dir = vec3(x, 0.0, y).normalise().scale(5.0*DELTA);
pos += move_dir.transform(&Mat3::from_rot(rx));
frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
//draw teapot
frame.draw(
teapot_mesh, &indices,
&program, &uniform! {
view: view,
model: Mat4::from_scale(Vec3::splat(0.1)),
camera: Mat4::from_inverse_transform(pos, Vec3::ONE, rot),
light: vec3(0.1, 0.25, -1.0).normalise(),
albedo: vec3(0.5, 0.1, 0.4),
ambient: vec3(0.0, 0.05, 0.1),
shine: 50.0f32,
},
&draw_parameters,
).unwrap();
let mut frame = display.draw();
frame.draw(
screen_mesh, &screen_indices, if fxaa_on { &fxaa } else { &normal },
&shaders::fxaa_uniforms(colour), &DrawParameters::default()
).unwrap();
frame.finish().unwrap();
thread::sleep(Duration::from_millis(16));
}).unwrap();
}
Auto Trait Implementations§
impl<const BINDS: usize> Freeze for InputMap<BINDS>
impl<const BINDS: usize> RefUnwindSafe for InputMap<BINDS>
impl<const BINDS: usize> Send for InputMap<BINDS>
impl<const BINDS: usize> Sync for InputMap<BINDS>
impl<const BINDS: usize> Unpin for InputMap<BINDS>
impl<const BINDS: usize> UnwindSafe for InputMap<BINDS>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.