use crossbeam_channel::Sender;
use hydrate_base::LoadHandle;
use hydrate_loader::storage::ArtifactLoadOp;
use rafx_api::RafxError;
use rafx_framework::upload::UploadOp;
pub enum UploadAssetOpResult<ResourceT, AssetT> {
UploadError(LoadHandle),
UploadComplete(ArtifactLoadOp, Sender<AssetT>, ResourceT),
UploadDrop(LoadHandle),
}
pub struct UploadAssetOpInner<ResourceT, AssetT> {
load_op: ArtifactLoadOp,
load_handle: LoadHandle,
asset_sender: Sender<AssetT>, sender: Sender<UploadAssetOpResult<ResourceT, AssetT>>, }
pub struct UploadAssetOp<ResourceT, AssetT> {
inner: Option<UploadAssetOpInner<ResourceT, AssetT>>,
}
impl<ResourceT, AssetT> Drop for UploadAssetOp<ResourceT, AssetT> {
fn drop(&mut self) {
if let Some(inner) = self.inner.take() {
let sender = inner.sender;
let _ = sender.send(UploadAssetOpResult::UploadDrop(inner.load_handle));
}
}
}
impl<ResourceT, AssetT> UploadAssetOp<ResourceT, AssetT> {
pub fn new(
load_op: ArtifactLoadOp,
load_handle: LoadHandle,
asset_sender: Sender<AssetT>,
sender: Sender<UploadAssetOpResult<ResourceT, AssetT>>,
) -> Self {
let inner = UploadAssetOpInner {
load_op,
load_handle,
asset_sender,
sender,
};
UploadAssetOp { inner: Some(inner) }
}
pub fn complete(
mut self,
resource: ResourceT,
) {
self.do_complete(resource)
}
pub fn error(
mut self: Box<Self>,
error: RafxError,
) {
self.do_error(error)
}
fn do_complete(
&mut self,
resource: ResourceT,
) {
let inner = self.inner.take().unwrap();
let load_op = inner.load_op;
let asset_sender = inner.asset_sender;
let _ = inner.sender.send(UploadAssetOpResult::UploadComplete(
load_op,
asset_sender,
resource,
));
}
fn do_error(
&mut self,
error: RafxError,
) {
let inner = self.inner.take().unwrap();
inner.load_op.error(error);
let _ = inner
.sender
.send(UploadAssetOpResult::UploadError(inner.load_handle));
}
}
impl<ResourceT: Send + Sync, AssetT: Send + Sync> UploadOp<ResourceT>
for UploadAssetOp<ResourceT, AssetT>
{
fn complete(
mut self: Box<Self>,
resource: ResourceT,
) {
self.do_complete(resource)
}
fn error(
mut self: Box<Self>,
error: RafxError,
) {
self.do_error(error)
}
}