Skip to content
This repository was archived by the owner on Mar 10, 2026. It is now read-only.

Commit 695b459

Browse files
committed
pt2: avoid try_get(_mut)() with singleton components, include them in system queries directly instead
1 parent a509706 commit 695b459

7 files changed

Lines changed: 143 additions & 138 deletions

File tree

Game/cpp/systems/enemy_animation.h

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -61,37 +61,34 @@ namespace enemy_animation {
6161
// BugLarge walk(up)
6262

6363
inline FlecsRegistry register_enemy_animation_system([](flecs::world& world) {
64-
world.system<const HitPoints, const Velocity2D, const MovementSpeed, const AnimationFrameOffset, const DeathTimer, const HitReactionTimer, HFlipTimer, VFlipTimer, RenderingCustomData>("Enemy Animation")
64+
world.system<HFlipTimer, VFlipTimer, RenderingCustomData, const EnemyAnimationSettings, const HitPoints, const Velocity2D, const MovementSpeed, const AnimationFrameOffset, const DeathTimer, const HitReactionTimer>("Enemy Animation")
6565
.with(flecs::IsA, world.lookup("Enemy"))
6666
.kind(flecs::PostUpdate)
6767
.run([](flecs::iter& it) {
68-
const EnemyAnimationSettings* animation_settings = it.world().try_get<EnemyAnimationSettings>();
69-
if (animation_settings == nullptr) {
70-
return;
71-
}
72-
73-
const godot::real_t animation_interval = animation_settings->animation_interval;
74-
const godot::real_t animation_speed = animation_interval > 0.0 ? godot::real_t(1.0) / animation_interval : godot::real_t(0.0);
75-
const godot::real_t animation_range = animation_settings->walk_animation_range;
76-
const godot::real_t death_animation_frame_count = animation_settings->death_animation_frame_count;
77-
const godot::real_t death_animation_range = death_animation_frame_count - godot::real_t(1.0);
78-
const godot::real_t frame_interval = animation_interval > 0.0 ? animation_interval : godot::real_t(0.001);
79-
const godot::real_t up_direction_frame_offset = animation_settings->up_direction_frame_offset;
80-
const godot::real_t horizontal_flip_cooldown = godot::Math::max(animation_settings->horizontal_flip_cooldown, godot::real_t(0.0));
81-
const godot::real_t vertical_flip_cooldown = godot::Math::max(animation_settings->vertical_flip_cooldown, godot::real_t(0.0));
82-
const godot::real_t nominal_movement_speed = animation_settings->nominal_movement_speed;
83-
const godot::real_t animation_offset_fraction_range = godot::Math::max(animation_settings->animation_offset_fraction_range, godot::real_t(0.0));
84-
8568
while (it.next()) {
86-
flecs::field<const HitPoints> hit_points = it.field<const HitPoints>(0);
87-
flecs::field<const Velocity2D> velocities = it.field<const Velocity2D>(1);
88-
flecs::field<const MovementSpeed> movement_speeds = it.field<const MovementSpeed>(2);
89-
flecs::field<const AnimationFrameOffset> frame_offsets = it.field<const AnimationFrameOffset>(3);
90-
flecs::field<const DeathTimer> death_timer = it.field<const DeathTimer>(4);
91-
flecs::field<const HitReactionTimer> hit_reaction_timers = it.field<const HitReactionTimer>(5);
92-
flecs::field<HFlipTimer> horizontal_flip_timers = it.field<HFlipTimer>(6);
93-
flecs::field<VFlipTimer> vertical_flip_timers = it.field<VFlipTimer>(7);
94-
flecs::field<RenderingCustomData> custom_data_field = it.field<RenderingCustomData>(8);
69+
flecs::field<HFlipTimer> horizontal_flip_timers = it.field<HFlipTimer>(0);
70+
flecs::field<VFlipTimer> vertical_flip_timers = it.field<VFlipTimer>(1);
71+
flecs::field<RenderingCustomData> custom_data_field = it.field<RenderingCustomData>(2);
72+
flecs::field<const EnemyAnimationSettings> animation_settings_field = it.field<const EnemyAnimationSettings>(3); // singleton
73+
flecs::field<const HitPoints> hit_points = it.field<const HitPoints>(4);
74+
flecs::field<const Velocity2D> velocities = it.field<const Velocity2D>(5);
75+
flecs::field<const MovementSpeed> movement_speeds = it.field<const MovementSpeed>(6);
76+
flecs::field<const AnimationFrameOffset> frame_offsets = it.field<const AnimationFrameOffset>(7);
77+
flecs::field<const DeathTimer> death_timer = it.field<const DeathTimer>(8);
78+
flecs::field<const HitReactionTimer> hit_reaction_timers = it.field<const HitReactionTimer>(9);
79+
80+
const EnemyAnimationSettings* animation_settings = &animation_settings_field[0];
81+
const godot::real_t animation_interval = animation_settings->animation_interval;
82+
const godot::real_t animation_speed = animation_interval > 0.0 ? godot::real_t(1.0) / animation_interval : godot::real_t(0.0);
83+
const godot::real_t animation_range = animation_settings->walk_animation_range;
84+
const godot::real_t death_animation_frame_count = animation_settings->death_animation_frame_count;
85+
const godot::real_t death_animation_range = death_animation_frame_count - godot::real_t(1.0);
86+
const godot::real_t frame_interval = animation_interval > 0.0 ? animation_interval : godot::real_t(0.001);
87+
const godot::real_t up_direction_frame_offset = animation_settings->up_direction_frame_offset;
88+
const godot::real_t horizontal_flip_cooldown = godot::Math::max(animation_settings->horizontal_flip_cooldown, godot::real_t(0.0));
89+
const godot::real_t vertical_flip_cooldown = godot::Math::max(animation_settings->vertical_flip_cooldown, godot::real_t(0.0));
90+
const godot::real_t nominal_movement_speed = animation_settings->nominal_movement_speed;
91+
const godot::real_t animation_offset_fraction_range = godot::Math::max(animation_settings->animation_offset_fraction_range, godot::real_t(0.0));
9592

9693
const size_t count = it.count();
9794
for (size_t i = 0; i < count; ++i) {

Game/cpp/systems/enemy_death.h

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,22 @@
1818
#include "components/singletons.h"
1919

2020
inline FlecsRegistry register_enemy_death_system([](flecs::world& world) {
21-
world.system<const Position2D, HitPoints, DeathTimer, MeleeDamage, MovementSpeed, Velocity2D>("Enemy Death")
21+
world.system<HitPoints, DeathTimer, MeleeDamage, MovementSpeed, Velocity2D, const EnemyAnimationSettings, const Position2D>("Enemy Death")
2222
.with(flecs::IsA, world.lookup("Enemy"))
2323
.kind(flecs::OnValidate)
2424
.run([](flecs::iter& it) {
25-
const EnemyAnimationSettings* animation_settings = it.world().try_get<EnemyAnimationSettings>();
26-
if (animation_settings == nullptr) { return; }
27-
28-
const godot::real_t death_animation_duration = animation_settings->animation_interval * animation_settings->death_animation_frame_count;
29-
const godot::real_t invulnerable_hit_points = kEnemyDeathInvulnerableHitPoints;
30-
3125
while (it.next()) {
32-
flecs::field<const Position2D> positions = it.field<const Position2D>(0);
33-
flecs::field<HitPoints> hit_points = it.field<HitPoints>(1);
34-
flecs::field<DeathTimer> death_timer = it.field<DeathTimer>(2);
35-
flecs::field<MeleeDamage> melee_damage = it.field<MeleeDamage>(3);
36-
flecs::field<MovementSpeed> movement_speed = it.field<MovementSpeed>(4);
37-
flecs::field<Velocity2D> velocities = it.field<Velocity2D>(5);
26+
flecs::field<HitPoints> hit_points = it.field<HitPoints>(0);
27+
flecs::field<DeathTimer> death_timer = it.field<DeathTimer>(1);
28+
flecs::field<MeleeDamage> melee_damage = it.field<MeleeDamage>(2);
29+
flecs::field<MovementSpeed> movement_speed = it.field<MovementSpeed>(3);
30+
flecs::field<Velocity2D> velocities = it.field<Velocity2D>(4);
31+
flecs::field<const EnemyAnimationSettings> animation_settings_field = it.field<const EnemyAnimationSettings>(5); // singleton
32+
flecs::field<const Position2D> positions = it.field<const Position2D>(6);
33+
34+
const EnemyAnimationSettings* animation_settings = &animation_settings_field[0];
35+
const godot::real_t death_animation_duration = animation_settings->animation_interval * animation_settings->death_animation_frame_count;
36+
const godot::real_t invulnerable_hit_points = kEnemyDeathInvulnerableHitPoints;
3837

3938
for (auto entity_index : it) {
4039
if (hit_points[entity_index].value > godot::real_t(0.0)) { continue; }
@@ -56,4 +55,3 @@ inline FlecsRegistry register_enemy_death_system([](flecs::world& world) {
5655
});
5756

5857
});
59-

Game/cpp/systems/enemy_hit_player.h

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,27 @@
1616
#include "components/singletons.h"
1717

1818
inline FlecsRegistry register_player_take_damage_system([](flecs::world& world) {
19-
world.system<const Position2D, const MeleeDamage>("Enemy Hit Player")
19+
world.system<PlayerDamageCooldown, const PlayerPosition, const PlayerTakeDamageSettings, const Position2D, const MeleeDamage>("Enemy Hit Player")
2020
.with(flecs::IsA, world.lookup("Enemy"))
2121
.run([](flecs::iter& it) {
22-
const PlayerPosition* player_position = it.world().try_get<PlayerPosition>();
23-
PlayerDamageCooldown* player_damage_cooldown = it.world().try_get_mut<PlayerDamageCooldown>();
24-
const PlayerTakeDamageSettings* damage_settings = it.world().try_get<PlayerTakeDamageSettings>();
25-
if (player_position == nullptr || player_damage_cooldown == nullptr || damage_settings == nullptr) {
26-
return;
27-
}
28-
29-
const godot::real_t cooldown = godot::Math::max(damage_settings->damage_cooldown, godot::real_t(0.0));
30-
const bool can_take_damage = cooldown <= godot::real_t(0.0) || player_damage_cooldown->value >= cooldown;
31-
if (!can_take_damage) {
32-
return;
33-
}
22+
while (it.next()) {
23+
flecs::field<PlayerDamageCooldown> player_damage_cooldown = it.field<PlayerDamageCooldown>(0); // singleton
24+
flecs::field<const PlayerPosition> player_position = it.field<const PlayerPosition>(1); // singleton
25+
flecs::field<const PlayerTakeDamageSettings> damage_settings = it.field<const PlayerTakeDamageSettings>(2); // singleton
26+
flecs::field<const Position2D> enemy_positions = it.field<const Position2D>(3);
27+
flecs::field<const MeleeDamage> melee_damages = it.field<const MeleeDamage>(4);
28+
29+
const godot::real_t cooldown = godot::Math::max(damage_settings->damage_cooldown, godot::real_t(0.0));
30+
const bool can_take_damage = cooldown <= godot::real_t(0.0) || player_damage_cooldown->value >= cooldown;
31+
if (!can_take_damage) {
32+
return;
33+
}
3434

35-
const godot::real_t player_hit_radius = godot::Math::max(damage_settings->player_hit_radius, godot::real_t(1.0));
36-
const godot::Vector2 player_position_value = player_position->value;
35+
const godot::real_t player_hit_radius = godot::Math::max(damage_settings->player_hit_radius, godot::real_t(1.0));
36+
const godot::Vector2 player_position_value = player_position->value;
3737

38-
while (it.next()) {
39-
flecs::field<const Position2D> positions = it.field<const Position2D>(0);
40-
flecs::field<const MeleeDamage> melee_damages = it.field<const MeleeDamage>(1);
4138
for (auto entity_index : it) { // https://discord.com/channels/633826290415435777/1455553733978099763/1455637997361041458
42-
const godot::Vector2 enemy_position = positions[entity_index].value;
39+
const godot::Vector2 enemy_position = enemy_positions[entity_index].value;
4340
const godot::Vector2 delta = player_position_value - enemy_position;
4441
const godot::real_t distance_squared = delta.length_squared();
4542
const godot::real_t contact_radius = player_hit_radius;

Game/cpp/systems/enemy_movement.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,9 @@ namespace enemy_movement {
7070
} // namespace enemy_movement
7171

7272
inline FlecsRegistry register_enemy_movement_system([](flecs::world& world) {
73-
world.system<Position2D, Velocity2D, const MovementSpeed, const DeathTimer>("Enemy Movement")
73+
world.system<Position2D, Velocity2D, const PlayerPosition, const EnemyBoidMovementSettings, const MovementSpeed, const DeathTimer>("Enemy Movement")
7474
.with(flecs::IsA, world.lookup("Enemy"))
7575
.run([](flecs::iter& it) {
76-
flecs::world stage_world = it.world();
77-
const PlayerPosition* player_position = stage_world.try_get<PlayerPosition>();
78-
const EnemyBoidMovementSettings* movement_settings = stage_world.try_get<EnemyBoidMovementSettings>();
79-
80-
if (player_position == nullptr || movement_settings == nullptr) {
81-
return;
82-
}
83-
8476
enemy_movement::KdTreeCache& kd_cache = enemy_movement::get_kd_tree_cache();
8577

8678
std::vector<enemy_movement::BoidAccessor> boids;
@@ -89,6 +81,8 @@ inline FlecsRegistry register_enemy_movement_system([](flecs::world& world) {
8981

9082
godot::real_t delta_time = 0.0f;
9183
bool delta_time_initialized = false;
84+
const PlayerPosition* player_position = nullptr;
85+
const EnemyBoidMovementSettings* movement_settings = nullptr;
9286

9387
while (it.next()) {
9488
if (!delta_time_initialized) {
@@ -98,9 +92,13 @@ inline FlecsRegistry register_enemy_movement_system([](flecs::world& world) {
9892

9993
flecs::field<Position2D> positions = it.field<Position2D>(0);
10094
flecs::field<Velocity2D> velocities = it.field<Velocity2D>(1);
101-
flecs::field<const MovementSpeed> movement_speeds = it.field<const MovementSpeed>(2);
102-
flecs::field<const DeathTimer> death_timers = it.field<const DeathTimer>(3);
95+
flecs::field<const PlayerPosition> player_position_field = it.field<const PlayerPosition>(2); // singleton
96+
flecs::field<const EnemyBoidMovementSettings> movement_settings_field = it.field<const EnemyBoidMovementSettings>(3); // singleton
97+
flecs::field<const MovementSpeed> movement_speeds = it.field<const MovementSpeed>(4);
98+
flecs::field<const DeathTimer> death_timers = it.field<const DeathTimer>(5);
10399

100+
player_position = &player_position_field[0];
101+
movement_settings = &movement_settings_field[0];
104102
const godot::real_t max_speed_multiplier = movement_settings->max_speed_multiplier;
105103

106104
for (size_t row_index = 0; row_index < it.count(); ++row_index) {
@@ -118,6 +116,10 @@ inline FlecsRegistry register_enemy_movement_system([](flecs::world& world) {
118116
}
119117
}
120118

119+
if (player_position == nullptr || movement_settings == nullptr) {
120+
return;
121+
}
122+
121123
const size_t enemy_count = boids.size();
122124
if (enemy_count == 0) {
123125
return;

0 commit comments

Comments
 (0)