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
//! Type-safe event system for the Deepslate proxy.
//!
//! Inspired by [Velocity's event system](https://docs.papermc.io/velocity/dev/event-system),
//! this module provides a type-safe publish-subscribe event system where:
//!
//! - **Events are plain structs** — no required base trait or common ancestor.
//! - **Result-based outcomes** — events that can be cancelled or modified implement
//! [`ResultedEvent`] with domain-specific result enums (e.g., `Allow`/`Deny`).
//! - **Priority ordering** — handlers execute in priority order ([`PostOrder`]),
//! so multiple plugins can cooperate on the same event.
//! - **Compile-time type safety** — the [`EventManager::subscribe`] API is fully
//! generic; internal storage uses type-erased trait objects keyed by [`TypeId`].
//!
//! # Plugin Model
//!
//! Rather than implementing a monolithic trait with one method per event, plugins
//! implement the [`Plugin`] trait and register individual event handlers during
//! startup:
//!
//! ```rust,no_run
//! use deepslate::event::*;
//! use deepslate::event::events::*;
//!
//! struct MyPlugin;
//!
//! impl Plugin for MyPlugin {
//! fn register(&self, events: &mut EventManager) {
//! events.subscribe::<LoginEvent>(PostOrder::NORMAL, |event| {
//! if event.player.profile.name == "griefer" {
//! event.set_result(LoginResult::Deny("Not allowed".into()));
//! }
//! });
//!
//! events.subscribe::<DisconnectEvent>(PostOrder::NORMAL, |event| {
//! println!("Player left: {}", event.player.profile.name);
//! });
//! }
//! }
//! ```
use TypeId;
use HashMap;
use GameProfile;
pub use *;
pub use PostOrder;
pub use ;
use ;
/// Information about a connected player, passed to event handlers.
/// Central event dispatcher.
///
/// Stores type-erased handlers keyed by event [`TypeId`]. Handlers are sorted
/// by priority at registration time and dispatched sequentially when an event
/// is fired.
///
/// The `EventManager` is built during proxy startup (plugins register handlers
/// via [`Plugin::register`]), then wrapped in an `Arc` and shared across async
/// tasks as an immutable reference.
/// Trait that plugins implement to hook into the proxy lifecycle.
///
/// Instead of overriding hardcoded event methods, plugins register individual
/// event handlers with the [`EventManager`] during the [`register`](Plugin::register)
/// call. This allows multiple plugins to subscribe to the same events with
/// independent priority ordering.
///
/// The trait requires `Send + Sync + 'static` because plugin references are
/// shared during the registration phase.
///
/// # Example
///
/// ```rust,no_run
/// use deepslate::event::*;
/// use deepslate::event::events::*;
///
/// struct LobbyPlugin;
///
/// impl Plugin for LobbyPlugin {
/// fn register(&self, events: &mut EventManager) {
/// events.subscribe::<ChooseServerEvent>(PostOrder::NORMAL, |event| {
/// event.set_result(ChooseServerResult::Override("lobby".into()));
/// });
/// }
/// }
/// ```