Struct DisplayInfo

Source
pub struct DisplayInfo { /* private fields */ }
Expand description

Information about the screen size.

Implementations§

Source§

impl DisplayInfo

Source

pub fn new(width: usize, height: usize) -> Self

Source

pub fn width(&self) -> usize

Returns the width of the screen.

Examples found in repository?
examples/exponentialgrowingboundschecker.rs (line 67)
65    fn setup(&mut self, setup_info: &SetupInfo, shared_state: &mut SharedState<()>) {
66        self.on_resize(
67            setup_info.display_info.width(),
68            setup_info.display_info.height(),
69            shared_state,
70        );
71    }
More examples
Hide additional examples
examples/falling-sand/main.rs (line 287)
281    fn setup(
282        &mut self,
283        setup_info: &SetupInfo,
284        shared_state: &mut SharedState<FallingSimulationData>,
285    ) {
286        self.on_resize(
287            setup_info.display_info.width(),
288            setup_info.display_info.height(),
289            shared_state,
290        );
291    }
examples/ecs/main.rs (line 177)
176    fn setup(&mut self, setup_info: &SetupInfo, shared_state: &mut SharedState<Ecs>) {
177        self.width = setup_info.display_info.width();
178        self.height = setup_info.display_info.height();
179
180        let ecs = &mut shared_state.custom;
181        ecs.components.register::<Position>();
182        ecs.components.register::<Draw>();
183    }
examples/simple.rs (line 12)
11    fn render(&self, renderer: &mut dyn Renderer, shared_state: &SharedState, depth_base: i32) {
12        let width = shared_state.display_info.width();
13        let height = shared_state.display_info.height();
14        let x = width / 2;
15        let y = height / 2;
16        let pixel = Pixel::new('█').with_color([0, 255, 0]);
17        renderer.render_pixel(x, y, pixel, depth_base);
18
19        "Hello World"
20            .with_bg_color([255, 0, 0])
21            .render(renderer, x, y + 1, depth_base);
22    }
examples/fpschecker.rs (line 47)
40    fn render(&self, renderer: &mut dyn Renderer, shared_state: &SharedState, depth_base: i32) {
41        // render a block at half height and x corresponding to the position at 144 blocks per second
42        let elapsed = Instant::now() - self.start_time;
43        let time_per_frame = 1.0 / 144.0;
44        let frame = (elapsed.as_secs_f64() / time_per_frame) as usize;
45        let y = shared_state.display_info.height() / 2;
46        // bounce x back and forth
47        let x = frame % (shared_state.display_info.width() * 2);
48        let pixel = Pixel::new('█');
49        if x < shared_state.display_info.width() {
50            renderer.render_pixel(x, y, pixel, i32::MAX);
51        } else {
52            renderer.render_pixel(
53                shared_state.display_info.width() * 2 - x - 1,
54                y,
55                pixel,
56                i32::MAX,
57            );
58        }
59    }
60}
61
62/// Movement speed is tied to framerate. Moves 1px/frame.
63pub struct FpsCheckerFrameCountComponent {
64    count: usize,
65}
66
67impl FpsCheckerFrameCountComponent {
68    pub fn new() -> Self {
69        Self { count: 0 }
70    }
71}
72
73impl Component for FpsCheckerFrameCountComponent {
74    fn update(&mut self, update_info: UpdateInfo, shared_state: &mut SharedState) {
75        self.count += 1;
76    }
77
78    fn render(&self, renderer: &mut dyn Renderer, shared_state: &SharedState, depth_base: i32) {
79        let y = shared_state.display_info.height() / 2;
80        // bounce x back and forth
81        let x = self.count % (shared_state.display_info.width() * 2);
82        let pixel = Pixel::new('█');
83        if x < shared_state.display_info.width() {
84            renderer.render_pixel(x, y, pixel, i32::MAX);
85        } else {
86            renderer.render_pixel(
87                shared_state.display_info.width() * 2 - x - 1,
88                y,
89                pixel,
90                i32::MAX,
91            );
92        }
93    }
Source

pub fn height(&self) -> usize

Returns the height of the screen.

Examples found in repository?
examples/exponentialgrowingboundschecker.rs (line 68)
65    fn setup(&mut self, setup_info: &SetupInfo, shared_state: &mut SharedState<()>) {
66        self.on_resize(
67            setup_info.display_info.width(),
68            setup_info.display_info.height(),
69            shared_state,
70        );
71    }
More examples
Hide additional examples
examples/ecs/main.rs (line 64)
57    fn update(&mut self, _update_info: teng::UpdateInfo, shared_state: &mut SharedState<Ecs>) {
58        let ecs = &mut shared_state.custom;
59        for &entity in &ecs.entities {
60            let Some(position) = ecs.components.get_mut_from_entity::<Position>(entity) else {
61                continue;
62            };
63            position.y += 1;
64            if position.y >= shared_state.display_info.height() {
65                position.y = 0;
66            }
67        }
68    }
69}
70
71fn main() -> io::Result<()> {
72    teng::terminal_setup()?;
73    teng::install_panic_handler();
74
75    let mut game = Game::new(stdout());
76    game.install_recommended_components();
77    game.add_component(Box::new(EcsComponent::default()));
78    game.add_component(Box::new(DrawSystem));
79    game.add_component(Box::new(PhysicsSystem));
80    game.run()?;
81
82    teng::terminal_cleanup()?;
83    Ok(())
84}
85
86struct ComponentList {
87    inner: AnyMap,
88}
89
90impl Default for ComponentList {
91    fn default() -> Self {
92        Self::new()
93    }
94}
95
96impl ComponentList {
97    fn new() -> Self {
98        Self {
99            inner: AnyMap::new(),
100        }
101    }
102
103    fn add_to_entity<T: 'static>(&mut self, entity: Entity, component: T) {
104        let map = self.get_mut::<T>().expect("Component not registered");
105        map.insert(entity, component);
106    }
107
108    fn get_from_entity<T: 'static>(&self, entity: Entity) -> Option<&T> {
109        let map = self.get::<T>()?;
110        map.get(&entity)
111    }
112
113    fn get_mut_from_entity<T: 'static>(&mut self, entity: Entity) -> Option<&mut T> {
114        let map = self.get_mut::<T>()?;
115        map.get_mut(&entity)
116    }
117
118    fn get<T: 'static>(&self) -> Option<&HashMap<Entity, T>> {
119        self.inner.get::<HashMap<Entity, T>>()
120    }
121
122    fn get_mut<T: 'static>(&mut self) -> Option<&mut HashMap<Entity, T>> {
123        self.inner.get_mut::<HashMap<Entity, T>>()
124    }
125
126    fn register<T: 'static>(&mut self) {
127        self.inner.insert::<HashMap<Entity, T>>(HashMap::new());
128    }
129}
130
131/// Shared state for ECS.
132#[derive(Default)]
133struct Ecs {
134    entities: Vec<Entity>,
135    max_key: usize,
136    components: ComponentList,
137}
138
139impl Ecs {
140    fn new() -> Self {
141        Self {
142            entities: Vec::new(),
143            max_key: 0,
144            components: ComponentList::new(),
145        }
146    }
147
148    fn create_entity(&mut self) -> Entity {
149        let entity = Entity(self.max_key);
150        self.entities.push(entity);
151        self.max_key += 1;
152        entity
153    }
154
155    fn add_component<T: 'static>(&mut self, entity: Entity, component: T) {
156        self.components.add_to_entity(entity, component);
157    }
158
159    fn get_component<T: 'static>(&self, entity: Entity) -> Option<&T> {
160        self.components.get_from_entity(entity)
161    }
162
163    fn get_mut_component<T: 'static>(&mut self, entity: Entity) -> Option<&mut T> {
164        self.components.get_mut_from_entity(entity)
165    }
166}
167
168/// A wrapper component that sets up the ECS and creates new entities.
169#[derive(Default)]
170struct EcsComponent {
171    width: usize,
172    height: usize,
173}
174
175impl TengComponent<Ecs> for EcsComponent {
176    fn setup(&mut self, setup_info: &SetupInfo, shared_state: &mut SharedState<Ecs>) {
177        self.width = setup_info.display_info.width();
178        self.height = setup_info.display_info.height();
179
180        let ecs = &mut shared_state.custom;
181        ecs.components.register::<Position>();
182        ecs.components.register::<Draw>();
183    }
examples/simple.rs (line 13)
11    fn render(&self, renderer: &mut dyn Renderer, shared_state: &SharedState, depth_base: i32) {
12        let width = shared_state.display_info.width();
13        let height = shared_state.display_info.height();
14        let x = width / 2;
15        let y = height / 2;
16        let pixel = Pixel::new('█').with_color([0, 255, 0]);
17        renderer.render_pixel(x, y, pixel, depth_base);
18
19        "Hello World"
20            .with_bg_color([255, 0, 0])
21            .render(renderer, x, y + 1, depth_base);
22    }
examples/falling-sand/main.rs (line 223)
210    fn update_render(&mut self, data: &FallingSimulationData, display_info: &DisplayInfo) {
211        // TODO: add display here
212
213        for x in data.world.x_range() {
214            for y in data.world.y_range() {
215                let piece = data.world[(x, y)];
216                let color = match piece.kind {
217                    PieceKind::Air => Color::Transparent,
218                    PieceKind::Sand => Color::Rgb([255, 255, 0]),
219                    PieceKind::Water => Color::Rgb([0, 0, 255]),
220                };
221                let d_x = x;
222                let d_y = y;
223                let d_y = 2 * display_info.height() as i64 - d_y;
224                let d_y = d_y - 1;
225                self.hb_display.set_color(d_x as usize, d_y as usize, color);
226            }
227        }
228    }
229
230    fn update_simulation(&mut self, shared_state: &mut SharedState<FallingSimulationData>) {
231        let data = &mut shared_state.custom;
232        data.secs_passed += Self::UPDATE_INTERVAL;
233
234        // std::mem::swap(&mut data.world, &mut data.old_world);
235        // data.world.clear(Piece { kind: PieceKind::Air });
236
237        data.has_moved.clear(false);
238
239        data.total_pieces = 0;
240
241        // go over every piece (that is not air) and update it
242        for x in data.world.x_range() {
243            for y in data.world.y_range().rev() {
244                if data.has_moved[(x, y)] {
245                    continue;
246                }
247                let piece = data.world[(x, y)];
248                if piece.kind == PieceKind::Air {
249                    continue;
250                }
251
252                match piece.kind {
253                    PieceKind::Air => {
254                        // do nothing
255                    }
256                    PieceKind::Sand => {
257                        data.sim_sand((x, y));
258                    }
259                    PieceKind::Water => {
260                        data.sim_water((x, y));
261                    }
262                }
263                data.has_moved[(x, y)] = true;
264            }
265        }
266
267        for x in data.world.x_range() {
268            for y in data.world.y_range() {
269                let piece = data.world[(x, y)];
270                if piece.kind != PieceKind::Air {
271                    data.total_pieces += 1;
272                }
273            }
274        }
275
276        self.update_render(data, &shared_state.display_info);
277    }
278}
279
280impl Component<FallingSimulationData> for FallingSimulationComponent {
281    fn setup(
282        &mut self,
283        setup_info: &SetupInfo,
284        shared_state: &mut SharedState<FallingSimulationData>,
285    ) {
286        self.on_resize(
287            setup_info.display_info.width(),
288            setup_info.display_info.height(),
289            shared_state,
290        );
291    }
292
293    fn on_resize(
294        &mut self,
295        width: usize,
296        height: usize,
297        shared_state: &mut SharedState<FallingSimulationData>,
298    ) {
299        self.hb_display.resize_discard(width, height * 2);
300        let data = &mut shared_state.custom;
301        data.resize_discard(width, height * 2);
302    }
303
304    fn update(
305        &mut self,
306        update_info: UpdateInfo,
307        shared_state: &mut SharedState<FallingSimulationData>,
308    ) {
309        let dt = update_info.dt;
310        self.dt_budget += dt;
311
312        // add sand from mouse events
313        let data = &mut shared_state.custom;
314
315        if shared_state.mouse_info.left_mouse_down
316            || shared_state.mouse_info.right_mouse_down
317            || shared_state.mouse_info.middle_mouse_down
318        {
319            let (s_x, s_y) = shared_state.mouse_info.last_mouse_pos;
320
321            let x = s_x as i64;
322            // scale to two halfblocks per pixel and recenter to 0,0
323            let y = shared_state.display_info.height() as i64 - s_y as i64;
324            let y = 2 * y;
325            let y = y - 1;
326
327            if let Some(piece) = data.world.get_mut(x, y) {
328                let kind = if shared_state.mouse_info.left_mouse_down {
329                    PieceKind::Sand
330                } else if shared_state.mouse_info.right_mouse_down {
331                    PieceKind::Water
332                } else {
333                    PieceKind::Air
334                };
335                piece.kind = kind;
336            } else {
337                panic!("Mouse out of bounds: ({}, {})", x, y);
338            }
339        }
340
341        while self.dt_budget >= Self::UPDATE_INTERVAL {
342            self.update_simulation(shared_state);
343            self.dt_budget -= Self::UPDATE_INTERVAL;
344        }
345    }
examples/fpschecker.rs (line 45)
40    fn render(&self, renderer: &mut dyn Renderer, shared_state: &SharedState, depth_base: i32) {
41        // render a block at half height and x corresponding to the position at 144 blocks per second
42        let elapsed = Instant::now() - self.start_time;
43        let time_per_frame = 1.0 / 144.0;
44        let frame = (elapsed.as_secs_f64() / time_per_frame) as usize;
45        let y = shared_state.display_info.height() / 2;
46        // bounce x back and forth
47        let x = frame % (shared_state.display_info.width() * 2);
48        let pixel = Pixel::new('█');
49        if x < shared_state.display_info.width() {
50            renderer.render_pixel(x, y, pixel, i32::MAX);
51        } else {
52            renderer.render_pixel(
53                shared_state.display_info.width() * 2 - x - 1,
54                y,
55                pixel,
56                i32::MAX,
57            );
58        }
59    }
60}
61
62/// Movement speed is tied to framerate. Moves 1px/frame.
63pub struct FpsCheckerFrameCountComponent {
64    count: usize,
65}
66
67impl FpsCheckerFrameCountComponent {
68    pub fn new() -> Self {
69        Self { count: 0 }
70    }
71}
72
73impl Component for FpsCheckerFrameCountComponent {
74    fn update(&mut self, update_info: UpdateInfo, shared_state: &mut SharedState) {
75        self.count += 1;
76    }
77
78    fn render(&self, renderer: &mut dyn Renderer, shared_state: &SharedState, depth_base: i32) {
79        let y = shared_state.display_info.height() / 2;
80        // bounce x back and forth
81        let x = self.count % (shared_state.display_info.width() * 2);
82        let pixel = Pixel::new('█');
83        if x < shared_state.display_info.width() {
84            renderer.render_pixel(x, y, pixel, i32::MAX);
85        } else {
86            renderer.render_pixel(
87                shared_state.display_info.width() * 2 - x - 1,
88                y,
89                pixel,
90                i32::MAX,
91            );
92        }
93    }

Trait Implementations§

Source§

impl Clone for DisplayInfo

Source§

fn clone(&self) -> DisplayInfo

Returns a copy of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more

Auto Trait Implementations§

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<T> CloneToUninit for T
where T: Clone,

Source§

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

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

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> 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> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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> Any for T
where T: Any,

Source§

impl<T> CloneAny for T
where T: Any + Clone,