use bevy_ecs::prelude::{Entity, World};
use tokio::sync::mpsc::UnboundedSender as TokioSender;
use std::sync::Arc;
use crate::{emit_disposal, ChannelItem, Disposal, OperationRoster};
#[derive(Clone)]
pub(crate) struct BufferAccessLifecycle {
scope: Entity,
accessor: Entity,
session: Entity,
buffer: Entity,
sender: TokioSender<ChannelItem>,
pub(crate) tracker: Arc<()>,
}
impl BufferAccessLifecycle {
pub(crate) fn new(
scope: Entity,
buffer: Entity,
session: Entity,
accessor: Entity,
sender: TokioSender<ChannelItem>,
tracker: Arc<()>,
) -> Self {
Self {
scope,
accessor,
session,
buffer,
sender,
tracker,
}
}
pub(crate) fn is_in_use(&self) -> bool {
Arc::strong_count(&self.tracker) > 1
}
}
impl Drop for BufferAccessLifecycle {
fn drop(&mut self) {
if self.is_in_use() {
let scope = self.scope;
let accessor = self.accessor;
let session = self.session;
let buffer = self.buffer;
if let Err(err) = self.sender.send(Box::new(
move |world: &mut World, roster: &mut OperationRoster| {
let disposal = Disposal::buffer_key(accessor, buffer);
emit_disposal(accessor, session, disposal, world, roster);
},
)) {
eprintln!(
"Failed to send disposal notice for dropped buffer key in \
scope [{:?}] for session [{:?}]: {}",
scope, session, err,
);
}
}
}
}