use std::error::Error;
use crate::loader::LoaderEvent;
use crate::ArtifactTypeId;
use crossbeam_channel::Sender;
use hydrate_base::handle::LoaderInfoProvider;
use hydrate_base::{ArtifactId, LoadHandle, StringHash};
#[derive(Debug)]
pub enum HandleOp {
Error(LoadHandle, Box<dyn Error + Send>),
Complete(LoadHandle),
Drop(LoadHandle),
}
pub struct ArtifactLoadOp {
sender: Option<Sender<LoaderEvent>>,
handle: LoadHandle,
}
impl ArtifactLoadOp {
pub(crate) fn new(
sender: Sender<LoaderEvent>,
handle: LoadHandle,
) -> Self {
Self {
sender: Some(sender),
handle,
}
}
pub fn load_handle(&self) -> LoadHandle {
self.handle
}
pub fn complete(mut self) {
log::debug!("LoadOp for {:?} complete", self.handle);
let _ = self
.sender
.as_ref()
.unwrap()
.send(LoaderEvent::LoadResult(HandleOp::Complete(self.handle)));
self.sender = None;
}
pub fn error<E: Error + 'static + Send>(
mut self,
error: E,
) {
println!("LoadOp for {:?} error {:?}", self.handle, error);
let _ = self
.sender
.as_ref()
.unwrap()
.send(LoaderEvent::LoadResult(HandleOp::Error(
self.handle,
Box::new(error),
)));
self.sender = None;
}
}
impl Drop for ArtifactLoadOp {
fn drop(&mut self) {
if let Some(ref sender) = self.sender {
let _ = sender.send(LoaderEvent::LoadResult(HandleOp::Drop(self.handle)));
}
}
}
pub trait ArtifactStorage {
fn load_artifact(
&mut self,
loader_info: &dyn LoaderInfoProvider,
artifact_type_id: &ArtifactTypeId,
artifact_id: ArtifactId,
data: Vec<u8>,
load_handle: LoadHandle,
load_op: ArtifactLoadOp,
) -> Result<(), Box<dyn Error + Send + 'static>>;
fn commit_artifact(
&mut self,
artifact_type: ArtifactTypeId,
load_handle: LoadHandle,
);
fn free_artifact(
&mut self,
artifact_type_id: ArtifactTypeId,
load_handle: LoadHandle,
);
}
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub enum IndirectIdentifier {
ArtifactId(ArtifactId, ArtifactTypeId),
SymbolWithType(StringHash, ArtifactTypeId),
}