feat(simulation): background worker pool infrastructure (#843 Part C)

Generic BackgroundWorkerPool<Req, Resp> with crossbeam channels, closure
handlers, and 3 delivery strategies (Fallback, GracefulDegrade, ModalLock).

Stub workers registered as Bevy resources:
  - ChunkGenWorker (2 threads) — terrain/props/navmesh generation
  - NpcPrepWorker (1 thread) — pre-compute NPC state for incoming areas
  - OffscreenTickWorker (1 thread) — advance NPCs outside active tier

Tick loop integration:
  - PreInput: poll_worker_results drains completed work
  - PostSnapshot: push_worker_requests queues new work (no-op until Phase 5)

Handlers are stubs — real computation plugs in when the phases that need
them arrive. The infrastructure (channels, threads, push/poll, shutdown)
is real and tested.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-11 00:15:05 +02:00
co-authored by Claude Opus 4.6
parent 2175e9b31c
commit 0098ee5a41
7 changed files with 429 additions and 1 deletions
+18
View File
@@ -70,6 +70,12 @@ impl Plugin for SimulationPlugin {
.init_resource::<crate::npc::relationships::RelationshipGraph>()
.init_resource::<crate::knowledge::KnowledgeEventQueue>();
// Background worker pools (#843 Part C) — off-tick computation on separate cores.
// Stub handlers for now; real implementations plug in at Phase 5+.
app.insert_resource(crate::workers::stubs::ChunkGenWorker::new(2));
app.insert_resource(crate::workers::stubs::NpcPrepWorker::new(1));
app.insert_resource(crate::workers::stubs::OffscreenTickWorker::new(1));
// Phase sub-plugins (#843) — each owns its domain
app.add_plugins(time_plugin::TimePlugin);
app.add_plugins(input_plugin::InputPlugin);
@@ -77,6 +83,18 @@ impl Plugin for SimulationPlugin {
app.add_plugins(social_plugin::SocialPlugin);
app.add_plugins(economy_plugin::EconomyPlugin);
// Background worker tick integration (#843 Part C)
app.add_systems(
Update,
crate::workers::systems::poll_worker_results
.in_set(crate::tick_phases::TickPhase::PreInput),
);
app.add_systems(
Update,
crate::workers::systems::push_worker_requests
.in_set(crate::tick_phases::TickPhase::PostSnapshot),
);
// save_load is an exclusive system (takes &mut World).
// Exclusive systems in Bevy 0.18 cannot use .in_set() — use .before()/.after()
// to position it within the Snapshot phase window.