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
//! Event bus for cross-system communication.
//!
//! A simple message queue for decoupling systems and passing events:
//!
//! - [`EventBus`]: Message queue resource
//! - [`Message`]: Event wrapper (input or custom app events)
//! - [`publish_event`]: Send a message to the bus
//! - [`publish_app_event`]: Send a typed custom event
//!
//! # Publishing Events
//!
//! Send custom events from anywhere:
//!
//! ```ignore
//! use nightshade::ecs::event_bus::publish_app_event;
//!
//! struct EnemyDied { entity: Entity, score: i32 }
//!
//! // When an enemy is defeated
//! publish_app_event(world, EnemyDied { entity, score: 100 });
//! ```
//!
//! # Handling Events
//!
//! Process events in your game loop:
//!
//! ```ignore
//! fn run_systems(&mut self, world: &mut World) {
//! while let Some(message) = world.resources.event_bus.messages.pop_front() {
//! match message {
//! Message::Input { event } => {
//! // Handle input events
//! }
//! Message::App { type_name, payload } => {
//! // Handle custom events
//! if type_name == std::any::type_name::<EnemyDied>() {
//! if let Some(event) = payload.downcast_ref::<EnemyDied>() {
//! self.score += event.score;
//! }
//! }
//! }
//! }
//! }
//! }
//! ```
//!
//! # Message Types
//!
//! | Variant | Description |
//! |---------|-------------|
//! | `Message::Input` | Input events (keyboard, mouse, gamepad) |
//! | `Message::App` | Custom application events with type-erased payload |
//!
//! # Pattern: Event-Driven Systems
//!
//! ```ignore
//! struct PlayerDamaged { amount: i32 }
//! struct PlayerHealed { amount: i32 }
//! struct GameOver;
//!
//! // In combat system
//! if hit_detected {
//! player_health -= damage;
//! publish_app_event(world, PlayerDamaged { amount: damage });
//! if player_health <= 0 {
//! publish_app_event(world, GameOver);
//! }
//! }
//!
//! // In UI system
//! for message in world.resources.event_bus.messages.iter() {
//! if let Message::App { type_name, payload } = message {
//! if type_name == std::any::type_name::<PlayerDamaged>() {
//! // Flash health bar red
//! }
//! }
//! }
//! ```
//!
//! [`EventBus`]: resources::EventBus
//! [`Message`]: resources::Message
//! [`publish_event`]: commands::publish_event
//! [`publish_app_event`]: commands::publish_app_event
pub mod commands;
pub mod resources;
pub mod systems;
pub use commands::*;
pub use resources::*;
pub use systems::*;
use winit::event::WindowEvent;
pub enum EngineEvent<'a> {
Window(&'a WindowEvent),
}