Skip to content

Commit 22d628c

Browse files
feat(hyperion)!: hardcoded SystemId → auto SystemOrder (#661)
Introduces a new `system-order` module to manage system execution ordering dynamically, removing hardcoded system IDs throughout the codebase. Key changes: - Add a new `system-order` crate with depth-based ordering logic - Update system execution to use `EntityView` for system context - Replace `SystemId` constants with dynamic `SystemOrder` values - Update packet handling APIs to receive system context instead of IDs - Refactor bundle management to include system context - Remove redundant world parameters where system context provides it - Fixes #510 Breaking: APIs using `SystemId` must be updated to use the new `SystemOrder` system
1 parent f7a9e00 commit 22d628c

File tree

37 files changed

+701
-667
lines changed

37 files changed

+701
-667
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[profile]
12
[profile.release-debug]
23
debug = true
34
inherits = 'release'
@@ -36,6 +37,7 @@ members = [
3637
'crates/hyperion-item',
3738
'crates/geometry',
3839
'crates/simd-utils',
40+
'crates/system-order',
3941
]
4042
resolver = '2'
4143

@@ -83,7 +85,7 @@ quote = '1.0.37'
8385
rand = '0.8.5'
8486
rayon = '1.10.0'
8587
rkyv = '0.8.8'
86-
rustc-hash = '2.0.0'
88+
rustc-hash = { version = '2.0.0' , features = ["nightly"] }
8789
serde = '1.0.214'
8890
serde_json = '1.0.117'
8991
slotmap = '1.0.7'
@@ -203,6 +205,9 @@ version = '0.10.8'
203205
[workspace.dependencies.simd-utils]
204206
path = 'crates/simd-utils'
205207

208+
[workspace.dependencies.system-order]
209+
path = 'crates/system-order'
210+
206211
[workspace.dependencies.tokio-util]
207212
features = ['full']
208213
version = '0.7.12'
@@ -255,19 +260,17 @@ branch = 'feat-open'
255260
git = 'https://github.com/andrewgazelka/valence'
256261

257262
[workspace.lints]
258-
259263
[workspace.lints.clippy]
260264
cast_precision_loss = 'allow'
261265
future_not_send = 'allow'
262266
missing_errors_doc = 'allow'
263267
missing_panics_doc = 'allow'
264268
module_name_repetitions = 'allow'
269+
print_stdout = 'deny'
265270
single_match_else = 'allow'
266271
too_long_first_doc_paragraph = 'allow'
267272
too_many_lines = 'allow'
268273

269-
print_stdout = 'deny'
270-
271274
[workspace.lints.clippy.complexity]
272275
level = 'deny'
273276
priority = -1

crates/hyperion-clap/src/lib.rs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ use std::iter::zip;
22

33
use clap::{Arg as ClapArg, Parser, ValueEnum, ValueHint, error::ErrorKind};
44
use flecs_ecs::{
5-
core::{Entity, EntityViewGet, World, WorldGet},
5+
core::{Entity, EntityView, EntityViewGet, World, WorldGet, WorldProvider},
66
prelude::{Component, Module},
77
};
88
use hyperion::{
99
net::{Compose, ConnectionId, DataBundle, agnostic},
1010
simulation::{IgnMap, command::get_root_command_entity, handlers::PacketSwitchQuery},
1111
storage::{CommandCompletionRequest, EventFn},
12-
system_registry::SystemId,
1312
};
1413
pub use hyperion_clap_macros::CommandPermission;
1514
pub use hyperion_command;
@@ -24,7 +23,7 @@ use valence_protocol::{
2423
};
2524

2625
pub trait MinecraftCommand: Parser + CommandPermission {
27-
fn execute(self, world: &World, caller: Entity);
26+
fn execute(self, system: EntityView<'_>, caller: Entity);
2827

2928
fn pre_register(_world: &World) {}
3029

@@ -60,8 +59,9 @@ pub trait MinecraftCommand: Parser + CommandPermission {
6059
on = world.entity().set(node_to_register).child_of_id(on);
6160
}
6261

63-
let on_execute = |input: &str, world: &World, caller: Entity| {
62+
let on_execute = |input: &str, system: EntityView<'_>, caller: Entity| {
6463
let input = input.split_whitespace();
64+
let world = system.world();
6565

6666
match Self::try_parse_from(input) {
6767
Ok(elem) => {
@@ -75,16 +75,16 @@ pub trait MinecraftCommand: Parser + CommandPermission {
7575
"§cYou do not have permission to use this command!",
7676
);
7777

78-
let mut bundle = DataBundle::new(compose);
79-
bundle.add_packet(&chat, world).unwrap();
80-
bundle.send(world, *stream, SystemId(8)).unwrap();
78+
let mut bundle = DataBundle::new(compose, system);
79+
bundle.add_packet(&chat).unwrap();
80+
bundle.send(*stream).unwrap();
8181

8282
false
8383
}
8484
},
8585
)
8686
}) {
87-
elem.execute(world, caller);
87+
elem.execute(system, caller);
8888
}
8989
}
9090
Err(e) => {
@@ -102,7 +102,7 @@ pub trait MinecraftCommand: Parser + CommandPermission {
102102
.entity_view(world)
103103
.get::<&hyperion::net::ConnectionId>(|stream| {
104104
let msg = agnostic::chat(msg);
105-
compose.unicast(&msg, *stream, SystemId(8), world).unwrap();
105+
compose.unicast(&msg, *stream, system).unwrap();
106106
});
107107
});
108108

