Skip to content

Commit

Permalink
Don't scale or forget to trunctate parts of the index
Browse files Browse the repository at this point in the history
Fixes #65 holy shit yay
  • Loading branch information
nixpulvis committed Sep 22, 2024
1 parent e678e3b commit f5a04a3
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 30 deletions.
5 changes: 3 additions & 2 deletions galos_map/src/camera.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::systems::Spyglass;
use bevy::core_pipeline::bloom::BloomSettings;
use bevy::prelude::*;
use bevy_mod_picking::prelude::*;
Expand All @@ -18,7 +19,7 @@ impl From<ListenerInput<Pointer<Click>>> for MoveCamera {
}

/// Place a camera in space
pub fn spawn_camera(mut commands: Commands) {
pub fn spawn_camera(mut commands: Commands, spyglass: Res<Spyglass>) {
commands.spawn((
Camera3dBundle {
transform: Transform::from_translation(Vec3::new(0., 0., 0.)),
Expand All @@ -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),
Expand Down
65 changes: 38 additions & 27 deletions galos_map/src/systems/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)]
Expand All @@ -55,7 +68,7 @@ pub fn fetch(
mut tasks: ResMut<FetchTasks>,
mut spyglass: ResMut<Spyglass>,
time: Res<Time<Real>>,
mut last_fetched: ResMut<LastFetchedAt>,
mut last_fetched_at: ResMut<LastFetchedAt>,
db: Res<Db>,
) {
if spyglass.fetch {
Expand All @@ -64,7 +77,7 @@ pub fn fetch(
&mut tasks,
&mut spyglass,
&time,
&mut last_fetched,
&mut last_fetched_at,
&db,
);
}
Expand All @@ -83,7 +96,7 @@ pub fn fetch(
name.into(),
&mut tasks,
&time,
&mut last_fetched,
&mut last_fetched_at,
&db,
);
}
Expand All @@ -94,7 +107,7 @@ pub fn fetch(
range.into(),
&mut tasks,
&time,
&mut last_fetched,
&mut last_fetched_at,
&db,
);
}
Expand All @@ -107,55 +120,53 @@ fn fetch_around_camera(
tasks: &mut ResMut<FetchTasks>,
spyglass: &ResMut<Spyglass>,
time: &Res<Time<Real>>,
last_fetched: &mut ResMut<LastFetchedAt>,
last_fetched_at: &mut ResMut<LastFetchedAt>,
db: &Res<Db>,
) {
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);
}
}

fn fetch_faction(
name: String,
tasks: &mut ResMut<FetchTasks>,
time: &Res<Time<Real>>,
last_fetched: &mut ResMut<LastFetchedAt>,
last_fetched_at: &mut ResMut<LastFetchedAt>,
db: &Res<Db>,
) {
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 {
DbSystem::fetch_faction(&db, &name).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);
}
}

Expand All @@ -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
}
})
}
19 changes: 18 additions & 1 deletion galos_map/src/systems/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -35,6 +35,7 @@ pub fn spawn(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut tasks: ResMut<FetchTasks>,
time: Res<Time<Real>>,
) {
tasks.fetched.retain(|index, (task, fetched_at)| {
let status = block_on(future::poll_once(task));
Expand All @@ -50,6 +51,8 @@ pub fn spawn(
&mut commands,
&mut meshes,
&mut materials,
&time,
fetched_at,
);

match index {
Expand Down Expand Up @@ -90,6 +93,8 @@ pub fn spawn_systems(
commands: &mut Commands,
mesh_asset: &mut ResMut<Assets<Mesh>>,
material_assets: &mut ResMut<Assets<StandardMaterial>>,
time: &Res<Time<Real>>,
fetched_at: &Instant,
) {
let mut existing_systems: HashMap<i64, Entity> = systems_query
.iter()
Expand All @@ -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),
Expand Down

0 comments on commit f5a04a3

Please sign in to comment.