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:
@@ -0,0 +1,59 @@
|
||||
//! Tick-loop integration systems for background workers (#843 Part C).
|
||||
//!
|
||||
//! - `poll_worker_results`: runs in PreInput, drains completed results
|
||||
//! - `push_worker_requests`: runs in PostSnapshot, queues new work
|
||||
//!
|
||||
//! Both are no-ops when no results/requests are pending. The worker pools
|
||||
//! exist as Bevy Resources — systems access them via `Res<ChunkGenWorker>` etc.
|
||||
|
||||
use bevy_ecs::prelude::*;
|
||||
|
||||
use super::stubs::{ChunkGenWorker, NpcPrepWorker, OffscreenTickWorker};
|
||||
|
||||
/// PreInput: poll all worker pools for completed results.
|
||||
///
|
||||
/// Incorporates results into the world state. Currently logs completions
|
||||
/// at debug level — real incorporation logic (spawning chunks, activating
|
||||
/// NPCs) plugs in at Phase 5+.
|
||||
pub fn poll_worker_results(
|
||||
chunk_worker: Option<Res<ChunkGenWorker>>,
|
||||
npc_worker: Option<Res<NpcPrepWorker>>,
|
||||
offscreen_worker: Option<Res<OffscreenTickWorker>>,
|
||||
) {
|
||||
if let Some(worker) = chunk_worker {
|
||||
for (result, _strategy) in worker.drain() {
|
||||
tracing::debug!(
|
||||
chunk_x = result.chunk_x,
|
||||
chunk_y = result.chunk_y,
|
||||
"ChunkGen result ready"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(worker) = npc_worker {
|
||||
for (result, _strategy) in worker.pool.drain() {
|
||||
tracing::debug!(area = %result.area_id, "NpcPrep result ready");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(worker) = offscreen_worker {
|
||||
for (result, _strategy) in worker.pool.drain() {
|
||||
tracing::debug!(
|
||||
area = %result.area_id,
|
||||
ticks = result.ticks_advanced,
|
||||
"OffscreenTick result ready"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// PostSnapshot: push new work requests based on player state.
|
||||
///
|
||||
/// Placeholder — real logic (predict player movement direction, queue
|
||||
/// chunks ahead, snapshot departing NPCs) plugs in at Phase 5+.
|
||||
pub fn push_worker_requests() {
|
||||
// No-op until chunk streaming and NPC tier transitions are implemented.
|
||||
// The worker pools are ready to receive requests via:
|
||||
// chunk_worker.submit(req, DeliveryStrategy::GracefulDegrade);
|
||||
// npc_worker.pool.submit(WorkRequest { ... });
|
||||
}
|
||||
Reference in New Issue
Block a user