1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 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
 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
use std::path::PathBuf;

use crate::input::{GamepadAxis, GamepadButton, GamepadStick, Key, MouseButton};
use crate::math::Vec2;
use crate::{Context, TetraError};

/// Implemented by types that contain game state and provide logic for updating it
/// and drawing it to the screen.
///
/// The methods on `State` allow you to return a [`Result`], either explicitly or via the `?`
/// operator. If an error is returned, the game will close and the error will be returned from
/// the [`Context::run`] call that was used to start it. This allows you to propagate errors
/// back to `main` for reporting/logging.
///
/// The error type defaults to [`TetraError`], but this can be overridden by adding a type parameter
/// to your `State` implementation (e.g. `State<MyError>`).
#[allow(unused_variables)]
pub trait State<E = TetraError> {
    /// Called when it is time for the game to update.
    fn update(&mut self, ctx: &mut Context) -> Result<(), E> {
        Ok(())
    }

    /// Called when it is time for the game to be drawn.
    fn draw(&mut self, ctx: &mut Context) -> Result<(), E> {
        Ok(())
    }

    /// Called when a window or input event occurs.
    fn event(&mut self, ctx: &mut Context, event: Event) -> Result<(), E> {
        Ok(())
    }
}

/// Events that can occur while the game is running.
///
/// [`State::event`] will receive events as they occur.
///
/// # Examples
///
/// The [`events`](https://github.com/17cupsofcoffee/tetra/blob/main/examples/events.rs)
/// example demonstrates how to handle events.
#[non_exhaustive]
#[derive(Debug, Clone)]
pub enum Event {
    /// The game window was resized.
    Resized {
        /// The new width of the game window.
        width: i32,

        /// The new height of the game window.
        height: i32,
    },

    /// The game window was focused by the user.
    FocusGained,

    /// The game window was un-focused by the user.
    FocusLost,

    /// A key on the keyboard was pressed.
    KeyPressed {
        /// The key that was pressed.
        key: Key,
    },

    /// A key on the keyboard was released.
    KeyReleased {
        /// The key that was released.
        key: Key,
    },

    /// A button on the mouse was pressed.
    MouseButtonPressed {
        /// The button that was pressed.
        button: MouseButton,
    },

    /// A button on the mouse was released.
    MouseButtonReleased {
        /// The button that was released.
        button: MouseButton,
    },

    /// The mouse was moved.
    MouseMoved {
        /// The new position of the mouse, in window co-ordinates.
        ///
        /// If [relative mouse mode](crate::window::set_relative_mouse_mode) is
        /// enabled, this field is not guarenteed to update.
        position: Vec2<f32>,

        /// The movement of the mouse, relative to the `position` of the previous
        /// `MouseMoved` event.
        delta: Vec2<f32>,
    },

    /// The mouse wheel was moved.
    MouseWheelMoved {
        /// The amount that the wheel was moved.
        ///
        /// Most 'normal' mice can only scroll vertically, but some devices can also scroll horizontally.
        /// Use the Y component of the returned vector if you don't care about horizontal scroll.
        ///
        /// Positive values correspond to scrolling up/right, negative values correspond to scrolling
        /// down/left.
        amount: Vec2<i32>,
    },

    /// A gamepad was connected to the system.
    GamepadAdded {
        /// The ID that was assigned to the gamepad.
        id: usize,
    },

    /// A gamepad was removed from the system.
    GamepadRemoved {
        /// The ID of the gamepad that was removed.
        id: usize,
    },

    /// A button on a gamepad was pressed.
    GamepadButtonPressed {
        /// The ID of the gamepad.
        id: usize,

        /// The button that was pressed.
        button: GamepadButton,
    },

    /// A button on a gamepad was released.
    GamepadButtonReleased {
        /// The ID of the gamepad.
        id: usize,

        /// The button that was released.
        button: GamepadButton,
    },

    /// An axis on a gamepad was moved.
    GamepadAxisMoved {
        /// The ID of the gamepad.
        id: usize,

        /// The axis that was moved.
        axis: GamepadAxis,

        /// The new position of the axis.
        position: f32,
    },

    /// A control stick on a gamepad was moved.
    GamepadStickMoved {
        /// The ID of the gamepad.
        id: usize,

        /// The stick that was moved.
        stick: GamepadStick,

        /// The new position of the stick.
        position: Vec2<f32>,
    },

    /// The user typed some text.
    TextInput {
        /// The text that was typed by the user.
        text: String,
    },

    /// The user dropped a file into the window.
    ///
    /// This event will be fired multiple times if the user dropped multiple files at the
    /// same time.
    ///
    /// Note that on MacOS, you must [edit your `info.plist` file to set which document types
    /// you want your application to support](https://help.apple.com/xcode/mac/current/#/devddd273fdd),
    /// otherwise no `FileDropped` events will be fired.
    FileDropped {
        /// The path of the file that was dropped.
        path: PathBuf,
    },
}