Skip to main content

Events

Struct Events 

Source
pub struct Events<E: Event> { /* private fields */ }
Expand description

ECS-compatible resource wrapper for event queues.

Events<E> wraps an EventQueue<E> and provides a high-level API suitable for use as an ECS resource. It manages the event lifecycle automatically and provides convenient accessor methods.

§Resource Integration

In a typical ECS architecture, Events<E> is stored as a resource in the World. Systems that need to send or receive events request it via the resource system.

§Frame Lifecycle

The update() method must be called once per frame (typically at the start or end of the frame) to:

  1. Swap the double buffers
  2. Clear stale events from the previous frame

This ensures events persist for exactly one frame after being sent.

§Example

use goud_engine::core::event::Events;

#[derive(Debug, Clone)]
struct DamageEvent {
    entity_id: u32,
    amount: i32,
}

// Create the events resource
let mut events: Events<DamageEvent> = Events::new();

// Systems can send events
events.send(DamageEvent { entity_id: 1, amount: 50 });
events.send(DamageEvent { entity_id: 2, amount: 25 });

// At frame boundary, call update
events.update();

// Now systems can read the events
let mut reader = events.reader();
for event in reader.read() {
    println!("Entity {} took {} damage", event.entity_id, event.amount);
}

§Thread Safety

Events<E> is Send + Sync when E is Send + Sync, enabling safe use in multi-threaded ECS systems.

Implementations§

Source§

impl<E: Event> Events<E>

Source

pub fn new() -> Self

Creates a new empty Events resource.

§Example
use goud_engine::core::event::Events;

struct MyEvent { data: i32 }
let events: Events<MyEvent> = Events::new();
Source

pub fn reader(&self) -> EventReader<'_, E>

Creates an EventReader for reading events from this resource.

Multiple readers can be created simultaneously, as they only require shared access to the underlying queue.

§Example
use goud_engine::core::event::Events;

#[derive(Debug)]
struct MyEvent { id: u32 }

let mut events: Events<MyEvent> = Events::new();
events.send(MyEvent { id: 1 });
events.update();

let mut reader = events.reader();
for event in reader.read() {
    println!("Got event: {:?}", event);
}
Source

pub fn writer(&mut self) -> EventWriter<'_, E>

Creates an EventWriter for sending events to this resource.

Only one writer can exist at a time due to the mutable borrow requirement.

§Example
use goud_engine::core::event::Events;

struct SpawnEvent { entity_type: String }

let mut events: Events<SpawnEvent> = Events::new();

{
    let mut writer = events.writer();
    writer.send(SpawnEvent { entity_type: "enemy".to_string() });
    writer.send(SpawnEvent { entity_type: "item".to_string() });
}
Source

pub fn send(&mut self, event: E)

Sends an event directly to the write buffer.

This is a convenience method equivalent to creating a writer and calling send() on it.

§Example
use goud_engine::core::event::Events;

struct InputEvent { key: char }

let mut events: Events<InputEvent> = Events::new();
events.send(InputEvent { key: 'w' });
events.send(InputEvent { key: 'a' });
Source

pub fn send_batch(&mut self, events: impl IntoIterator<Item = E>)

Sends multiple events to the write buffer in batch.

More efficient than calling send() multiple times when you have a collection of events.

§Example
use goud_engine::core::event::Events;

#[derive(Clone)]
struct ParticleEvent { x: f32, y: f32 }

let mut events: Events<ParticleEvent> = Events::new();
let particles = vec![
    ParticleEvent { x: 0.0, y: 0.0 },
    ParticleEvent { x: 1.0, y: 1.0 },
    ParticleEvent { x: 2.0, y: 2.0 },
];
events.send_batch(particles);
Source

pub fn update(&mut self)

Updates the event system at frame boundary.

This method MUST be called exactly once per frame, typically at the start or end of the game loop. It:

  1. Clears events from the previous read buffer (they’ve had their chance)
  2. Swaps the buffers so newly written events become readable
§Frame Timing
Frame N:
  1. update() called - events from Frame N-1 become readable
  2. Systems read events
  3. Systems write new events

Frame N+1:
  1. update() called - Frame N-1 events cleared, Frame N events readable
  ... and so on
§Important
  • Calling update() more than once per frame will cause events to be lost (the write buffer gets swapped to read before systems can write)
  • Not calling update() will cause events to accumulate and never become readable
§Example
use goud_engine::core::event::Events;

struct GameEvent;

let mut events: Events<GameEvent> = Events::new();

// Game loop
for frame in 0..3 {
    // Start of frame: update events
    events.update();

    // Read events from previous frame
    let mut reader = events.reader();
    for _ in reader.read() {
        // Process events...
    }

    // Systems write new events
    events.send(GameEvent);
}
Source

pub fn drain(&mut self) -> impl Iterator<Item = E> + '_

Drains all events from the read buffer, consuming them.

Unlike using a reader, this removes the events entirely from the buffer.

§Example
use goud_engine::core::event::Events;

struct Event { id: u32 }

let mut events: Events<Event> = Events::new();
events.send(Event { id: 1 });
events.send(Event { id: 2 });
events.update();

let collected: Vec<Event> = events.drain().collect();
assert_eq!(collected.len(), 2);
Source

pub fn clear(&mut self)

Clears all events from both buffers.

Use this when transitioning between game states or when you need to discard all pending events.

§Example
use goud_engine::core::event::Events;

struct Event;

let mut events: Events<Event> = Events::new();
events.send(Event);
events.update();
events.send(Event);

events.clear();
assert!(events.is_empty());
Source

pub fn is_empty(&self) -> bool

Returns true if no events are pending in the write buffer.

Note: The read buffer may still contain events from the previous frame.

§Example
use goud_engine::core::event::Events;

struct Event;

let mut events: Events<Event> = Events::new();
assert!(events.is_empty());

events.send(Event);
assert!(!events.is_empty());
Source

pub fn len(&self) -> usize

Returns the number of events in the write buffer.

§Example
use goud_engine::core::event::Events;

struct Event;

let mut events: Events<Event> = Events::new();
events.send(Event);
events.send(Event);

assert_eq!(events.len(), 2);
Source

pub fn read_len(&self) -> usize

Returns the number of events available for reading.

§Example
use goud_engine::core::event::Events;

struct Event;

let mut events: Events<Event> = Events::new();
events.send(Event);
events.send(Event);

// Events are in write buffer
assert_eq!(events.read_len(), 0);

events.update();

// Now in read buffer
assert_eq!(events.read_len(), 2);
Source

pub fn read_buffer(&self) -> &[E]

Returns a slice of events available for reading.

This provides direct access to the read buffer, enabling cursor-based reading patterns used by ECS system parameters.

§Example
use goud_engine::core::event::Events;

struct Event { id: u32 }

let mut events: Events<Event> = Events::new();
events.send(Event { id: 1 });
events.send(Event { id: 2 });
events.update();

let buffer = events.read_buffer();
assert_eq!(buffer.len(), 2);

Trait Implementations§

Source§

impl<E: Event> Default for Events<E>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<E> Freeze for Events<E>

§

impl<E> RefUnwindSafe for Events<E>
where E: RefUnwindSafe,

§

impl<E> Send for Events<E>

§

impl<E> Sync for Events<E>

§

impl<E> Unpin for Events<E>
where E: Unpin,

§

impl<E> UnsafeUnpin for Events<E>

§

impl<E> UnwindSafe for Events<E>
where E: 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<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, 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<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
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 = 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<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> Event for T
where T: Send + Sync + 'static,

Source§

impl<T> Resource for T
where T: Send + Sync + 'static,