Implement native asset pipeline and cache (#64)
Some checks failed
Native code generation / deterministic (push) Failing after 2m18s
Imaging and meshing gate / native (push) Failing after 1m30s
JPEG 2000 feature / linux (push) Successful in 2m40s
Native Rust workspace compile / compile (push) Failing after 57s
Skia feature / linux (push) Successful in 31m8s
Some checks failed
Native code generation / deterministic (push) Failing after 2m18s
Imaging and meshing gate / native (push) Failing after 1m30s
JPEG 2000 feature / linux (push) Successful in 2m40s
Native Rust workspace compile / compile (push) Failing after 57s
Skia feature / linux (push) Successful in 31m8s
This commit is contained in:
226
crates/libremetaverse/src/transfers.rs
Normal file
226
crates/libremetaverse/src/transfers.rs
Normal file
@@ -0,0 +1,226 @@
|
||||
//! Asset transfer state shared by HTTP and LLUDP pipelines.
|
||||
|
||||
#![allow(clippy::missing_errors_doc, clippy::must_use_candidate)]
|
||||
|
||||
use crate::{
|
||||
ChannelType, Error, ImageCodec, ImageType, Simulator, SourceType, StatusCode, TargetType,
|
||||
TransferError,
|
||||
};
|
||||
use libremetaverse_types::compat::SortedList;
|
||||
use libremetaverse_types::{AssetType, UUID};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::RwLock;
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Transfer {
|
||||
pub asset_data: Vec<u8>,
|
||||
pub asset_type: AssetType,
|
||||
pub id: UUID,
|
||||
pub size: i32,
|
||||
pub success: bool,
|
||||
pub transferred: i32,
|
||||
pub(crate) last_packet: Instant,
|
||||
}
|
||||
impl Transfer {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
asset_data: Vec::new(),
|
||||
asset_type: AssetType::Unknown,
|
||||
id: UUID::zero(),
|
||||
size: 0,
|
||||
success: false,
|
||||
transferred: 0,
|
||||
last_packet: Instant::now(),
|
||||
})
|
||||
}
|
||||
pub fn time_since_last_packet(&self) -> i32 {
|
||||
i32::try_from(self.last_packet.elapsed().as_millis()).unwrap_or(i32::MAX)
|
||||
}
|
||||
pub fn set_time_since_last_packet(&mut self, value: i32) {
|
||||
self.last_packet = Instant::now()
|
||||
.checked_sub(std::time::Duration::from_millis(
|
||||
u64::try_from(value.max(0)).unwrap_or(0),
|
||||
))
|
||||
.unwrap_or_else(Instant::now);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssetDownload {
|
||||
pub asset_id: UUID,
|
||||
pub channel: ChannelType,
|
||||
pub priority: f32,
|
||||
pub simulator: Option<Simulator>,
|
||||
pub source: SourceType,
|
||||
pub status: StatusCode,
|
||||
pub target: TargetType,
|
||||
pub next_packet: i32,
|
||||
pub out_of_order_packets: RwLock<HashMap<i32, Vec<u8>>>,
|
||||
pub base: Transfer,
|
||||
}
|
||||
impl AssetDownload {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
asset_id: UUID::zero(),
|
||||
channel: ChannelType::Asset,
|
||||
priority: 0.0,
|
||||
simulator: None,
|
||||
source: SourceType::Asset,
|
||||
status: StatusCode::Unknown,
|
||||
target: TargetType::Unknown,
|
||||
next_packet: 0,
|
||||
out_of_order_packets: RwLock::new(HashMap::new()),
|
||||
base: Transfer::new()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ImageDownload {
|
||||
pub codec: ImageCodec,
|
||||
pub discard_level: i32,
|
||||
pub image_type: ImageType,
|
||||
pub packet_count: u16,
|
||||
pub packets_seen: SortedList<u16, u16>,
|
||||
pub priority: f32,
|
||||
pub simulator: Option<Simulator>,
|
||||
pub base: Transfer,
|
||||
}
|
||||
|
||||
impl ImageDownload {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
codec: ImageCodec::Invalid,
|
||||
discard_level: 0,
|
||||
image_type: ImageType::Normal,
|
||||
packet_count: 0,
|
||||
packets_seen: SortedList(std::collections::BTreeMap::new()),
|
||||
priority: 0.0,
|
||||
simulator: None,
|
||||
base: Transfer::new()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AssetUpload {
|
||||
pub asset_id: UUID,
|
||||
pub packet_num: u32,
|
||||
pub type_: AssetType,
|
||||
pub xfer_id: u64,
|
||||
pub base: Transfer,
|
||||
}
|
||||
impl AssetUpload {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
asset_id: UUID::zero(),
|
||||
packet_num: 0,
|
||||
type_: AssetType::Unknown,
|
||||
xfer_id: 0,
|
||||
base: Transfer::new()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AssetUploadEventArgs {
|
||||
upload: AssetUpload,
|
||||
}
|
||||
impl AssetUploadEventArgs {
|
||||
pub fn new(upload: AssetUpload) -> Result<Self, Error> {
|
||||
Ok(Self { upload })
|
||||
}
|
||||
pub fn upload(&self) -> AssetUpload {
|
||||
self.upload.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ImageReceiveProgressEventArgs {
|
||||
image_id: UUID,
|
||||
received: i32,
|
||||
total: i32,
|
||||
}
|
||||
|
||||
impl ImageReceiveProgressEventArgs {
|
||||
pub fn new(image_id: UUID, received: i32, total: i32) -> Result<Self, Error> {
|
||||
if received < 0 || total < 0 || received > total {
|
||||
return Err(Error::Argument);
|
||||
}
|
||||
Ok(Self {
|
||||
image_id,
|
||||
received,
|
||||
total,
|
||||
})
|
||||
}
|
||||
pub const fn image_id(&self) -> UUID {
|
||||
self.image_id
|
||||
}
|
||||
pub const fn received(&self) -> i32 {
|
||||
self.received
|
||||
}
|
||||
pub const fn total(&self) -> i32 {
|
||||
self.total
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct InitiateDownloadEventArgs {
|
||||
sim_filename: String,
|
||||
viewer_filename: String,
|
||||
}
|
||||
|
||||
impl InitiateDownloadEventArgs {
|
||||
pub fn new(sim_filename: String, viewer_filename: String) -> Result<Self, Error> {
|
||||
if sim_filename.as_bytes().contains(&0) || viewer_filename.as_bytes().contains(&0) {
|
||||
return Err(Error::Argument);
|
||||
}
|
||||
Ok(Self {
|
||||
sim_filename,
|
||||
viewer_filename,
|
||||
})
|
||||
}
|
||||
pub fn sim_file_name(&self) -> String {
|
||||
self.sim_filename.clone()
|
||||
}
|
||||
pub fn viewer_file_name(&self) -> String {
|
||||
self.viewer_filename.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct XferDownload {
|
||||
pub error: TransferError,
|
||||
pub filename: String,
|
||||
pub packet_num: u32,
|
||||
pub v_file_id: UUID,
|
||||
pub xfer_id: u64,
|
||||
pub base: Transfer,
|
||||
}
|
||||
|
||||
impl XferDownload {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
error: TransferError::None,
|
||||
filename: String::new(),
|
||||
packet_num: 0,
|
||||
v_file_id: UUID::zero(),
|
||||
xfer_id: 0,
|
||||
base: Transfer::new()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct XferReceivedEventArgs {
|
||||
xfer: XferDownload,
|
||||
}
|
||||
impl XferReceivedEventArgs {
|
||||
pub fn new(xfer: XferDownload) -> Result<Self, Error> {
|
||||
Ok(Self { xfer })
|
||||
}
|
||||
pub fn xfer(&self) -> XferDownload {
|
||||
self.xfer.clone()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user