@@ -181,8 +181,7 @@ pub trait MinecraftCommand: Parser + CommandPermission {
181181
.unicast(
182182
&packet,
183183
packet_switch_query.io_ref,
184-
SystemId(0),
185-
packet_switch_query.world,
184+
packet_switch_query.system,
186185
)
187186
.unwrap();
188187

@@ -224,8 +223,7 @@ pub trait MinecraftCommand: Parser + CommandPermission {
224223
.unicast(
225224
&packet,
226225
packet_switch_query.io_ref,
227-
SystemId(0),
228-
packet_switch_query.world,
226+
packet_switch_query.system,
229227
)
230228
.unwrap();
231229
},
@@ -297,7 +295,8 @@ pub enum PermissionCommand {
297295
}
298296

299297
impl MinecraftCommand for PermissionCommand {
300-
fn execute(self, world: &World, caller: Entity) {
298+
fn execute(self, system: EntityView<'_>, caller: Entity) {
299+
let world = system.world();
301300
world.get::<&IgnMap>(|ign_map| {
302301
match self {
303302
Self::Set(cmd) => {
@@ -307,7 +306,7 @@ impl MinecraftCommand for PermissionCommand {
307306
let msg = format!("§c{} not found", cmd.player);
308307
let chat = hyperion::net::agnostic::chat(msg);
309308
world.get::<&Compose>(|compose| {
310-
compose.unicast(&chat, *stream, SystemId(8), world).unwrap();
309+
compose.unicast(&chat, *stream, system).unwrap();
311310
});
312311
});
313312
return;
@@ -326,7 +325,7 @@ impl MinecraftCommand for PermissionCommand {
326325
);
327326
let chat = hyperion::net::agnostic::chat(msg);
328327
world.get::<&Compose>(|compose| {
329-
compose.unicast(&chat, *stream, SystemId(8), world).unwrap();
328+
compose.unicast(&chat, *stream, system).unwrap();
330329
});
331330
});
332331
});
@@ -337,7 +336,7 @@ impl MinecraftCommand for PermissionCommand {
337336
let msg = format!("§c{} not found", cmd.player);
338337
let chat = hyperion::net::agnostic::chat(msg);
339338
world.get::<&Compose>(|compose| {
340-
compose.unicast(&chat, *stream, SystemId(8), world).unwrap();
339+
compose.unicast(&chat, *stream, system).unwrap();
341340
});
342341
});
343342
return;
@@ -348,7 +347,7 @@ impl MinecraftCommand for PermissionCommand {
348347
let msg = format!("§b{}§r's group is §e{:?}", cmd.player, group);
349348
let chat = hyperion::net::agnostic::chat(msg);
350349
world.get::<&Compose>(|compose| {
351-
compose.unicast(&chat, *stream, SystemId(8), world).unwrap();
350+
compose.unicast(&chat, *stream, system).unwrap();
352351
});
353352
});
354353
});

