From ae6c4fe4ce50e9d3b5202c38ceac220919fac26e Mon Sep 17 00:00:00 2001 From: Jacobtread Date: Tue, 19 Sep 2023 09:52:04 +1200 Subject: [PATCH] Seperated gaw decay compute from gaw lookup --- src/database/entities/galaxy_at_war.rs | 117 ++++++++++++------------- src/routes/gaw.rs | 6 +- src/routes/players.rs | 2 +- 3 files changed, 59 insertions(+), 66 deletions(-) diff --git a/src/database/entities/galaxy_at_war.rs b/src/database/entities/galaxy_at_war.rs index 3e3d9435..fef9e87b 100644 --- a/src/database/entities/galaxy_at_war.rs +++ b/src/database/entities/galaxy_at_war.rs @@ -7,10 +7,10 @@ use sea_orm::prelude::*; use sea_orm::{ ActiveModelTrait, ActiveValue::{NotSet, Set}, - DatabaseConnection, IntoActiveModel, + DatabaseConnection, }; use serde::Serialize; -use std::cmp; +use std::future::Future; /// Structure for a galaxy at war model stored in the database #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize)] @@ -49,29 +49,18 @@ impl Model { /// The maximum value for galaxy at war entries const MAX_VALUE: u16 = 10099; - /// Finds or creates a new galaxy at war entry for the provided - /// player. If one exists then the provided decay value will be - /// applied to it. - /// - /// `db` The database connection - /// `player` The player to search for galaxy at war models for - /// `decay` The decay value - pub async fn find_or_create( - db: &DatabaseConnection, - player_id: PlayerID, - decay: f32, - ) -> DbResult { + pub async fn get(db: &DatabaseConnection, player_id: PlayerID) -> DbResult { let existing = Entity::find() .filter(Column::PlayerId.eq(player_id)) .one(db) .await?; if let Some(value) = existing { - return value.apply_decay(db, decay).await; + return Ok(value); } let current_time = Local::now().naive_local(); - let model = ActiveModel { + ActiveModel { id: NotSet, player_id: Set(player_id), last_modified: Set(current_time), @@ -80,45 +69,62 @@ impl Model { group_c: Set(Self::MIN_VALUE), group_d: Set(Self::MIN_VALUE), group_e: Set(Self::MIN_VALUE), - }; + } + .insert(db) + .await + } - model.insert(db).await + /// Increases the stored group values increasing them by the `values` + /// provided for each respective group + pub fn add( + self, + db: &DatabaseConnection, + values: [u16; 5], + ) -> impl Future> + '_ { + self.transform(db, |a, b| a.saturating_add(b).min(Model::MAX_VALUE), values) } - /// Increases the group values stored on the provided - /// galaxy at war models by the values provided. - /// - /// `db` The database connection - /// `value` The galaxy at war model to increase - /// `values` The values to increase each group by - pub async fn increase( + /// Decrease the stored group values decreasuing them by the `values` + /// provided for each respective group + pub fn sub( self, db: &DatabaseConnection, - values: (u16, u16, u16, u16, u16), - ) -> DbResult { - let new_a = self.group_a + values.0; - let new_b = self.group_b + values.1; - let new_c = self.group_c + values.2; - let new_d = self.group_d + values.3; - let new_e = self.group_e + values.4; + values: [u16; 5], + ) -> impl Future> + '_ { + self.transform(db, |a, b| a.saturating_sub(b).max(Model::MIN_VALUE), values) + } - let mut gaw_data = self.into_active_model(); - gaw_data.group_a = Set(cmp::min(new_a, Self::MAX_VALUE)); - gaw_data.group_b = Set(cmp::min(new_b, Self::MAX_VALUE)); - gaw_data.group_c = Set(cmp::min(new_c, Self::MAX_VALUE)); - gaw_data.group_d = Set(cmp::min(new_d, Self::MAX_VALUE)); - gaw_data.group_e = Set(cmp::min(new_e, Self::MAX_VALUE)); - gaw_data.update(db).await + /// Transforms the underlying group values using the provided action + /// function which is given the current value as the first argument + /// and the respective value from `values` as the second argument + #[inline] + pub async fn transform( + self, + db: &DatabaseConnection, + action: F, + values: [u16; 5], + ) -> DbResult + where + F: Fn(u16, u16) -> u16, + { + let current_time = Local::now().naive_local(); + ActiveModel { + id: Set(self.id), + player_id: Set(self.player_id), + last_modified: Set(current_time), + group_a: Set(action(self.group_a, values[0])), + group_b: Set(action(self.group_b, values[1])), + group_c: Set(action(self.group_c, values[2])), + group_d: Set(action(self.group_d, values[3])), + group_e: Set(action(self.group_e, values[4])), + } + .update(db) + .await } - /// Applies the provided galaxy at war decay value to the provided - /// galaxy at war model decreasing the values by the number of days - /// that have passed. - /// - /// `db` The database connection - /// `value` The galaxy at war model to decay - /// `decay` The decay value - async fn apply_decay(self, db: &DatabaseConnection, decay: f32) -> DbResult { + /// Applies the daily decay progress to the group values calculating the + /// decay amount from the number of days passed + pub async fn apply_decay(self, db: &DatabaseConnection, decay: f32) -> DbResult { // Skip decaying if decay is non existent if decay <= 0.0 { return Ok(self); @@ -128,21 +134,6 @@ impl Model { let days_passed = (current_time - self.last_modified).num_days() as f32; let decay_value = (decay * days_passed * 100.0) as u16; - // Apply decay while keeping minimum - let a = cmp::max(self.group_a - decay_value, Self::MIN_VALUE); - let b = cmp::max(self.group_b - decay_value, Self::MIN_VALUE); - let c = cmp::max(self.group_c - decay_value, Self::MIN_VALUE); - let d = cmp::max(self.group_d - decay_value, Self::MIN_VALUE); - let e = cmp::max(self.group_e - decay_value, Self::MIN_VALUE); - - // Update stored copy - let mut value = self.into_active_model(); - value.group_a = Set(a); - value.group_b = Set(b); - value.group_c = Set(c); - value.group_d = Set(d); - value.group_e = Set(e); - - value.update(db).await + self.sub(db, [decay_value; 5]).await } } diff --git a/src/routes/gaw.rs b/src/routes/gaw.rs index 0684fc9d..4eefcd5a 100644 --- a/src/routes/gaw.rs +++ b/src/routes/gaw.rs @@ -141,7 +141,7 @@ pub async fn increase_ratings( ) -> Result { let (gaw_data, promotions) = get_player_gaw_data(&db, sessions, &id, &config).await?; let gaw_data = gaw_data - .increase(&db, (query.a, query.b, query.c, query.d, query.e)) + .add(&db, [query.a, query.b, query.c, query.d, query.e]) .await?; Ok(ratings_response(gaw_data, promotions)) } @@ -166,9 +166,11 @@ async fn get_player_gaw_data( .ok_or(GAWError::InvalidToken)?; let (gaw_data, promotions) = try_join!( - GalaxyAtWar::find_or_create(db, player.id, config.galaxy_at_war.decay), + GalaxyAtWar::get(db, player.id), get_promotions(db, &player, config) )?; + let gaw_data = gaw_data.apply_decay(db, config.galaxy_at_war.decay).await?; + Ok((gaw_data, promotions)) } diff --git a/src/routes/players.rs b/src/routes/players.rs index 3b9ddd00..fdc944cc 100644 --- a/src/routes/players.rs +++ b/src/routes/players.rs @@ -542,7 +542,7 @@ pub async fn get_player_gaw( Extension(db): Extension, ) -> PlayersRes { let player = find_player(&db, player_id).await?; - let galax_at_war = GalaxyAtWar::find_or_create(&db, player.id, 0.0).await?; + let galax_at_war = GalaxyAtWar::get(&db, player.id).await?; Ok(Json(galax_at_war)) }