0x02. Processing window closed

Time:2021-11-29

In the previous article, we used sdl2 to display a window. At that time, we made the thread sleep for 10 seconds and looked at the appearance of a window. Now we want to close the window through our active trigger event. Otherwise, it will run all the time

Keep the window displayed

It’s easy to keep the window displayed. Based on the original code, it can be solved through an endless loop

use sdl2::pixels::Color;

fn main() {
    let sdl2_context = sdl2::init().unwrap();
    let video = sdl2_context.video().unwrap();
    let window = video
        .window("Arcade Shooter", 800, 600)
        .position_centered()
        .opengl()
        .build()
        .unwrap();
    let mut canvas = window.renderer().accelerated().build().unwrap();
    canvas.set_draw_color(Color::RGB(0, 0, 0));
    canvas.clear();
    canvas.present();
    'running: loop {}
}

Rust has oneloopThe way of circulation,'runningYou can ignore it. It’s just a life cycle mark. Now the state of the program is not a normal state. After that, the program should be closed under the control of the user

Let the window close

rust-sdl2The event control method of is in its GitHub warehouse examples, just like this, by callingsdl2_contextofevent_pumpFunction to obtain the event set of sdl2, and then traverse through the event set in the looppoll_iterFunction to get the polling iterator

let mut event_pump = sdl2_context.event_pump().unwrap();
'running: loop {
    for event in event_pump.poll_iter() {
        match event {
            Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                break 'running
            },
            _ => {}
        }
    }
}

The event we want to deal with is the programQuitEvents and keyboard pressedescapeNow let’s create a file calledevents.rs, putmain.rsUnder the same level directory

use sdl2::EventPump;

pub struct Events {
    pump: EventPump,
    pub quit: bool,
    pub key_escape: bool,
}

impl Events {
    pub fn new(pump: EventPump) -> Self {
        Self {
            pump,
            quit: false,
            key_escape: false,
        }
    }
    pub fn pump(&mut self) {
        for event in self.pump.poll_iter() {
            use sdl2::event::Event::*;
            use sdl2::keyboard::Keycode::*;
            match event {
                Quit { .. } => self.quit = true,
                KeyDown {
                    keycode: Some(Escape),
                    ..
                } => self.key_escape = true,
                _ => {}
            }
        }
    }
}

Now you can see an events structure. The rust structure is first understood in other languagesclass, we can give oneclassTo define attributes, you can also add construction methods. For general methods, you can also useprivate, public, protectedThis kind of keyword controls the access permission of attributes. The rust structure also has this kind of feature, but the difference is that it doesn’tprotectedControl of
There is no strictly named construction method for rust structure, which is used according to conventionnew, you can also use it as long as you need itcreate, foo, bar… and other functions as construction methods
A very useful syntax of rust is pattern matchingAppleThe new language pattern matching produced every year is easier to play. It has powerful functions,matchA bunch of regular expressions can be followed. What kind of bike do you want

Now the structure is definedquit, key_escapeThese are used to mark status changesboolType properties, andpumpProperty is used for internal functions. It is not usedpubKeyword to open for external use
We seepumpThe function has aselfThis parameter can be understood as representing the structure instance itself. With this parameter, you can use theselfUse the attribute of the instance itself. Since we are going to modify the attribute value of the instance itself in this function, we usemutTo achieve variable effects. As for&This symbol, if you want the instance to callpumpFunction can continue to be used. You have to transfer it by borrowingself.

Then inmain.rsUse our event handler in

#![feature(uniform_paths)]

use sdl2::pixels::Color;
mod events;
use events::Events;

fn main() {
    let sdl2_context = sdl2::init().unwrap();
    let video = sdl2_context.video().unwrap();
    let window = video
        .window("Arcade Shooter", 800, 600)
        .position_centered()
        .opengl()
        .build()
        .unwrap();
    let mut canvas = window.renderer().accelerated().build().unwrap();
    canvas.set_draw_color(Color::RGB(0, 0, 0));
    canvas.clear();
    canvas.present();
    let mut event = Events::new(sdl2_context.event_pump().unwrap());

    'running: loop {
        event.pump();
        if event.quit || event.key_escape { break 'running; }
    }
}

#![feature(uniform_paths)]This paragraph is used to use the new features of rust, because I want to make it easier to use oureventsModule, and then you can directlymainUse in functionEventsThe structure is

The logic behind is very simple, calling each time in the loop.event.pumpTo determine whether to stop the cycle according to the triggered event modification state


In this article, we use a markedloopLoop keeps the program available. Through a structure, useimpl FooAdd a function to the structure in the way of. You can learn that the function can beselfUse the instance itself. We can also usematchPattern matching is used to deal with many cases of data
Let’s do it first

This work adoptsCC agreement, reprint must indicate the author and the link to this article