crates/hyperion-command/src/component.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use flecs_ecs::{
2-
core::{Entity, World},
2+
core::{Entity, EntityView, World},
33
macros::Component,
44
prelude::Module,
55
};
66
use hyperion::storage::{CommandCompletionRequest, EventFn};
77
use indexmap::IndexMap;
88

99
pub struct CommandHandler {
10-
pub on_execute: fn(input: &str, world: &World, caller: Entity),
10+
pub on_execute: fn(input: &str, system: EntityView<'_>, caller: Entity),
1111
pub on_tab_complete: EventFn<CommandCompletionRequest<'static>>,
1212
pub has_permissions: fn(world: &World, caller: Entity) -> bool,
1313
}

crates/hyperion-command/src/system.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use hyperion::{
99
net::agnostic,
1010
simulation::event,
1111
storage::{EventQueue, GlobalEventHandlers},
12-
system_registry::SystemId,
1312
};
1413

1514
use crate::component::CommandRegistry;
@@ -26,6 +25,8 @@ impl Module for CommandSystemModule {
2625
&CommandRegistry($)
2726
)
2827
.each_iter(|it, _, (event_queue, registry)| {
28+
let system = it.system();
29+
2930
let world = it.world();
3031
for event::Command { raw, by } in event_queue.drain() {
3132
let Some(first_word) = raw.split_whitespace().next() else {
@@ -50,9 +51,7 @@ impl Module for CommandSystemModule {
5051
world.get::<&hyperion::net::Compose>(|compose| {
5152
by.entity_view(world)
5253
.get::<&hyperion::net::ConnectionId>(|stream| {
53-
compose
54-
.unicast(&chat, *stream, SystemId(8), &world)
55-
.unwrap();
54+
compose.unicast(&chat, *stream, system).unwrap();
5655
});
5756
});
5857

@@ -62,7 +61,7 @@ impl Module for CommandSystemModule {
6261
tracing::debug!("executing command {first_word}");
6362

6463
let command = command.on_execute;
65-
command(raw, &world, by);
64+
command(raw, system, by);
6665
}
6766
});
6867

crates/hyperion-gui/src/lib.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
use std::{borrow::Cow, cell::Cell, collections::HashMap};
44

5-
use flecs_ecs::core::{Entity, EntityViewGet, World, WorldGet};
5+
use flecs_ecs::core::{Entity, EntityView, EntityViewGet, WorldGet, WorldProvider};
66
use hyperion::{
77
net::{Compose, ConnectionId},
88
storage::GlobalEventHandlers,
9-
system_registry::SystemId,
109
valence_protocol::{
1110
ItemStack, VarInt,
1211
packets::play::{
@@ -105,7 +104,7 @@ impl Gui {
105104
Ok(())
106105
}
107106

108-
pub fn draw<'a>(&'a self, world: &World, player: Entity) {
107+
pub fn draw<'a>(&'a self, system: EntityView<'_>, player: Entity) {
109108
let container_items: Cow<'a, [ItemStack]> = (0..self.size)
110109
.map(|slot| {
111110
self.items
@@ -123,37 +122,42 @@ impl Gui {
123122
carried_item: Cow::Borrowed(&binding),
124123
};
125124

125+
let world = system.world();
126+
126127
world.get::<&Compose>(|compose| {
127128
player.entity_view(world).get::<&ConnectionId>(|stream| {
128129
compose
129-
.unicast(&set_content_packet, *stream, SystemId(8), world)
130+
.unicast(&set_content_packet, *stream, system)
130131
.unwrap();
131132
});
132133
});
133134
}
134135

135-
pub fn open(&mut self, world: &World, player: Entity) {
136+
pub fn open(&mut self, system: EntityView<'_>, player: Entity) {
136137
let open_screen_packet = OpenScreenS2c {
137138
window_id: VarInt(i32::from(self.window_id)),
138139
window_type: self.get_window_type(),
139140
window_title: self.title.clone().into_cow_text(),
140141
};
141142

143+
let world = system.world();
144+
142145
world.get::<&Compose>(|compose| {
143146
player.entity_view(world).get::<&ConnectionId>(|stream| {
144147
compose
145-
.unicast(&open_screen_packet, *stream, SystemId(8), world)
148+
.unicast(&open_screen_packet, *stream, system)
146149
.unwrap();
147150
});
148151
});
149152

150-
self.draw(world, player);
153+
self.draw(system, player);
151154

152155
world.get::<&mut GlobalEventHandlers>(|event_handlers| {
153156
let window_id = self.window_id;
154157
let items = self.items.clone();
155158
let gui = self.clone();
156159
event_handlers.click.register(move |query, event| {
160+
let system = query.system;
157161
let button = event.mode;
158162

159163
if event.window_id != window_id {
@@ -166,7 +170,7 @@ impl Gui {
166170
};
167171

168172
(item.on_click)(player, button);
169-
gui.draw(query.world, player);
173+
gui.draw(query.system, player);
170174

171175
let inventory = &*query.inventory;
172176
let compose = query.compose;
@@ -183,7 +187,7 @@ impl Gui {
183187
};
184188

185189
compose
186-
.unicast(&set_content_packet, stream, SystemId(8), query.world)
190+
.unicast(&set_content_packet, stream, system)
187191
.unwrap();
188192
});
189193
});

crates/hyperion-permission/src/lib.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
use clap::ValueEnum;
22
use flecs_ecs::{
3-
core::{
4-
EntityViewGet, QueryBuilderImpl, SystemAPI, TermBuilderImpl, World, WorldGet, WorldProvider,
5-
},
3+
core::{EntityViewGet, QueryBuilderImpl, SystemAPI, TermBuilderImpl, World, WorldGet},
64
macros::{Component, observer},
75
prelude::{Module, flecs},
86
};
97
use hyperion::{
108
net::{Compose, ConnectionId},
119
simulation::{Player, Uuid, command::get_command_packet},
1210
storage::LocalDb,
13-
system_registry::SystemId,
1411
};
1512
use num_derive::{FromPrimitive, ToPrimitive};
1613

@@ -65,18 +62,18 @@ impl Module for PermissionModule {
6562
permissions.set(**uuid, *group).unwrap();
6663
});
6764

68-
observer!(world, flecs::OnSet, &Group).each_entity(|entity, _group| {
69-
let world = entity.world();
65+
observer!(world, flecs::OnSet, &Group).each_iter(|it, row, _group| {
66+
let system = it.system();
67+
let world = it.world();
68+
let entity = it.entity(row);
7069

7170
let root_command = hyperion::simulation::command::get_root_command_entity();
7271

7372
let cmd_pkt = get_command_packet(&world, root_command, Some(*entity));
7473

7574
entity.get::<&ConnectionId>(|stream| {
7675
world.get::<&Compose>(|compose| {
77-
compose
78-
.unicast(&cmd_pkt, *stream, SystemId(999), &world)
79-
.unwrap();
76+
compose.unicast(&cmd_pkt, *stream, system).unwrap();
8077
});
8178
});
8279
});

0 commit comments

Comments
 (0)