From f5a04a31ef5b8cbbc3887034b2a88509471f1de6 Mon Sep 17 00:00:00 2001 From: Nathan Lilienthal Date: Sun, 22 Sep 2024 11:57:03 -0400 Subject: [PATCH] Don't scale or forget to trunctate parts of the index Fixes #65 holy shit yay --- galos_map/src/camera.rs | 5 +-- galos_map/src/systems/fetch.rs | 65 ++++++++++++++++++++-------------- galos_map/src/systems/spawn.rs | 19 +++++++++- 3 files changed, 59 insertions(+), 30 deletions(-) diff --git a/galos_map/src/camera.rs b/galos_map/src/camera.rs index abbaca9..4f31b91 100644 --- a/galos_map/src/camera.rs +++ b/galos_map/src/camera.rs @@ -1,3 +1,4 @@ +use crate::systems::Spyglass; use bevy::core_pipeline::bloom::BloomSettings; use bevy::prelude::*; use bevy_mod_picking::prelude::*; @@ -18,7 +19,7 @@ impl From>> for MoveCamera { } /// Place a camera in space -pub fn spawn_camera(mut commands: Commands) { +pub fn spawn_camera(mut commands: Commands, spyglass: Res) { commands.spawn(( Camera3dBundle { transform: Transform::from_translation(Vec3::new(0., 0., 0.)), @@ -28,7 +29,7 @@ pub fn spawn_camera(mut commands: Commands) { PanOrbitCamera { pitch: Some(0.), yaw: Some(0.), - radius: Some(25.0), + radius: Some(spyglass.radius * 3.), // Achenar, home of the Empire! focus: Vec3::new(67.5, -119.46875, 24.84375), diff --git a/galos_map/src/systems/fetch.rs b/galos_map/src/systems/fetch.rs index a397814..26c84e0 100644 --- a/galos_map/src/systems/fetch.rs +++ b/galos_map/src/systems/fetch.rs @@ -5,6 +5,7 @@ use bevy::tasks::{AsyncComputeTaskPool, Task}; use bevy_panorbit_camera::PanOrbitCamera; use galos_db::systems::System as DbSystem; use std::collections::HashMap; +use std::fmt; use std::time::{Duration, Instant}; /// Represents a single fetch request @@ -23,14 +24,26 @@ pub enum FetchIndex { Route(String, String, String), } -/// A region is as large as the current spyglass radius / this factor. -const REGION_FACTOR: i32 = 10; +impl fmt::Debug for FetchIndex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + FetchIndex::Region(center, radius) => write!( + f, + "<({},{},{}),{}>", + center.x, center.y, center.z, radius + ), + FetchIndex::Faction(name) => write!(f, "<{}>", name), + FetchIndex::Route(start, end, range) => { + write!(f, "<{}-{}>{}>", start, end, range) + } + } + } +} /// The amount to throttle requests for old indices. -const LAST_FETCH_DELAY: Duration = Duration::from_secs(1); +const UPDATE_DELAY: Duration = Duration::from_secs(1); /// The amount to throttle requests for new indices. -const NEW_FETCH_DELAY: Duration = - Duration::from_millis((1. / 60. * 1000.) as u64); +const FRESH_DELAY: Duration = Duration::from_millis(50); /// Tasks for systems in the DB which will be spawned #[derive(Resource, Default)] @@ -55,7 +68,7 @@ pub fn fetch( mut tasks: ResMut, mut spyglass: ResMut, time: Res>, - mut last_fetched: ResMut, + mut last_fetched_at: ResMut, db: Res, ) { if spyglass.fetch { @@ -64,7 +77,7 @@ pub fn fetch( &mut tasks, &mut spyglass, &time, - &mut last_fetched, + &mut last_fetched_at, &db, ); } @@ -83,7 +96,7 @@ pub fn fetch( name.into(), &mut tasks, &time, - &mut last_fetched, + &mut last_fetched_at, &db, ); } @@ -94,7 +107,7 @@ pub fn fetch( range.into(), &mut tasks, &time, - &mut last_fetched, + &mut last_fetched_at, &db, ); } @@ -107,34 +120,32 @@ fn fetch_around_camera( tasks: &mut ResMut, spyglass: &ResMut, time: &Res>, - last_fetched: &mut ResMut, + last_fetched_at: &mut ResMut, db: &Res, ) { let camera = camera_query.single(); let center = camera.focus.as_ivec3(); - // Regions need to be smaller than the spyglass radius. Once we load cubes, - // we'll need to change things to hide the entities outside of the sphere. - let scale = spyglass.radius as i32 / REGION_FACTOR; - let index = if scale == 0 { - FetchIndex::Region(IVec3::ZERO, spyglass.radius as i32) - } else { - FetchIndex::Region(center / scale, spyglass.radius as i32) - }; - + let index = FetchIndex::Region(center, spyglass.radius as i32); let now = time.last_update().unwrap_or(time.startup()); - if fetch_condition(&index, &tasks, now, &last_fetched) { + if fetch_condition(&index, &tasks, now, &last_fetched_at) { + debug!( + "fetching {:?} @ {:?}", + index, + now.duration_since(time.startup()) + ); + let task_pool = AsyncComputeTaskPool::get(); let db = db.0.clone(); let radius = spyglass.radius; let task = task_pool.spawn(async move { let cent = [center.x as f64, center.y as f64, center.z as f64]; - DbSystem::fetch_in_range_of_point(&db, radius as f64, cent) + DbSystem::fetch_in_range_of_point(&db, radius.floor() as f64, cent) .await .unwrap_or_default() }); tasks.fetched.insert(index.clone(), (task, now)); tasks.last_fetched = Some(index); - **last_fetched = LastFetchedAt(now); + **last_fetched_at = LastFetchedAt(now); } } @@ -142,12 +153,12 @@ fn fetch_faction( name: String, tasks: &mut ResMut, time: &Res>, - last_fetched: &mut ResMut, + last_fetched_at: &mut ResMut, db: &Res, ) { let index = FetchIndex::Faction(name.clone()); let now = time.last_update().unwrap_or(time.startup()); - if fetch_condition(&index, &tasks, now, &last_fetched) { + if fetch_condition(&index, &tasks, now, &last_fetched_at) { let task_pool = AsyncComputeTaskPool::get(); let db = db.0.clone(); let task = task_pool.spawn(async move { @@ -155,7 +166,7 @@ fn fetch_faction( }); tasks.fetched.insert(index.clone(), (task, now)); tasks.last_fetched = Some(index); - **last_fetched = LastFetchedAt(now); + **last_fetched_at = LastFetchedAt(now); } } @@ -167,9 +178,9 @@ pub fn fetch_condition( ) -> bool { tasks.last_fetched.as_ref().map_or(true, |last_fetched| { if *index == *last_fetched { - last_fetched_at.0 + LAST_FETCH_DELAY < now + last_fetched_at.0 + UPDATE_DELAY < now } else { - last_fetched_at.0 + NEW_FETCH_DELAY < now + last_fetched_at.0 + FRESH_DELAY < now } }) } diff --git a/galos_map/src/systems/spawn.rs b/galos_map/src/systems/spawn.rs index 4d575c3..3d0cab6 100644 --- a/galos_map/src/systems/spawn.rs +++ b/galos_map/src/systems/spawn.rs @@ -10,7 +10,7 @@ use bevy::tasks::futures_lite::future; use bevy_mod_picking::prelude::*; use elite_journal::{system::Security, Allegiance, Government}; use galos_db::systems::System as DbSystem; -use std::{collections::HashMap, ops::Deref}; +use std::{collections::HashMap, ops::Deref, time::Instant}; /// Determains what color to draw in system view mode. #[derive(Resource, Copy, Clone, Debug, PartialEq)] @@ -35,6 +35,7 @@ pub fn spawn( mut meshes: ResMut>, mut materials: ResMut>, mut tasks: ResMut, + time: Res>, ) { tasks.fetched.retain(|index, (task, fetched_at)| { let status = block_on(future::poll_once(task)); @@ -50,6 +51,8 @@ pub fn spawn( &mut commands, &mut meshes, &mut materials, + &time, + fetched_at, ); match index { @@ -90,6 +93,8 @@ pub fn spawn_systems( commands: &mut Commands, mesh_asset: &mut ResMut>, material_assets: &mut ResMut>, + time: &Res>, + fetched_at: &Instant, ) { let mut existing_systems: HashMap = systems_query .iter() @@ -101,11 +106,23 @@ pub fn spawn_systems( for new_system in new_systems { if let Some(enitity) = existing_systems.remove(&new_system.address) { + debug!( + "updating {} @ {:?}", + new_system.address, + fetched_at.duration_since(time.startup()) + ); + commands.entity(enitity).insert(System::from(new_system)); commands .entity(enitity) .insert(pbr_bundle(new_system, &mesh, &materials, color_by)); } else { + debug!( + "spawning {} {:?}", + new_system.address, + fetched_at.duration_since(time.startup()) + ); + commands.spawn(( pbr_bundle(new_system, &mesh, &materials, color_by), System::from(new_system),