diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index 06e4d97..99c65bb 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -1,5 +1,5 @@ use thiserror::Error; -use futures::Future; +use futures::future::{Future, BoxFuture}; use crate::entity::account::*; use crate::entity::character::*; @@ -19,12 +19,12 @@ pub enum GatewayError { #[async_trait::async_trait] pub trait EntityGateway: Send + Sync { - type Transaction: EntityGatewayTransaction + Clone; + type Transaction<'t>: EntityGatewayTransaction + Clone where Self: 't; - async fn with_transaction<'a, F, Fut, R>(&'a mut self, _func: F) -> Result + fn with_transaction<'a, F, Fut, R>(&'a mut self, _func: F) -> BoxFuture<'a, Result> where - Fut: Future> + Send + 'a, - F: FnOnce(Self::Transaction) -> Fut + Send, + Fut: Future, R), anyhow::Error>> + Send + 'a, + F: FnOnce(Self::Transaction<'a>) -> Fut + Send + 'a, R: Send, Self: Sized { diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 7752780..75df8a1 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; use std::convert::TryInto; -use futures::Future; +use futures::future::{Future, BoxFuture}; use crate::entity::account::*; use crate::entity::character::*; @@ -31,7 +31,7 @@ where // functions here have been skipped as they are not used in transactions, add as needed #[async_trait::async_trait] impl EntityGateway for InMemoryGatewayTransaction { - type Transaction = InMemoryGatewayTransaction; + type Transaction<'t> = InMemoryGatewayTransaction where Self: 't; async fn create_user(&mut self, user: NewUserAccountEntity) -> Result { self.working_gateway.create_user(user).await @@ -317,55 +317,57 @@ fn apply_modifiers(items: &BTreeMap, #[async_trait::async_trait] impl EntityGateway for InMemoryGateway { - type Transaction = InMemoryGatewayTransaction; + type Transaction<'t> = InMemoryGatewayTransaction where Self: 't; - async fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> Result + fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> BoxFuture<'a, Result> where - Fut: Future> + Send + 'a, - F: FnOnce(Self::Transaction) -> Fut + Send, + Fut: Future, R), anyhow::Error>> + Send + 'a, + F: FnOnce(Self::Transaction<'a>) -> Fut + Send + 'a, R: Send, { - let users = self.users.lock().await.clone(); - let user_settings = self.user_settings.lock().await.clone(); - let characters = self.characters.lock().await.clone(); - let character_meseta = self.character_meseta.lock().await.clone(); - let bank_meseta = self.bank_meseta.lock().await.clone(); - let shared_bank_meseta = self.shared_bank_meseta.lock().await.clone(); - let items = self.items.lock().await.clone(); - let inventories = self.inventories.lock().await.clone(); - let character_banks = self.character_banks.lock().await.clone(); - let shared_banks = self.shared_banks.lock().await.clone(); - let equips = self.equips.lock().await.clone(); - let mag_modifiers = self.mag_modifiers.lock().await.clone(); - let weapon_modifiers = self.weapon_modifiers.lock().await.clone(); - let trades = self.trades.lock().await.clone(); - - let working_gateway = InMemoryGateway { - users: Arc::new(Mutex::new(users)), - user_settings: Arc::new(Mutex::new(user_settings)), - characters: Arc::new(Mutex::new(characters)), - character_meseta: Arc::new(Mutex::new(character_meseta)), - bank_meseta: Arc::new(Mutex::new(bank_meseta)), - shared_bank_meseta: Arc::new(Mutex::new(shared_bank_meseta)), - items: Arc::new(Mutex::new(items)), - inventories: Arc::new(Mutex::new(inventories)), - character_banks: Arc::new(Mutex::new(character_banks)), - shared_banks: Arc::new(Mutex::new(shared_banks)), - equips: Arc::new(Mutex::new(equips)), - mag_modifiers: Arc::new(Mutex::new(mag_modifiers)), - weapon_modifiers: Arc::new(Mutex::new(weapon_modifiers)), - trades: Arc::new(Mutex::new(trades)), - }; - - let transaction = InMemoryGatewayTransaction { - working_gateway, - original_gateway: self.clone(), - }; - - let (transaction, result) = func(transaction).await?; - - transaction.commit().await?; - Ok(result) + Box::pin(async move { + let users = self.users.lock().await.clone(); + let user_settings = self.user_settings.lock().await.clone(); + let characters = self.characters.lock().await.clone(); + let character_meseta = self.character_meseta.lock().await.clone(); + let bank_meseta = self.bank_meseta.lock().await.clone(); + let shared_bank_meseta = self.shared_bank_meseta.lock().await.clone(); + let items = self.items.lock().await.clone(); + let inventories = self.inventories.lock().await.clone(); + let character_banks = self.character_banks.lock().await.clone(); + let shared_banks = self.shared_banks.lock().await.clone(); + let equips = self.equips.lock().await.clone(); + let mag_modifiers = self.mag_modifiers.lock().await.clone(); + let weapon_modifiers = self.weapon_modifiers.lock().await.clone(); + let trades = self.trades.lock().await.clone(); + + let working_gateway = InMemoryGateway { + users: Arc::new(Mutex::new(users)), + user_settings: Arc::new(Mutex::new(user_settings)), + characters: Arc::new(Mutex::new(characters)), + character_meseta: Arc::new(Mutex::new(character_meseta)), + bank_meseta: Arc::new(Mutex::new(bank_meseta)), + shared_bank_meseta: Arc::new(Mutex::new(shared_bank_meseta)), + items: Arc::new(Mutex::new(items)), + inventories: Arc::new(Mutex::new(inventories)), + character_banks: Arc::new(Mutex::new(character_banks)), + shared_banks: Arc::new(Mutex::new(shared_banks)), + equips: Arc::new(Mutex::new(equips)), + mag_modifiers: Arc::new(Mutex::new(mag_modifiers)), + weapon_modifiers: Arc::new(Mutex::new(weapon_modifiers)), + trades: Arc::new(Mutex::new(trades)), + }; + + let transaction = InMemoryGatewayTransaction { + working_gateway, + original_gateway: self.clone(), + }; + + let (transaction, result) = func(transaction).await?; + + transaction.commit().await?; + Ok(result) + }) } async fn create_user(&mut self, user: NewUserAccountEntity) -> Result { diff --git a/src/entity/gateway/postgres/postgres.rs b/src/entity/gateway/postgres/postgres.rs index 4de7413..717f8ca 100644 --- a/src/entity/gateway/postgres/postgres.rs +++ b/src/entity/gateway/postgres/postgres.rs @@ -2,7 +2,7 @@ #![allow(clippy::explicit_auto_deref)] use std::convert::{From, TryFrom, Into}; -use futures::Future; +use futures::future::{Future, BoxFuture}; use futures::stream::{StreamExt, FuturesOrdered}; use async_std::sync::{Arc, Mutex}; use libpso::character::guildcard; @@ -36,9 +36,7 @@ impl<'t> EntityGatewayTransaction for PostgresTransaction<'t> { self } - //async fn commit(self: Box) -> Result<(), GatewayError> { async fn commit(self) -> Result<(), GatewayError> { - //self.pgtransaction.lock().await.commit().await?; Arc::try_unwrap(self.pgtransaction) .unwrap() .into_inner() @@ -50,13 +48,12 @@ impl<'t> EntityGatewayTransaction for PostgresTransaction<'t> { #[derive(Clone)] -pub struct PostgresGateway<'t> { +pub struct PostgresGateway { pool: sqlx::Pool, - _t: std::marker::PhantomData<&'t ()>, } -impl<'t> PostgresGateway<'t> { - pub fn new(host: &str, dbname: &str, username: &str, password: &str) -> PostgresGateway<'t> { +impl PostgresGateway { + pub fn new(host: &str, dbname: &str, username: &str, password: &str) -> PostgresGateway { let mut conn = refinery::config::Config::new(refinery::config::ConfigDbType::Postgres) .set_db_host(host) .set_db_user(username) @@ -72,7 +69,6 @@ impl<'t> PostgresGateway<'t> { PostgresGateway { pool, - _t: Default::default(), } } } @@ -568,6 +564,7 @@ async fn set_character_equips(conn: &mut sqlx::PgConnection, char_id: &Character Ok(()) } + async fn set_character_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> { sqlx::query("insert into character_meseta values ($1, $2) on conflict (pchar) do update set meseta = $2") @@ -662,21 +659,23 @@ async fn set_character_playtime(conn: &mut sqlx::PgConnection, char_id: &Charact } #[async_trait::async_trait] -impl<'t> EntityGateway for PostgresGateway<'t> { - type Transaction = PostgresTransaction<'t>; +impl EntityGateway for PostgresGateway { + type Transaction<'t> = PostgresTransaction<'t> where Self: 't; - async fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> Result + fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> BoxFuture<'a, Result> where - Fut: Future> + Send + 'a, - F: FnOnce(Self::Transaction) -> Fut + Send, + Fut: Future, R), anyhow::Error>> + Send + 'a, + F: FnOnce(Self::Transaction<'a>) -> Fut + Send + 'a, R: Send, { - let transaction = PostgresTransaction { - pgtransaction: Arc::new(Mutex::new(self.pool.begin().await?)) - }; - let (transaction, result) = func(transaction).await?; - transaction.commit().await?; - Ok(result) + Box::pin(async move { + let transaction = PostgresTransaction { + pgtransaction: Arc::new(Mutex::new(self.pool.begin().await?)) + }; + let (transaction, result) = func(transaction).await?; + transaction.commit().await?; + Ok(result) + }) } async fn create_user(&mut self, user: NewUserAccountEntity) -> Result { @@ -803,7 +802,7 @@ impl<'t> EntityGateway for PostgresGateway<'t> { #[async_trait::async_trait] impl<'c> EntityGateway for PostgresTransaction<'c> { - type Transaction = PostgresTransaction<'c>; + type Transaction<'t> = PostgresTransaction<'c> where Self: 't; async fn create_user(&mut self, user: NewUserAccountEntity) -> Result { create_user(&mut *self.pgtransaction.lock().await, user).await diff --git a/src/login/character.rs b/src/login/character.rs index 60446fc..f23beea 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -846,7 +846,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction = (); + type Transaction<'a> = () where Self: 'a; async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result { Ok(UserSettingsEntity { id: UserSettingsId(0), @@ -889,7 +889,7 @@ mod test { #[derive(Clone)] struct TestData; impl EntityGateway for TestData { - type Transaction = (); + type Transaction<'a> = () where Self: 'a; } let mut server = CharacterServerState::new(TestData {}, AuthToken("".into())); let send = server.handle(ClientId(1), RecvCharacterPacket::Checksum(Checksum {checksum: 1234, diff --git a/src/login/login.rs b/src/login/login.rs index bce909a..b4fcad6 100644 --- a/src/login/login.rs +++ b/src/login/login.rs @@ -206,7 +206,7 @@ mod test { }); impl EntityGateway for () { - type Transaction = (); + type Transaction<'t> = () where Self: 't; } impl EntityGatewayTransaction for () { @@ -221,7 +221,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction = (); + type Transaction<'t> = () where Self: 't; async fn get_user_by_name(&mut self, name: String) -> Result { assert!(name == "testuser"); Ok(UserAccountEntity { @@ -280,7 +280,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction = (); + type Transaction<'t> = () where Self: 't; async fn get_user_by_name(&mut self, _name: String) -> Result { Err(GatewayError::Error) } @@ -315,7 +315,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction = (); + type Transaction<'t> = () where Self: 't; async fn get_user_by_name(&mut self, name: String) -> Result { assert!(name == "testuser"); Ok(UserAccountEntity { @@ -365,7 +365,7 @@ mod test { #[async_trait::async_trait] impl EntityGateway for TestData { - type Transaction = (); + type Transaction<'t> = () where Self: 't; async fn get_user_by_name(&mut self, name: String) -> Result { assert!(name == "testuser"); Ok(UserAccountEntity { diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index 3b74a0a..18c52ca 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -3,6 +3,7 @@ use crate::ship::items::ClientItemId; use crate::entity::item::{Meseta, ItemNote}; use async_std::sync::Arc; use std::future::Future; +use futures::future::BoxFuture; use std::pin::Pin; use std::iter::IntoIterator; use anyhow::Context; @@ -25,21 +26,22 @@ use crate::ship::drops::{ItemDrop, ItemDropType}; use crate::ship::packet::builder; use crate::ship::location::AreaClient; -type BoxFuture = Pin + Send>>; +//type BoxFuture = Pin + Send>>; +//type LBoxFuture<'a, T> = Pin + Send + 'a>>; pub enum TriggerCreateItem { Yes, No } -pub(super) fn take_item_from_floor( +pub(super) fn take_item_from_floor<'a, EG, TR>( character_id: CharacterEntityId, item_id: ClientItemId ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + 'a where EG: EntityGateway + Send, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, transaction): (ItemStateProxy, TR) , _| { Box::pin(async move { @@ -52,13 +54,13 @@ where } } -pub(super) fn add_floor_item_to_inventory( +pub(super) fn add_floor_item_to_inventory<'a, EG, TR>( character: &CharacterEntity ) -> impl Fn((ItemStateProxy, TR), FloorItem) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), TriggerCreateItem), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + Clone + 'static, + TR: EntityGatewayTransaction + Clone + 'a, { let character = character.clone(); move |(mut item_state, transaction), floor_item| { @@ -98,15 +100,15 @@ where } -pub(super) fn remove_item_from_inventory( +pub(super) fn remove_item_from_inventory<'a, EG, TR>( character_id: CharacterEntityId, item_id: ClientItemId, amount: u32, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItemDetail), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -124,22 +126,23 @@ where } } -pub(super) fn take_item_from_inventory( +pub(super) fn take_item_from_inventory<'a, EG, TR>( character_id: CharacterEntityId, item_id: ClientItemId, amount: u32, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> where - EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + EG: EntityGateway + 'a, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { let mut inventory = item_state.inventory(&character_id).await?; let item = inventory.take_item(&item_id, amount) .await - .ok_or_else(|| ItemStateError::NoInventoryItem(item_id))?; + .ok_or_else(|| ItemStateError::NoInventoryItem(item_id)) + .with_context(|| format!("{inventory:#?}"))?; transaction.gateway().set_character_inventory(&character_id, &inventory.as_inventory_entity(&character_id)).await?; item_state.set_inventory(inventory).await; @@ -150,15 +153,15 @@ where } -pub(super) fn add_inventory_item_to_shared_floor( +pub(super) fn add_inventory_item_to_shared_floor<'a, EG, TR>( character_id: CharacterEntityId, map_area: MapArea, drop_position: (f32, f32, f32), ) -> impl Fn((ItemStateProxy, TR), InventoryItem) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, transaction), inventory_item| { Box::pin(async move { @@ -184,14 +187,14 @@ where } -pub(super) fn take_meseta_from_inventory( +pub(super) fn take_meseta_from_inventory<'a, EG, TR>( character_id: CharacterEntityId, amount: u32, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -205,14 +208,14 @@ where } } -pub(super) fn add_meseta_to_inventory( +pub(super) fn add_meseta_to_inventory<'a, EG, TR>( character_id: CharacterEntityId, amount: u32 ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -226,16 +229,16 @@ where } } -pub(super) fn add_meseta_to_shared_floor( +pub(super) fn add_meseta_to_shared_floor<'a, EG, TR>( character_id: CharacterEntityId, amount: u32, map_area: MapArea, drop_position: (f32, f32) ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, transaction), _| { Box::pin(async move { @@ -257,14 +260,14 @@ where } } -pub(super) fn take_meseta_from_bank( +pub(super) fn take_meseta_from_bank<'a, EG, TR>( character_id: CharacterEntityId, amount: u32, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -278,14 +281,14 @@ where } } -pub(super) fn add_meseta_from_bank_to_inventory( +pub(super) fn add_meseta_from_bank_to_inventory<'a, EG, TR>( character_id: CharacterEntityId, amount: u32, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -300,14 +303,14 @@ where } -pub(super) fn add_meseta_to_bank( +pub(super) fn add_meseta_to_bank<'a, EG, TR>( character_id: CharacterEntityId, amount: u32, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -322,15 +325,15 @@ where } -pub(super) fn take_item_from_bank( +pub(super) fn take_item_from_bank<'a, EG, TR>( character_id: CharacterEntityId, item_id: ClientItemId, amount: u32, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), BankItem), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -346,13 +349,13 @@ where } } -pub(super) fn add_bank_item_to_inventory( +pub(super) fn add_bank_item_to_inventory<'a, EG, TR>( character: &CharacterEntity, ) -> impl Fn((ItemStateProxy, TR), BankItem) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { let character = character.clone(); move |(mut item_state, transaction), bank_item| { @@ -397,13 +400,13 @@ where } -pub(super) fn add_inventory_item_to_bank( +pub(super) fn add_inventory_item_to_bank<'a, EG, TR>( character_id: CharacterEntityId, ) -> impl Fn((ItemStateProxy, TR), InventoryItem) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, transaction), inventory_item| { Box::pin(async move { @@ -430,15 +433,15 @@ where } -pub(super) fn equip_inventory_item( +pub(super) fn equip_inventory_item<'a, EG, TR>( character_id: CharacterEntityId, item_id: ClientItemId, equip_slot: u8, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -453,14 +456,14 @@ where } -pub(super) fn unequip_inventory_item( +pub(super) fn unequip_inventory_item<'a, EG, TR>( character_id: CharacterEntityId, item_id: ClientItemId, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -476,14 +479,14 @@ where -pub(super) fn sort_inventory_items( +pub(super) fn sort_inventory_items<'a, EG, TR>( character_id: CharacterEntityId, item_ids: Vec, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { let item_ids = item_ids.clone(); @@ -499,13 +502,13 @@ where } -pub(super) fn use_consumed_item( +pub(super) fn use_consumed_item<'a, EG, TR>( character: &CharacterEntity, ) -> impl Fn((ItemStateProxy, TR), InventoryItemDetail) - -> BoxFuture), anyhow::Error>> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec), anyhow::Error>> where - EG: EntityGateway + Clone + 'static, - TR: EntityGatewayTransaction + 'static, + EG: EntityGateway + Clone + 'a, + TR: EntityGatewayTransaction + 'a, { let character = character.clone(); move |(mut item_state, transaction), inventory_item| { @@ -525,14 +528,14 @@ where } -pub(super) fn feed_mag_item( +pub(super) fn feed_mag_item<'a, EG, TR>( character: CharacterEntity, mag_item_id: ClientItemId, ) -> impl Fn((ItemStateProxy, TR), InventoryItem) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), CharacterEntity), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, transaction), tool| { let character = character.clone(); @@ -586,7 +589,7 @@ pub(super) fn add_bought_item_to_inventory<'a, EG, TR>( -> Pin> + Send + 'a>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { Box::pin(async move { @@ -644,13 +647,13 @@ where } -pub(super) fn sell_inventory_item( +pub(super) fn sell_inventory_item<'a, EG, TR>( character_id: CharacterEntityId, ) -> impl Fn((ItemStateProxy, TR), InventoryItem) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, transaction), inventory_item| { Box::pin(async move { @@ -685,9 +688,9 @@ where I: Send, O: Send, T: Clone + Send + Sync, - F: Fn(I) -> FR + Send + Sync + Clone + 'static, + F: Fn(I) -> FR + Send + Sync + Clone + 'a, FR: Fn((ItemStateProxy, TR), T) - -> BoxFuture> + Send + Sync, + -> BoxFuture<'a, Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync, { let item = match input.pop() { Some(item) => item, @@ -703,20 +706,20 @@ where Ok((state, output)) } -pub(super) fn iterate( +pub(super) fn iterate<'a, EG, TR, I, O, T, F, FR>( input: Vec, func: F, ) -> impl Fn((ItemStateProxy, TR), T) - -> BoxFuture), anyhow::Error>> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, O: Send, I: Send + Clone + 'static + std::fmt::Debug, T: Send + Clone + 'static + std::fmt::Debug, - F: Fn(I) -> FR + Send + Sync + Clone + 'static, + F: Fn(I) -> FR + Send + Sync + Clone + 'a, FR: Fn((ItemStateProxy, TR), T) - -> BoxFuture> + Send + Sync, + -> BoxFuture<'a, Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync, T: Clone + Send + Sync, { move |(item_state, transaction), arg| { @@ -739,12 +742,12 @@ async fn foreach_inner<'a, EG, TR, O, T, F, I>( where 'a: 'async_recursion, EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, O: Send, T: Send, F: Fn((ItemStateProxy, TR), T) - -> BoxFuture> + Send + Sync, - I: Iterator + Send + Sync + 'static, + -> BoxFuture<'a, Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync, + I: Iterator + Send + Sync + 'a, { let item = match input.next() { Some(item) => item, @@ -759,19 +762,19 @@ where Ok((state, output)) } -pub(super) fn foreach( +pub(super) fn foreach<'a, EG, TR, O, T, F, I>( func: F ) -> impl Fn((ItemStateProxy, TR), I) - -> BoxFuture), anyhow::Error>> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, O: Send, T: Send + Clone + 'static + std::fmt::Debug, F: Fn((ItemStateProxy, TR), T) - -> BoxFuture> + Send + Sync + 'static, + -> BoxFuture<'a, Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync + 'a, T: Send + Sync, - I: IntoIterator + Send + Sync + 'static, + I: IntoIterator + Send + Sync + 'a, I::IntoIter: Send + Sync, { let func = Arc::new(func); @@ -791,7 +794,7 @@ pub(super) fn insert<'a, EG, TR, T>( -> Pin> + Send + 'a>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, T: Send + Clone + 'a, { move |state, _| { @@ -802,17 +805,17 @@ where } } -pub(super) fn fork( +pub(super) fn fork<'a, EG, TR, F1, F2, T, O1, O2>( func1: F1, func2: F2, ) -> impl Fn((ItemStateProxy, TR), T) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), (O1, O2)), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, - F1: Fn((ItemStateProxy, TR), T) -> BoxFuture> + Send + Sync + 'static, - F2: Fn((ItemStateProxy, TR), T) -> BoxFuture> + Send + Sync + 'static, - T: Send + Sync + Clone + 'static, + TR: EntityGatewayTransaction + 'a, + F1: Fn((ItemStateProxy, TR), T) -> BoxFuture<'a, Result<((ItemStateProxy, TR), O1), anyhow::Error>> + Send + Sync + 'a, + F2: Fn((ItemStateProxy, TR), T) -> BoxFuture<'a, Result<((ItemStateProxy, TR), O2), anyhow::Error>> + Send + Sync + 'a, + T: Send + Sync + Clone + 'a, O1: Send, O2: Send, { @@ -830,13 +833,13 @@ where } } -pub(super) fn add_item_to_inventory( +pub(super) fn add_item_to_inventory<'a, EG, TR>( character: CharacterEntity, ) -> impl Fn((ItemStateProxy, TR), InventoryItem) - -> BoxFuture> + Clone + -> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Clone where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, transaction), inventory_item| { let character = character.clone(); @@ -858,15 +861,15 @@ where } } -pub(super) fn record_trade( +pub(super) fn record_trade<'a, EG, TR>( trade_id: TradeId, character_to: CharacterEntityId, character_from: CharacterEntityId, ) -> impl Fn((ItemStateProxy, TR), Vec) - -> BoxFuture), anyhow::Error>> + Clone + -> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec), anyhow::Error>> + Clone where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(item_state, mut transaction), traded_items| { Box::pin(async move { @@ -887,12 +890,12 @@ where } -pub(super) fn assign_new_item_id( +pub(super) fn assign_new_item_id<'a, EG, TR>( ) -> impl Fn((ItemStateProxy, TR), InventoryItem) - -> BoxFuture> + Clone + -> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Clone where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, transaction), mut inventory_item| { Box::pin(async move { @@ -903,14 +906,14 @@ where } -pub(super) fn convert_item_drop_to_floor_item( +pub(super) fn convert_item_drop_to_floor_item<'a, EG, TR>( character_id: CharacterEntityId, item_drop: ItemDrop, ) -> impl Fn((ItemStateProxy, TR), ()) - -> BoxFuture> + Clone + -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), _| { let item_drop = item_drop.clone(); @@ -1005,13 +1008,13 @@ where } } -pub(super) fn add_item_to_local_floor( +pub(super) fn add_item_to_local_floor<'a, EG, TR>( character_id: CharacterEntityId, ) -> impl Fn((ItemStateProxy, TR), FloorItem) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, transaction) , floor_item| { Box::pin(async move { @@ -1024,13 +1027,13 @@ where } } -pub(super) fn apply_modifier_to_inventory_item( +pub(super) fn apply_modifier_to_inventory_item<'a, EG, TR>( modifier: ItemModifier, ) -> impl Fn((ItemStateProxy, TR), InventoryItem) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(item_state, mut transaction), mut inventory_item| { let modifier = modifier.clone(); @@ -1048,12 +1051,12 @@ where } } -pub(super) fn as_individual_item( +pub(super) fn as_individual_item<'a, EG, TR>( ) -> impl Fn((ItemStateProxy, TR), InventoryItem) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), IndividualItemDetail), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(item_state, transaction), inventory_item| { Box::pin(async move { @@ -1068,14 +1071,14 @@ where } -pub(super) fn apply_item_action_packets( +pub(super) fn apply_item_action_packets<'a, EG, TR>( character_id: CharacterEntityId, area_client: AreaClient, ) -> impl Fn((ItemStateProxy, TR), ApplyItemAction) - -> BoxFuture), anyhow::Error>> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { move |(mut item_state, mut transaction), apply_item_action| { Box::pin(async move { @@ -1126,13 +1129,13 @@ where } } -pub(super) fn apply_item_action_character( +pub(super) fn apply_item_action_character<'a, EG, TR>( character: &CharacterEntity ) -> impl Fn((ItemStateProxy, TR), Vec) - -> BoxFuture> + -> BoxFuture<'a, Result<((ItemStateProxy, TR), CharacterEntity), anyhow::Error>> where EG: EntityGateway, - TR: EntityGatewayTransaction + 'static, + TR: EntityGatewayTransaction + 'a, { let character = character.clone(); move |(item_state, transaction), apply_item_actions| { diff --git a/src/ship/items/apply_item.rs b/src/ship/items/apply_item.rs index 58f3b98..4c1a636 100644 --- a/src/ship/items/apply_item.rs +++ b/src/ship/items/apply_item.rs @@ -354,13 +354,13 @@ where } -pub async fn apply_item<'a, EG>(item_state: &mut ItemStateProxy, - entity_gateway: &mut EG, - character: &mut CharacterEntity, +pub async fn apply_item<'a, EG>(item_state: &'a mut ItemStateProxy, + entity_gateway: &'a mut EG, + character: &'a mut CharacterEntity, item: InventoryItemDetail ) -> Result, anyhow::Error> where - EG: EntityGateway + ?Sized + Clone + 'static + EG: EntityGateway + ?Sized + Clone + 'a { match item { InventoryItemDetail::Individual(individual_item) => { diff --git a/src/ship/items/itemstateaction.rs b/src/ship/items/itemstateaction.rs index 3b60548..fdbbc8f 100644 --- a/src/ship/items/itemstateaction.rs +++ b/src/ship/items/itemstateaction.rs @@ -1,4 +1,5 @@ use std::future::Future; +use futures::future::BoxFuture; #[async_trait::async_trait] pub trait ItemAction { @@ -34,38 +35,40 @@ where S: Send + Sync, E: Send + Sync, { - pub fn act(self, f: F) -> ItemActionStage, F, Fut, S, E> + pub fn act<'a, O, F, Fut>(self, f: F) -> ItemActionStage<'a, O, ItemStateAction, F, Fut, S, E> where - F: Fn(S, ()) -> Fut + Send + Sync, - Fut: Future> + Send + F: Fn(S, ()) -> Fut + Send + Sync + 'a, + Fut: Future> + Send + 'a { ItemActionStage { _s: Default::default(), _e: std::marker::PhantomData, + _a: Default::default(), prev: self, actionf: f, } } } -pub struct ItemActionStage +pub struct ItemActionStage<'a, O, P, F, Fut, S, E> where P: ItemAction, - F: Fn(S, P::Output) -> Fut + Send + Sync, - Fut: Future> + Send, + F: Fn(S, P::Output) -> Fut + Send + Sync + 'a, + Fut: Future> + Send + 'a, { _s: std::marker::PhantomData, _e: std::marker::PhantomData, + _a: std::marker::PhantomData<&'a ()>, prev: P, actionf: F, } #[async_trait::async_trait] -impl ItemAction for ItemActionStage +impl<'a, O, P: ItemAction, F, Fut, S, E> ItemAction for ItemActionStage<'a, O, P, F, Fut, S, E> where P: ItemAction + ItemAction + Send + Sync, - F: Fn(S, P::Output) -> Fut + Send + Sync, - Fut: Future> + Send, + F: Fn(S, P::Output) -> Fut + Send + Sync + 'a, + Fut: Future> + Send + 'a, S: Send + Sync, P::Output: Send + Sync, E: Send + Sync, @@ -87,11 +90,11 @@ where } } -impl ItemActionStage +impl<'a, O, P: ItemAction, F, Fut, S, E> ItemActionStage<'a, O, P, F, Fut, S, E> where P: ItemAction + Send + Sync, - F: Fn(S, P::Output) -> Fut + Send + Sync, - Fut: Future> + Send, + F: Fn(S, P::Output) -> Fut + Send + Sync + 'a, + Fut: Future> + Send + 'a, S: Send + Sync, P::Output: Send + Sync, E: Send + Sync, @@ -99,16 +102,17 @@ where P::Error: Send + Sync, { #[allow(clippy::type_complexity)] - pub fn act(self, g: G) -> ItemActionStage, G, GFut, S, E> + pub fn act<'b, O2, G, GFut>(self, g: G) -> ItemActionStage<'b, O2, ItemActionStage<'a, O, P, F, Fut, S, E>, G, GFut, S, E> where S: Send + Sync, - G: Fn(S, as ItemAction>::Output) -> GFut + Send + Sync, - GFut: Future> + Send, + G: Fn(S, as ItemAction>::Output) -> GFut + Send + Sync + 'b, + GFut: Future> + Send + 'b, O2: Send + Sync, { ItemActionStage { _s: Default::default(), _e: Default::default(), + _a: Default::default(), prev: self, actionf: g, } diff --git a/src/ship/items/tasks.rs b/src/ship/items/tasks.rs index c0d71ed..89ad6b4 100644 --- a/src/ship/items/tasks.rs +++ b/src/ship/items/tasks.rs @@ -1,3 +1,4 @@ +use futures::future::{Future, BoxFuture}; use crate::ship::items::ClientItemId; use crate::entity::item::Meseta; @@ -17,17 +18,18 @@ use crate::ship::drops::ItemDrop; use crate::ship::items::actions; -pub async fn pick_up_item( - item_state: &mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: &ClientItemId) - -> Result +//pub async fn pick_up_item<'a, EG>( +pub fn pick_up_item<'a, EG>( + item_state: &'a mut ItemState, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + item_id: &'a ClientItemId, +) -> BoxFuture<'a, Result> where EG: EntityGateway + 'static, - EG::Transaction: Clone, + EG::Transaction<'a>: Clone, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::take_item_from_floor(character.id, *item_id)) @@ -36,21 +38,22 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn drop_item( - item_state: &mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: &ClientItemId, +pub fn drop_item<'a, EG>( + item_state: &'a mut ItemState, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + item_id: &'a ClientItemId, map_area: MapArea, - drop_position: (f32, f32, f32)) - -> Result + drop_position: (f32, f32, f32), +)-> BoxFuture<'a, Result> where EG: EntityGateway + 'static, + EG::Transaction<'a>: Clone, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::take_item_from_inventory(character.id, *item_id, 0)) @@ -59,22 +62,22 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn drop_partial_item<'a, EG>( +pub fn drop_partial_item<'a, EG>( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: &ClientItemId, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + item_id: &'a ClientItemId, map_area: MapArea, drop_position: (f32, f32), - amount: u32) - -> Result + amount: u32 +) -> BoxFuture<'a, Result> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::take_item_from_inventory(character.id, *item_id, amount)) @@ -83,23 +86,23 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn drop_meseta<'a, EG>( +pub fn drop_meseta<'a, EG>( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, map_area: MapArea, drop_position: (f32, f32), - amount: u32) - -> Result + amount: u32, +) -> BoxFuture<'a, Result> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::take_meseta_from_inventory(character.id, amount)) @@ -108,20 +111,20 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn withdraw_meseta<'a, EG>( +pub fn withdraw_meseta<'a, EG>( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - amount: u32) - -> Result<(), anyhow::Error> + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + amount: u32, +) -> BoxFuture<'a, Result<(), anyhow::Error>> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::take_meseta_from_bank(character.id, amount)) @@ -130,20 +133,20 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn deposit_meseta<'a, EG>( +pub fn deposit_meseta<'a, EG>( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - amount: u32) - -> Result<(), anyhow::Error> + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + amount: u32, +) -> BoxFuture<'a, Result<(), anyhow::Error>> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), _) = ItemStateAction::default() .act(actions::take_meseta_from_inventory(character.id, amount)) @@ -152,21 +155,21 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, ())) - }).await + }) } -pub async fn withdraw_item<'a, EG>( +pub fn withdraw_item<'a, EG>( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: &ClientItemId, - amount: u32) - -> Result + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + item_id: &'a ClientItemId, + amount: u32, +) -> BoxFuture<'a, Result> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::take_item_from_bank(character.id, *item_id, amount)) @@ -177,21 +180,21 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn deposit_item<'a, EG> ( +pub fn deposit_item<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: &ClientItemId, - amount: u32) - -> Result<(), anyhow::Error> + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + item_id: &'a ClientItemId, + amount: u32, +) -> BoxFuture<'a, Result<(), anyhow::Error>> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::take_item_from_inventory(character.id, *item_id, amount)) @@ -200,20 +203,20 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn equip_item<'a, EG> ( +pub fn equip_item<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: &ClientItemId, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + item_id: &'a ClientItemId, equip_slot: u8, -) -> Result<(), anyhow::Error> +) -> BoxFuture<'a, Result<(), anyhow::Error>> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::equip_inventory_item(character.id, *item_id, equip_slot)) @@ -221,20 +224,20 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn unequip_item<'a, EG> ( +pub fn unequip_item<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - item_id: &ClientItemId, -) -> Result<(), anyhow::Error> + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + item_id: &'a ClientItemId, +) -> BoxFuture<'a, Result<(), anyhow::Error>> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::unequip_inventory_item(character.id, *item_id)) @@ -242,20 +245,20 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn sort_inventory<'a, EG> ( +pub fn sort_inventory<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, item_ids: Vec, -) -> Result<(), anyhow::Error> +) -> BoxFuture<'a, Result<(), anyhow::Error>> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::sort_inventory_items(character.id, item_ids)) @@ -263,22 +266,22 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn use_item<'a, EG> ( +pub fn use_item<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &mut CharacterEntity, + entity_gateway: &'a mut EG, + character: &'a mut CharacterEntity, area_client: AreaClient, - item_id: &ClientItemId, + item_id: &'a ClientItemId, amount: u32, -) -> Result, anyhow::Error> +) -> BoxFuture<'a, Result, anyhow::Error>> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), (pkts, new_character)) = ItemStateAction::default() .act(actions::remove_item_from_inventory(character.id, *item_id, amount)) @@ -293,21 +296,21 @@ where *character = new_character; Ok((transaction, pkts.into_iter().flatten().collect())) - }).await + }) } -pub async fn feed_mag<'a, EG> ( +pub fn feed_mag<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, - mag_item_id: &ClientItemId, - tool_item_id: &ClientItemId, -) -> Result<(), anyhow::Error> + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + mag_item_id: &'a ClientItemId, + tool_item_id: &'a ClientItemId, +) -> BoxFuture<'a, Result<(), anyhow::Error>> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), _) = ItemStateAction::default() .act(actions::take_item_from_inventory(character.id, *tool_item_id, 1)) @@ -316,23 +319,23 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, ())) - }).await + }) } -pub async fn buy_shop_item<'a, EG> ( +pub fn buy_shop_item<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, shop_item: &'a (dyn ShopItem + Send + Sync), item_id: ClientItemId, amount: u32, -) -> Result +) -> BoxFuture<'a, Result> where EG: EntityGateway + 'static, { let item_price = shop_item.price() as u32 * amount; - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::take_meseta_from_inventory(character.id, item_price)) @@ -343,21 +346,21 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn sell_item<'a, EG> ( +pub fn sell_item<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, item_id: ClientItemId, amount: u32, -) -> Result +) -> BoxFuture<'a, Result> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), result) = ItemStateAction::default() .act(actions::take_item_from_inventory(character.id, item_id, amount)) @@ -366,14 +369,14 @@ where .await?; item_state_proxy.commit().await; Ok((transaction, result)) - }).await + }) } -pub async fn trade_items<'a, EG> ( +pub fn trade_items<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - p1: (&AreaClient, &CharacterEntity, &Vec, Meseta), - p2: (&AreaClient, &CharacterEntity, &Vec, Meseta)) - -> Result<(Vec, Vec), anyhow::Error> + entity_gateway: &'a mut EG, + p1: (&'a AreaClient, &'a CharacterEntity, &'a Vec, Meseta), + p2: (&'a AreaClient, &'a CharacterEntity, &'a Vec, Meseta)) + -> BoxFuture<'a, Result<(Vec, Vec), anyhow::Error>> where EG: EntityGateway + 'static, { @@ -395,7 +398,7 @@ where } }) .collect(); - entity_gateway.with_transaction(|mut transaction| async move { + entity_gateway.with_transaction(move |mut transaction| async move { let p1_id = p1.1.id; let p2_id = p2.1.id; let trade = transaction.gateway().create_trade(&p1_id, &p2_id).await?; @@ -434,20 +437,20 @@ where item_state_proxy.commit().await; Ok((transaction, (p1_new_items, p2_new_items))) - }).await + }) } -pub async fn take_meseta<'a, EG> ( +pub fn take_meseta<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character_id: &CharacterEntityId, + entity_gateway: &'a mut EG, + character_id: &'a CharacterEntityId, meseta: Meseta) - -> Result<(), anyhow::Error> + -> BoxFuture<'a, Result<(), anyhow::Error>> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), _) = ItemStateAction::default() .act(actions::take_meseta_from_inventory(*character_id, meseta.0)) @@ -456,19 +459,19 @@ where item_state_proxy.commit().await; Ok((transaction, ())) - }).await + }) } -pub async fn enemy_drops_item<'a, EG> ( +pub fn enemy_drops_item<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, + entity_gateway: &'a mut EG, character_id: CharacterEntityId, item_drop: ItemDrop) - -> Result + -> BoxFuture<'a, Result> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default() .act(actions::convert_item_drop_to_floor_item(character_id, item_drop)) @@ -478,21 +481,21 @@ where item_state_proxy.commit().await; Ok((transaction, floor_item)) - }).await + }) } -pub async fn apply_modifier<'a, EG> ( +pub fn apply_modifier<'a, EG> ( item_state: &'a mut ItemState, - entity_gateway: &mut EG, - character: &CharacterEntity, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, item_id: ClientItemId, modifier: ItemModifier) - -> Result + -> BoxFuture<'a, Result> where EG: EntityGateway + 'static, { - entity_gateway.with_transaction(|transaction| async move { + entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), item) = ItemStateAction::default() .act(actions::take_item_from_inventory(character.id, item_id, 1)) @@ -504,5 +507,5 @@ where item_state_proxy.commit().await; Ok((transaction, item)) - }).await + }) }