use GATs to remove lifetime on postgresgateway #132

Merged
jake merged 2 commits from gat_fuckery into master 2 years ago
  1. 10
      src/entity/gateway/entitygateway.rs
  2. 96
      src/entity/gateway/inmemory.rs
  3. 39
      src/entity/gateway/postgres/postgres.rs
  4. 4
      src/login/character.rs
  5. 10
      src/login/login.rs
  6. 230
      src/ship/items/actions.rs
  7. 8
      src/ship/items/apply_item.rs
  8. 33
      src/ship/items/itemstateaction.rs
  9. 270
      src/ship/items/tasks.rs

10
src/entity/gateway/entitygateway.rs

@ -1,5 +1,5 @@
use thiserror::Error; use thiserror::Error;
use futures::Future;
use futures::future::{Future, BoxFuture};
use crate::entity::account::*; use crate::entity::account::*;
use crate::entity::character::*; use crate::entity::character::*;
@ -19,12 +19,12 @@ pub enum GatewayError {
#[async_trait::async_trait] #[async_trait::async_trait]
pub trait EntityGateway: Send + Sync { 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<R, anyhow::Error>
fn with_transaction<'a, F, Fut, R>(&'a mut self, _func: F) -> BoxFuture<'a, Result<R, anyhow::Error>>
where where
Fut: Future<Output = Result<(Self::Transaction, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction) -> Fut + Send,
Fut: Future<Output = Result<(Self::Transaction<'a>, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction<'a>) -> Fut + Send + 'a,
R: Send, R: Send,
Self: Sized Self: Sized
{ {

96
src/entity/gateway/inmemory.rs

@ -1,6 +1,6 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::convert::TryInto; use std::convert::TryInto;
use futures::Future;
use futures::future::{Future, BoxFuture};
use crate::entity::account::*; use crate::entity::account::*;
use crate::entity::character::*; use crate::entity::character::*;
@ -31,7 +31,7 @@ where
// functions here have been skipped as they are not used in transactions, add as needed // functions here have been skipped as they are not used in transactions, add as needed
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for InMemoryGatewayTransaction { impl EntityGateway for InMemoryGatewayTransaction {
type Transaction = InMemoryGatewayTransaction;
type Transaction<'t> = InMemoryGatewayTransaction where Self: 't;
async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> { async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
self.working_gateway.create_user(user).await self.working_gateway.create_user(user).await
@ -317,55 +317,57 @@ fn apply_modifiers(items: &BTreeMap<ItemEntityId, ItemEntity>,
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for InMemoryGateway { 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<R, anyhow::Error>
fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> BoxFuture<'a, Result<R, anyhow::Error>>
where where
Fut: Future<Output = Result<(Self::Transaction, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction) -> Fut + Send,
Fut: Future<Output = Result<(Self::Transaction<'a>, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction<'a>) -> Fut + Send + 'a,
R: Send, 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<UserAccountEntity, GatewayError> { async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {

39
src/entity/gateway/postgres/postgres.rs

@ -2,7 +2,7 @@
#![allow(clippy::explicit_auto_deref)] #![allow(clippy::explicit_auto_deref)]
use std::convert::{From, TryFrom, Into}; use std::convert::{From, TryFrom, Into};
use futures::Future;
use futures::future::{Future, BoxFuture};
use futures::stream::{StreamExt, FuturesOrdered}; use futures::stream::{StreamExt, FuturesOrdered};
use async_std::sync::{Arc, Mutex}; use async_std::sync::{Arc, Mutex};
use libpso::character::guildcard; use libpso::character::guildcard;
@ -36,9 +36,7 @@ impl<'t> EntityGatewayTransaction for PostgresTransaction<'t> {
self self
} }
//async fn commit(self: Box<Self>) -> Result<(), GatewayError> {
async fn commit(self) -> Result<(), GatewayError> { async fn commit(self) -> Result<(), GatewayError> {
//self.pgtransaction.lock().await.commit().await?;
Arc::try_unwrap(self.pgtransaction) Arc::try_unwrap(self.pgtransaction)
.unwrap() .unwrap()
.into_inner() .into_inner()
@ -50,13 +48,12 @@ impl<'t> EntityGatewayTransaction for PostgresTransaction<'t> {
#[derive(Clone)] #[derive(Clone)]
pub struct PostgresGateway<'t> {
pub struct PostgresGateway {
pool: sqlx::Pool<sqlx::Postgres>, pool: sqlx::Pool<sqlx::Postgres>,
_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) let mut conn = refinery::config::Config::new(refinery::config::ConfigDbType::Postgres)
.set_db_host(host) .set_db_host(host)
.set_db_user(username) .set_db_user(username)
@ -72,7 +69,6 @@ impl<'t> PostgresGateway<'t> {
PostgresGateway { PostgresGateway {
pool, pool,
_t: Default::default(),
} }
} }
} }
@ -568,6 +564,7 @@ async fn set_character_equips(conn: &mut sqlx::PgConnection, char_id: &Character
Ok(()) Ok(())
} }
async fn set_character_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> 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") 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] #[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<R, anyhow::Error>
fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> BoxFuture<'a, Result<R, anyhow::Error>>
where where
Fut: Future<Output = Result<(Self::Transaction, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction) -> Fut + Send,
Fut: Future<Output = Result<(Self::Transaction<'a>, R), anyhow::Error>> + Send + 'a,
F: FnOnce(Self::Transaction<'a>) -> Fut + Send + 'a,
R: Send, 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<UserAccountEntity, GatewayError> { async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
@ -803,7 +802,7 @@ impl<'t> EntityGateway for PostgresGateway<'t> {
#[async_trait::async_trait] #[async_trait::async_trait]
impl<'c> EntityGateway for PostgresTransaction<'c> { 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<UserAccountEntity, GatewayError> { async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
create_user(&mut *self.pgtransaction.lock().await, user).await create_user(&mut *self.pgtransaction.lock().await, user).await

4
src/login/character.rs

@ -846,7 +846,7 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
type Transaction = ();
type Transaction<'a> = () where Self: 'a;
async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result<UserSettingsEntity, GatewayError> { async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result<UserSettingsEntity, GatewayError> {
Ok(UserSettingsEntity { Ok(UserSettingsEntity {
id: UserSettingsId(0), id: UserSettingsId(0),
@ -889,7 +889,7 @@ mod test {
#[derive(Clone)] #[derive(Clone)]
struct TestData; struct TestData;
impl EntityGateway for TestData { impl EntityGateway for TestData {
type Transaction = ();
type Transaction<'a> = () where Self: 'a;
} }
let mut server = CharacterServerState::new(TestData {}, AuthToken("".into())); let mut server = CharacterServerState::new(TestData {}, AuthToken("".into()));
let send = server.handle(ClientId(1), RecvCharacterPacket::Checksum(Checksum {checksum: 1234, let send = server.handle(ClientId(1), RecvCharacterPacket::Checksum(Checksum {checksum: 1234,

10
src/login/login.rs

@ -206,7 +206,7 @@ mod test {
}); });
impl EntityGateway for () { impl EntityGateway for () {
type Transaction = ();
type Transaction<'t> = () where Self: 't;
} }
impl EntityGatewayTransaction for () { impl EntityGatewayTransaction for () {
@ -221,7 +221,7 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
type Transaction = ();
type Transaction<'t> = () where Self: 't;
async fn get_user_by_name(&mut self, name: String) -> Result<UserAccountEntity, GatewayError> { async fn get_user_by_name(&mut self, name: String) -> Result<UserAccountEntity, GatewayError> {
assert!(name == "testuser"); assert!(name == "testuser");
Ok(UserAccountEntity { Ok(UserAccountEntity {
@ -280,7 +280,7 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
type Transaction = ();
type Transaction<'t> = () where Self: 't;
async fn get_user_by_name(&mut self, _name: String) -> Result<UserAccountEntity, GatewayError> { async fn get_user_by_name(&mut self, _name: String) -> Result<UserAccountEntity, GatewayError> {
Err(GatewayError::Error) Err(GatewayError::Error)
} }
@ -315,7 +315,7 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
type Transaction = ();
type Transaction<'t> = () where Self: 't;
async fn get_user_by_name(&mut self, name: String) -> Result<UserAccountEntity, GatewayError> { async fn get_user_by_name(&mut self, name: String) -> Result<UserAccountEntity, GatewayError> {
assert!(name == "testuser"); assert!(name == "testuser");
Ok(UserAccountEntity { Ok(UserAccountEntity {
@ -365,7 +365,7 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
type Transaction = ();
type Transaction<'t> = () where Self: 't;
async fn get_user_by_name(&mut self, name: String) -> Result<UserAccountEntity, GatewayError> { async fn get_user_by_name(&mut self, name: String) -> Result<UserAccountEntity, GatewayError> {
assert!(name == "testuser"); assert!(name == "testuser");
Ok(UserAccountEntity { Ok(UserAccountEntity {

230
src/ship/items/actions.rs

@ -3,6 +3,7 @@ use crate::ship::items::ClientItemId;
use crate::entity::item::{Meseta, ItemNote}; use crate::entity::item::{Meseta, ItemNote};
use async_std::sync::Arc; use async_std::sync::Arc;
use std::future::Future; use std::future::Future;
use futures::future::BoxFuture;
use std::pin::Pin; use std::pin::Pin;
use std::iter::IntoIterator; use std::iter::IntoIterator;
use anyhow::Context; use anyhow::Context;
@ -25,21 +26,19 @@ use crate::ship::drops::{ItemDrop, ItemDropType};
use crate::ship::packet::builder; use crate::ship::packet::builder;
use crate::ship::location::AreaClient; use crate::ship::location::AreaClient;
type BoxFuture<T> = Pin<Box<dyn Future<Output=T> + Send>>;
pub enum TriggerCreateItem { pub enum TriggerCreateItem {
Yes, Yes,
No No
} }
pub(super) fn take_item_from_floor<EG, TR>(
pub(super) fn take_item_from_floor<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
item_id: ClientItemId item_id: ClientItemId
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + 'a
where where
EG: EntityGateway + Send, EG: EntityGateway + Send,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, transaction): (ItemStateProxy, TR) , _| { move |(mut item_state, transaction): (ItemStateProxy, TR) , _| {
Box::pin(async move { Box::pin(async move {
@ -52,13 +51,13 @@ where
} }
} }
pub(super) fn add_floor_item_to_inventory<EG, TR>(
pub(super) fn add_floor_item_to_inventory<'a, EG, TR>(
character: &CharacterEntity character: &CharacterEntity
) -> impl Fn((ItemStateProxy, TR), FloorItem) ) -> impl Fn((ItemStateProxy, TR), FloorItem)
-> BoxFuture<Result<((ItemStateProxy, TR), TriggerCreateItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), TriggerCreateItem), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + Clone + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + Clone + 'a,
{ {
let character = character.clone(); let character = character.clone();
move |(mut item_state, transaction), floor_item| { move |(mut item_state, transaction), floor_item| {
@ -98,15 +97,15 @@ where
} }
pub(super) fn remove_item_from_inventory<EG, TR>(
pub(super) fn remove_item_from_inventory<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
item_id: ClientItemId, item_id: ClientItemId,
amount: u32, amount: u32,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItemDetail), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItemDetail), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -124,22 +123,23 @@ where
} }
} }
pub(super) fn take_item_from_inventory<EG, TR>(
pub(super) fn take_item_from_inventory<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
item_id: ClientItemId, item_id: ClientItemId,
amount: u32, amount: u32,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
where where
EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
EG: EntityGateway + 'a,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
let mut inventory = item_state.inventory(&character_id).await?; let mut inventory = item_state.inventory(&character_id).await?;
let item = inventory.take_item(&item_id, amount) let item = inventory.take_item(&item_id, amount)
.await .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?; transaction.gateway().set_character_inventory(&character_id, &inventory.as_inventory_entity(&character_id)).await?;
item_state.set_inventory(inventory).await; item_state.set_inventory(inventory).await;
@ -150,15 +150,15 @@ where
} }
pub(super) fn add_inventory_item_to_shared_floor<EG, TR>(
pub(super) fn add_inventory_item_to_shared_floor<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
map_area: MapArea, map_area: MapArea,
drop_position: (f32, f32, f32), drop_position: (f32, f32, f32),
) -> impl Fn((ItemStateProxy, TR), InventoryItem) ) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, transaction), inventory_item| { move |(mut item_state, transaction), inventory_item| {
Box::pin(async move { Box::pin(async move {
@ -184,14 +184,14 @@ where
} }
pub(super) fn take_meseta_from_inventory<EG, TR>(
pub(super) fn take_meseta_from_inventory<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
amount: u32, amount: u32,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -205,14 +205,14 @@ where
} }
} }
pub(super) fn add_meseta_to_inventory<EG, TR>(
pub(super) fn add_meseta_to_inventory<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
amount: u32 amount: u32
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -226,16 +226,16 @@ where
} }
} }
pub(super) fn add_meseta_to_shared_floor<EG, TR>(
pub(super) fn add_meseta_to_shared_floor<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
amount: u32, amount: u32,
map_area: MapArea, map_area: MapArea,
drop_position: (f32, f32) drop_position: (f32, f32)
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, transaction), _| { move |(mut item_state, transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -257,14 +257,14 @@ where
} }
} }
pub(super) fn take_meseta_from_bank<EG, TR>(
pub(super) fn take_meseta_from_bank<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
amount: u32, amount: u32,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -278,14 +278,14 @@ where
} }
} }
pub(super) fn add_meseta_from_bank_to_inventory<EG, TR>(
pub(super) fn add_meseta_from_bank_to_inventory<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
amount: u32, amount: u32,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -300,14 +300,14 @@ where
} }
pub(super) fn add_meseta_to_bank<EG, TR>(
pub(super) fn add_meseta_to_bank<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
amount: u32, amount: u32,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -322,15 +322,15 @@ where
} }
pub(super) fn take_item_from_bank<EG, TR>(
pub(super) fn take_item_from_bank<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
item_id: ClientItemId, item_id: ClientItemId,
amount: u32, amount: u32,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), BankItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), BankItem), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -346,13 +346,13 @@ where
} }
} }
pub(super) fn add_bank_item_to_inventory<EG, TR>(
pub(super) fn add_bank_item_to_inventory<'a, EG, TR>(
character: &CharacterEntity, character: &CharacterEntity,
) -> impl Fn((ItemStateProxy, TR), BankItem) ) -> impl Fn((ItemStateProxy, TR), BankItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
let character = character.clone(); let character = character.clone();
move |(mut item_state, transaction), bank_item| { move |(mut item_state, transaction), bank_item| {
@ -397,13 +397,13 @@ where
} }
pub(super) fn add_inventory_item_to_bank<EG, TR>(
pub(super) fn add_inventory_item_to_bank<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
) -> impl Fn((ItemStateProxy, TR), InventoryItem) ) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, transaction), inventory_item| { move |(mut item_state, transaction), inventory_item| {
Box::pin(async move { Box::pin(async move {
@ -430,15 +430,15 @@ where
} }
pub(super) fn equip_inventory_item<EG, TR>(
pub(super) fn equip_inventory_item<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
item_id: ClientItemId, item_id: ClientItemId,
equip_slot: u8, equip_slot: u8,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -453,14 +453,14 @@ where
} }
pub(super) fn unequip_inventory_item<EG, TR>(
pub(super) fn unequip_inventory_item<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
item_id: ClientItemId, item_id: ClientItemId,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -476,14 +476,14 @@ where
pub(super) fn sort_inventory_items<EG, TR>(
pub(super) fn sort_inventory_items<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
item_ids: Vec<ClientItemId>, item_ids: Vec<ClientItemId>,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), ()), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
let item_ids = item_ids.clone(); let item_ids = item_ids.clone();
@ -499,13 +499,13 @@ where
} }
pub(super) fn use_consumed_item<EG, TR>(
pub(super) fn use_consumed_item<'a, EG, TR>(
character: &CharacterEntity, character: &CharacterEntity,
) -> impl Fn((ItemStateProxy, TR), InventoryItemDetail) ) -> impl Fn((ItemStateProxy, TR), InventoryItemDetail)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<ApplyItemAction>), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec<ApplyItemAction>), anyhow::Error>>
where where
EG: EntityGateway + Clone + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
EG: EntityGateway + Clone + 'a,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
let character = character.clone(); let character = character.clone();
move |(mut item_state, transaction), inventory_item| { move |(mut item_state, transaction), inventory_item| {
@ -525,14 +525,14 @@ where
} }
pub(super) fn feed_mag_item<EG, TR>(
pub(super) fn feed_mag_item<'a, EG, TR>(
character: CharacterEntity, character: CharacterEntity,
mag_item_id: ClientItemId, mag_item_id: ClientItemId,
) -> impl Fn((ItemStateProxy, TR), InventoryItem) ) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), CharacterEntity), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), CharacterEntity), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, transaction), tool| { move |(mut item_state, transaction), tool| {
let character = character.clone(); let character = character.clone();
@ -586,7 +586,7 @@ pub(super) fn add_bought_item_to_inventory<'a, EG, TR>(
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Send + 'a>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
Box::pin(async move { Box::pin(async move {
@ -644,13 +644,13 @@ where
} }
pub(super) fn sell_inventory_item<EG, TR>(
pub(super) fn sell_inventory_item<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
) -> impl Fn((ItemStateProxy, TR), InventoryItem) ) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, transaction), inventory_item| { move |(mut item_state, transaction), inventory_item| {
Box::pin(async move { Box::pin(async move {
@ -685,9 +685,9 @@ where
I: Send, I: Send,
O: Send, O: Send,
T: Clone + Send + Sync, 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) FR: Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync,
-> BoxFuture<'a, Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync,
{ {
let item = match input.pop() { let item = match input.pop() {
Some(item) => item, Some(item) => item,
@ -703,20 +703,20 @@ where
Ok((state, output)) Ok((state, output))
} }
pub(super) fn iterate<EG, TR, I, O, T, F, FR>(
pub(super) fn iterate<'a, EG, TR, I, O, T, F, FR>(
input: Vec<I>, input: Vec<I>,
func: F, func: F,
) -> impl Fn((ItemStateProxy, TR), T) ) -> impl Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<O>), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec<O>), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
O: Send, O: Send,
I: Send + Clone + 'static + std::fmt::Debug, I: Send + Clone + 'static + std::fmt::Debug,
T: 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) FR: Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync,
-> BoxFuture<'a, Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync,
T: Clone + Send + Sync, T: Clone + Send + Sync,
{ {
move |(item_state, transaction), arg| { move |(item_state, transaction), arg| {
@ -739,12 +739,12 @@ async fn foreach_inner<'a, EG, TR, O, T, F, I>(
where where
'a: 'async_recursion, 'a: 'async_recursion,
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
O: Send, O: Send,
T: Send, T: Send,
F: Fn((ItemStateProxy, TR), T) F: Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync,
I: Iterator<Item = T> + Send + Sync + 'static,
-> BoxFuture<'a, Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync,
I: Iterator<Item = T> + Send + Sync + 'a,
{ {
let item = match input.next() { let item = match input.next() {
Some(item) => item, Some(item) => item,
@ -759,19 +759,19 @@ where
Ok((state, output)) Ok((state, output))
} }
pub(super) fn foreach<EG, TR, O, T, F, I>(
pub(super) fn foreach<'a, EG, TR, O, T, F, I>(
func: F func: F
) -> impl Fn((ItemStateProxy, TR), I) ) -> impl Fn((ItemStateProxy, TR), I)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<O>), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec<O>), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
O: Send, O: Send,
T: Send + Clone + 'static + std::fmt::Debug, T: Send + Clone + 'static + std::fmt::Debug,
F: Fn((ItemStateProxy, TR), T) F: Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync + 'static,
-> BoxFuture<'a, Result<((ItemStateProxy, TR), O), anyhow::Error>> + Send + Sync + 'a,
T: Send + Sync, T: Send + Sync,
I: IntoIterator<Item = T> + Send + Sync + 'static,
I: IntoIterator<Item = T> + Send + Sync + 'a,
I::IntoIter: Send + Sync, I::IntoIter: Send + Sync,
{ {
let func = Arc::new(func); let func = Arc::new(func);
@ -791,7 +791,7 @@ pub(super) fn insert<'a, EG, TR, T>(
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), T), anyhow::Error>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy, TR), T), anyhow::Error>> + Send + 'a>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
T: Send + Clone + 'a, T: Send + Clone + 'a,
{ {
move |state, _| { move |state, _| {
@ -802,17 +802,17 @@ where
} }
} }
pub(super) fn fork<EG, TR, F1, F2, T, O1, O2>(
pub(super) fn fork<'a, EG, TR, F1, F2, T, O1, O2>(
func1: F1, func1: F1,
func2: F2, func2: F2,
) -> impl Fn((ItemStateProxy, TR), T) ) -> impl Fn((ItemStateProxy, TR), T)
-> BoxFuture<Result<((ItemStateProxy, TR), (O1, O2)), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), (O1, O2)), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
F1: Fn((ItemStateProxy, TR), T) -> BoxFuture<Result<((ItemStateProxy, TR), O1), anyhow::Error>> + Send + Sync + 'static,
F2: Fn((ItemStateProxy, TR), T) -> BoxFuture<Result<((ItemStateProxy, TR), O2), anyhow::Error>> + Send + Sync + 'static,
T: Send + Sync + Clone + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + '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, O1: Send,
O2: Send, O2: Send,
{ {
@ -830,13 +830,13 @@ where
} }
} }
pub(super) fn add_item_to_inventory<EG, TR>(
pub(super) fn add_item_to_inventory<'a, EG, TR>(
character: CharacterEntity, character: CharacterEntity,
) -> impl Fn((ItemStateProxy, TR), InventoryItem) ) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Clone
-> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Clone
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, transaction), inventory_item| { move |(mut item_state, transaction), inventory_item| {
let character = character.clone(); let character = character.clone();
@ -858,15 +858,15 @@ where
} }
} }
pub(super) fn record_trade<EG, TR>(
pub(super) fn record_trade<'a, EG, TR>(
trade_id: TradeId, trade_id: TradeId,
character_to: CharacterEntityId, character_to: CharacterEntityId,
character_from: CharacterEntityId, character_from: CharacterEntityId,
) -> impl Fn((ItemStateProxy, TR), Vec<InventoryItem>) ) -> impl Fn((ItemStateProxy, TR), Vec<InventoryItem>)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<InventoryItem>), anyhow::Error>> + Clone
-> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec<InventoryItem>), anyhow::Error>> + Clone
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(item_state, mut transaction), traded_items| { move |(item_state, mut transaction), traded_items| {
Box::pin(async move { Box::pin(async move {
@ -887,12 +887,12 @@ where
} }
pub(super) fn assign_new_item_id<EG, TR>(
pub(super) fn assign_new_item_id<'a, EG, TR>(
) -> impl Fn((ItemStateProxy, TR), InventoryItem) ) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Clone
-> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>> + Clone
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, transaction), mut inventory_item| { move |(mut item_state, transaction), mut inventory_item| {
Box::pin(async move { Box::pin(async move {
@ -903,14 +903,14 @@ where
} }
pub(super) fn convert_item_drop_to_floor_item<EG, TR>(
pub(super) fn convert_item_drop_to_floor_item<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
item_drop: ItemDrop, item_drop: ItemDrop,
) -> impl Fn((ItemStateProxy, TR), ()) ) -> impl Fn((ItemStateProxy, TR), ())
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone
-> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), _| { move |(mut item_state, mut transaction), _| {
let item_drop = item_drop.clone(); let item_drop = item_drop.clone();
@ -1005,13 +1005,13 @@ where
} }
} }
pub(super) fn add_item_to_local_floor<EG, TR>(
pub(super) fn add_item_to_local_floor<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
) -> impl Fn((ItemStateProxy, TR), FloorItem) ) -> impl Fn((ItemStateProxy, TR), FloorItem)
-> BoxFuture<Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, transaction) , floor_item| { move |(mut item_state, transaction) , floor_item| {
Box::pin(async move { Box::pin(async move {
@ -1024,13 +1024,13 @@ where
} }
} }
pub(super) fn apply_modifier_to_inventory_item<EG, TR>(
pub(super) fn apply_modifier_to_inventory_item<'a, EG, TR>(
modifier: ItemModifier, modifier: ItemModifier,
) -> impl Fn((ItemStateProxy, TR), InventoryItem) ) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), InventoryItem), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(item_state, mut transaction), mut inventory_item| { move |(item_state, mut transaction), mut inventory_item| {
let modifier = modifier.clone(); let modifier = modifier.clone();
@ -1048,12 +1048,12 @@ where
} }
} }
pub(super) fn as_individual_item<EG, TR>(
pub(super) fn as_individual_item<'a, EG, TR>(
) -> impl Fn((ItemStateProxy, TR), InventoryItem) ) -> impl Fn((ItemStateProxy, TR), InventoryItem)
-> BoxFuture<Result<((ItemStateProxy, TR), IndividualItemDetail), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), IndividualItemDetail), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(item_state, transaction), inventory_item| { move |(item_state, transaction), inventory_item| {
Box::pin(async move { Box::pin(async move {
@ -1068,14 +1068,14 @@ where
} }
pub(super) fn apply_item_action_packets<EG, TR>(
pub(super) fn apply_item_action_packets<'a, EG, TR>(
character_id: CharacterEntityId, character_id: CharacterEntityId,
area_client: AreaClient, area_client: AreaClient,
) -> impl Fn((ItemStateProxy, TR), ApplyItemAction) ) -> impl Fn((ItemStateProxy, TR), ApplyItemAction)
-> BoxFuture<Result<((ItemStateProxy, TR), Vec<SendShipPacket>), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), Vec<SendShipPacket>), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
move |(mut item_state, mut transaction), apply_item_action| { move |(mut item_state, mut transaction), apply_item_action| {
Box::pin(async move { Box::pin(async move {
@ -1126,13 +1126,13 @@ where
} }
} }
pub(super) fn apply_item_action_character<EG, TR>(
pub(super) fn apply_item_action_character<'a, EG, TR>(
character: &CharacterEntity character: &CharacterEntity
) -> impl Fn((ItemStateProxy, TR), Vec<ApplyItemAction>) ) -> impl Fn((ItemStateProxy, TR), Vec<ApplyItemAction>)
-> BoxFuture<Result<((ItemStateProxy, TR), CharacterEntity), anyhow::Error>>
-> BoxFuture<'a, Result<((ItemStateProxy, TR), CharacterEntity), anyhow::Error>>
where where
EG: EntityGateway, EG: EntityGateway,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'static,
TR: EntityGatewayTransaction<ParentGateway = EG> + 'a,
{ {
let character = character.clone(); let character = character.clone();
move |(item_state, transaction), apply_item_actions| { move |(item_state, transaction), apply_item_actions| {

8
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 item: InventoryItemDetail
) -> Result<Vec<ApplyItemAction>, anyhow::Error> ) -> Result<Vec<ApplyItemAction>, anyhow::Error>
where where
EG: EntityGateway + ?Sized + Clone + 'static
EG: EntityGateway + ?Sized + Clone + 'a
{ {
match item { match item {
InventoryItemDetail::Individual(individual_item) => { InventoryItemDetail::Individual(individual_item) => {

33
src/ship/items/itemstateaction.rs

@ -34,38 +34,40 @@ where
S: Send + Sync, S: Send + Sync,
E: Send + Sync, E: Send + Sync,
{ {
pub fn act<O, F, Fut>(self, f: F) -> ItemActionStage<O, ItemStateAction<T, S, E>, F, Fut, S, E>
pub fn act<'a, O, F, Fut>(self, f: F) -> ItemActionStage<'a, O, ItemStateAction<T, S, E>, F, Fut, S, E>
where where
F: Fn(S, ()) -> Fut + Send + Sync,
Fut: Future<Output=Result<(S, O), E>> + Send
F: Fn(S, ()) -> Fut + Send + Sync + 'a,
Fut: Future<Output=Result<(S, O), E>> + Send + 'a
{ {
ItemActionStage { ItemActionStage {
_s: Default::default(), _s: Default::default(),
_e: std::marker::PhantomData, _e: std::marker::PhantomData,
_a: Default::default(),
prev: self, prev: self,
actionf: f, actionf: f,
} }
} }
} }
pub struct ItemActionStage<O, P, F, Fut, S, E>
pub struct ItemActionStage<'a, O, P, F, Fut, S, E>
where where
P: ItemAction, P: ItemAction,
F: Fn(S, P::Output) -> Fut + Send + Sync,
Fut: Future<Output=Result<(S, O) , E>> + Send,
F: Fn(S, P::Output) -> Fut + Send + Sync + 'a,
Fut: Future<Output=Result<(S, O) , E>> + Send + 'a,
{ {
_s: std::marker::PhantomData<S>, _s: std::marker::PhantomData<S>,
_e: std::marker::PhantomData<E>, _e: std::marker::PhantomData<E>,
_a: std::marker::PhantomData<&'a ()>,
prev: P, prev: P,
actionf: F, actionf: F,
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl<O, P: ItemAction, F, Fut, S, E> ItemAction for ItemActionStage<O, P, F, Fut, S, E>
impl<'a, O, P: ItemAction, F, Fut, S, E> ItemAction for ItemActionStage<'a, O, P, F, Fut, S, E>
where where
P: ItemAction + ItemAction<Start = S, Error = E> + Send + Sync, P: ItemAction + ItemAction<Start = S, Error = E> + Send + Sync,
F: Fn(S, P::Output) -> Fut + Send + Sync,
Fut: Future<Output=Result<(S, O), E>> + Send,
F: Fn(S, P::Output) -> Fut + Send + Sync + 'a,
Fut: Future<Output=Result<(S, O), E>> + Send + 'a,
S: Send + Sync, S: Send + Sync,
P::Output: Send + Sync, P::Output: Send + Sync,
E: Send + Sync, E: Send + Sync,
@ -87,11 +89,11 @@ where
} }
} }
impl<O, P: ItemAction, F, Fut, S, E> ItemActionStage<O, P, F, Fut, S, E>
impl<'a, O, P: ItemAction, F, Fut, S, E> ItemActionStage<'a, O, P, F, Fut, S, E>
where where
P: ItemAction<Start = S, Error = E> + Send + Sync, P: ItemAction<Start = S, Error = E> + Send + Sync,
F: Fn(S, P::Output) -> Fut + Send + Sync,
Fut: Future<Output=Result<(S, O), E>> + Send,
F: Fn(S, P::Output) -> Fut + Send + Sync + 'a,
Fut: Future<Output=Result<(S, O), E>> + Send + 'a,
S: Send + Sync, S: Send + Sync,
P::Output: Send + Sync, P::Output: Send + Sync,
E: Send + Sync, E: Send + Sync,
@ -99,16 +101,17 @@ where
P::Error: Send + Sync, P::Error: Send + Sync,
{ {
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub fn act<O2, G, GFut>(self, g: G) -> ItemActionStage<O2, ItemActionStage<O, P, F, Fut, S, E>, 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 where
S: Send + Sync, S: Send + Sync,
G: Fn(S, <ItemActionStage<O, P, F, Fut, S, E> as ItemAction>::Output) -> GFut + Send + Sync,
GFut: Future<Output=Result<(S, O2), E>> + Send,
G: Fn(S, <ItemActionStage<'a, O, P, F, Fut, S, E> as ItemAction>::Output) -> GFut + Send + Sync + 'b,
GFut: Future<Output=Result<(S, O2), E>> + Send + 'b,
O2: Send + Sync, O2: Send + Sync,
{ {
ItemActionStage { ItemActionStage {
_s: Default::default(), _s: Default::default(),
_e: Default::default(), _e: Default::default(),
_a: Default::default(),
prev: self, prev: self,
actionf: g, actionf: g,
} }

270
src/ship/items/tasks.rs

@ -1,3 +1,4 @@
use futures::future::BoxFuture;
use crate::ship::items::ClientItemId; use crate::ship::items::ClientItemId;
use crate::entity::item::Meseta; use crate::entity::item::Meseta;
@ -17,17 +18,17 @@ use crate::ship::drops::ItemDrop;
use crate::ship::items::actions; use crate::ship::items::actions;
pub async fn pick_up_item<EG>(
item_state: &mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId)
-> Result<actions::TriggerCreateItem, anyhow::Error>
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<actions::TriggerCreateItem, anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_floor(character.id, *item_id)) .act(actions::take_item_from_floor(character.id, *item_id))
@ -36,21 +37,22 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn drop_item<EG>(
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, map_area: MapArea,
drop_position: (f32, f32, f32))
-> Result<FloorItem, anyhow::Error>
drop_position: (f32, f32, f32),
)-> BoxFuture<'a, Result<FloorItem, anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, *item_id, 0)) .act(actions::take_item_from_inventory(character.id, *item_id, 0))
@ -59,22 +61,22 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn drop_partial_item<'a, EG>(
pub fn drop_partial_item<'a, EG>(
item_state: &'a mut ItemState, 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, map_area: MapArea,
drop_position: (f32, f32), drop_position: (f32, f32),
amount: u32)
-> Result<FloorItem, anyhow::Error>
amount: u32
) -> BoxFuture<'a, Result<FloorItem, anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, *item_id, amount)) .act(actions::take_item_from_inventory(character.id, *item_id, amount))
@ -83,23 +85,23 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn drop_meseta<'a, EG>(
pub fn drop_meseta<'a, EG>(
item_state: &'a mut ItemState, item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
entity_gateway: &'a mut EG,
character: &'a CharacterEntity,
map_area: MapArea, map_area: MapArea,
drop_position: (f32, f32), drop_position: (f32, f32),
amount: u32)
-> Result<FloorItem, anyhow::Error>
amount: u32,
) -> BoxFuture<'a, Result<FloorItem, anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_meseta_from_inventory(character.id, amount)) .act(actions::take_meseta_from_inventory(character.id, amount))
@ -108,20 +110,20 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn withdraw_meseta<'a, EG>(
pub fn withdraw_meseta<'a, EG>(
item_state: &'a mut ItemState, 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 where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_meseta_from_bank(character.id, amount)) .act(actions::take_meseta_from_bank(character.id, amount))
@ -130,20 +132,20 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn deposit_meseta<'a, EG>(
pub fn deposit_meseta<'a, EG>(
item_state: &'a mut ItemState, 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 where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), _) = ItemStateAction::default() let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(actions::take_meseta_from_inventory(character.id, amount)) .act(actions::take_meseta_from_inventory(character.id, amount))
@ -152,21 +154,21 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, ())) Ok((transaction, ()))
}).await
})
} }
pub async fn withdraw_item<'a, EG>(
pub fn withdraw_item<'a, EG>(
item_state: &'a mut ItemState, item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
amount: u32)
-> Result<InventoryItem, anyhow::Error>
entity_gateway: &'a mut EG,
character: &'a CharacterEntity,
item_id: &'a ClientItemId,
amount: u32,
) -> BoxFuture<'a, Result<InventoryItem, anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_bank(character.id, *item_id, amount)) .act(actions::take_item_from_bank(character.id, *item_id, amount))
@ -177,21 +179,21 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn deposit_item<'a, EG> (
pub fn deposit_item<'a, EG> (
item_state: &'a mut ItemState, 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 where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, *item_id, amount)) .act(actions::take_item_from_inventory(character.id, *item_id, amount))
@ -200,20 +202,20 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn equip_item<'a, EG> (
pub fn equip_item<'a, EG> (
item_state: &'a mut ItemState, 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, equip_slot: u8,
) -> Result<(), anyhow::Error>
) -> BoxFuture<'a, Result<(), anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::equip_inventory_item(character.id, *item_id, equip_slot)) .act(actions::equip_inventory_item(character.id, *item_id, equip_slot))
@ -221,20 +223,20 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn unequip_item<'a, EG> (
pub fn unequip_item<'a, EG> (
item_state: &'a mut ItemState, 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 where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::unequip_inventory_item(character.id, *item_id)) .act(actions::unequip_inventory_item(character.id, *item_id))
@ -242,20 +244,20 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn sort_inventory<'a, EG> (
pub fn sort_inventory<'a, EG> (
item_state: &'a mut ItemState, item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
entity_gateway: &'a mut EG,
character: &'a CharacterEntity,
item_ids: Vec<ClientItemId>, item_ids: Vec<ClientItemId>,
) -> Result<(), anyhow::Error>
) -> BoxFuture<'a, Result<(), anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::sort_inventory_items(character.id, item_ids)) .act(actions::sort_inventory_items(character.id, item_ids))
@ -263,22 +265,22 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn use_item<'a, EG> (
pub fn use_item<'a, EG> (
item_state: &'a mut ItemState, item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &mut CharacterEntity,
entity_gateway: &'a mut EG,
character: &'a mut CharacterEntity,
area_client: AreaClient, area_client: AreaClient,
item_id: &ClientItemId,
item_id: &'a ClientItemId,
amount: u32, amount: u32,
) -> Result<Vec<SendShipPacket>, anyhow::Error>
) -> BoxFuture<'a, Result<Vec<SendShipPacket>, anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), (pkts, new_character)) = ItemStateAction::default() let ((item_state_proxy, transaction), (pkts, new_character)) = ItemStateAction::default()
.act(actions::remove_item_from_inventory(character.id, *item_id, amount)) .act(actions::remove_item_from_inventory(character.id, *item_id, amount))
@ -293,21 +295,21 @@ where
*character = new_character; *character = new_character;
Ok((transaction, pkts.into_iter().flatten().collect())) 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, 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 where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), _) = ItemStateAction::default() let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, *tool_item_id, 1)) .act(actions::take_item_from_inventory(character.id, *tool_item_id, 1))
@ -316,23 +318,23 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, ())) Ok((transaction, ()))
}).await
})
} }
pub async fn buy_shop_item<'a, EG> (
pub fn buy_shop_item<'a, EG> (
item_state: &'a mut ItemState, 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), shop_item: &'a (dyn ShopItem + Send + Sync),
item_id: ClientItemId, item_id: ClientItemId,
amount: u32, amount: u32,
) -> Result<InventoryItem, anyhow::Error>
) -> BoxFuture<'a, Result<InventoryItem, anyhow::Error>>
where where
EG: EntityGateway + 'static, EG: EntityGateway + 'static,
{ {
let item_price = shop_item.price() as u32 * amount; 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_meseta_from_inventory(character.id, item_price)) .act(actions::take_meseta_from_inventory(character.id, item_price))
@ -343,21 +345,21 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn sell_item<'a, EG> (
pub fn sell_item<'a, EG> (
item_state: &'a mut ItemState, item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
entity_gateway: &'a mut EG,
character: &'a CharacterEntity,
item_id: ClientItemId, item_id: ClientItemId,
amount: u32, amount: u32,
) -> Result<InventoryItem, anyhow::Error>
) -> BoxFuture<'a, Result<InventoryItem, anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), result) = ItemStateAction::default() let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, item_id, amount)) .act(actions::take_item_from_inventory(character.id, item_id, amount))
@ -366,14 +368,14 @@ where
.await?; .await?;
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, result)) Ok((transaction, result))
}).await
})
} }
pub async fn trade_items<'a, EG> (
pub fn trade_items<'a, EG> (
item_state: &'a mut ItemState, item_state: &'a mut ItemState,
entity_gateway: &mut EG,
p1: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, Meseta),
p2: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, Meseta))
-> Result<(Vec<InventoryItem>, Vec<InventoryItem>), anyhow::Error>
entity_gateway: &'a mut EG,
p1: (&'a AreaClient, &'a CharacterEntity, &'a Vec<TradeItem>, Meseta),
p2: (&'a AreaClient, &'a CharacterEntity, &'a Vec<TradeItem>, Meseta))
-> BoxFuture<'a, Result<(Vec<InventoryItem>, Vec<InventoryItem>), anyhow::Error>>
where where
EG: EntityGateway + 'static, EG: EntityGateway + 'static,
{ {
@ -395,7 +397,7 @@ where
} }
}) })
.collect(); .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 p1_id = p1.1.id;
let p2_id = p2.1.id; let p2_id = p2.1.id;
let trade = transaction.gateway().create_trade(&p1_id, &p2_id).await?; let trade = transaction.gateway().create_trade(&p1_id, &p2_id).await?;
@ -434,20 +436,20 @@ where
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, (p1_new_items, p2_new_items))) 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, item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character_id: &CharacterEntityId,
entity_gateway: &'a mut EG,
character_id: &'a CharacterEntityId,
meseta: Meseta) meseta: Meseta)
-> Result<(), anyhow::Error>
-> BoxFuture<'a, Result<(), anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), _) = ItemStateAction::default() let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(actions::take_meseta_from_inventory(*character_id, meseta.0)) .act(actions::take_meseta_from_inventory(*character_id, meseta.0))
@ -456,19 +458,19 @@ where
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, ())) Ok((transaction, ()))
}).await
})
} }
pub async fn enemy_drops_item<'a, EG> (
pub fn enemy_drops_item<'a, EG> (
item_state: &'a mut ItemState, item_state: &'a mut ItemState,
entity_gateway: &mut EG,
entity_gateway: &'a mut EG,
character_id: CharacterEntityId, character_id: CharacterEntityId,
item_drop: ItemDrop) item_drop: ItemDrop)
-> Result<FloorItem, anyhow::Error>
-> BoxFuture<'a, Result<FloorItem, anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default() let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default()
.act(actions::convert_item_drop_to_floor_item(character_id, item_drop)) .act(actions::convert_item_drop_to_floor_item(character_id, item_drop))
@ -478,21 +480,21 @@ where
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, floor_item)) Ok((transaction, floor_item))
}).await
})
} }
pub async fn apply_modifier<'a, EG> (
pub fn apply_modifier<'a, EG> (
item_state: &'a mut ItemState, item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
entity_gateway: &'a mut EG,
character: &'a CharacterEntity,
item_id: ClientItemId, item_id: ClientItemId,
modifier: ItemModifier) modifier: ItemModifier)
-> Result<IndividualItemDetail, anyhow::Error>
-> BoxFuture<'a, Result<IndividualItemDetail, anyhow::Error>>
where where
EG: EntityGateway + 'static, 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 = ItemStateProxy::new(item_state.clone());
let ((item_state_proxy, transaction), item) = ItemStateAction::default() let ((item_state_proxy, transaction), item) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, item_id, 1)) .act(actions::take_item_from_inventory(character.id, item_id, 1))
@ -504,5 +506,5 @@ where
item_state_proxy.commit().await; item_state_proxy.commit().await;
Ok((transaction, item)) Ok((transaction, item))
}).await
})
} }
Loading…
Cancel
Save