Implement native inventory manager workflows (#62)
This commit is contained in:
@@ -359,9 +359,10 @@ async fn run_seed_requests(weak: Weak<CapsInner>, cancellation: CancellationToke
|
||||
let Some(simulator) = inner.simulator() else {
|
||||
return;
|
||||
};
|
||||
if !simulator.native_is_connected() {
|
||||
return;
|
||||
}
|
||||
// Seed discovery is HTTP-only. It is valid for composed/fake clients
|
||||
// to install a simulator and query capabilities before a UDP circuit
|
||||
// is started, and tying this request to UDP connectivity creates an
|
||||
// unnecessary race for every capability-backed manager.
|
||||
let http = simulator.client.native_http_caps_client();
|
||||
let response = http
|
||||
.post_with_uri_osd_format_osd_cancellation_token_i_progress(
|
||||
|
||||
@@ -118,6 +118,7 @@ struct ClientRuntime {
|
||||
caps_rate_limiter: Mutex<crate::caps_http::CapsRateLimiter>,
|
||||
network_manager: Mutex<std::sync::Weak<crate::network_manager::NetworkManagerInner>>,
|
||||
agent_manager: Mutex<std::sync::Weak<crate::agent_manager::AgentManagerInner>>,
|
||||
inventory_manager: Mutex<Option<Arc<crate::inventory_manager::InventoryManagerInner>>>,
|
||||
shutdown_complete: Condvar,
|
||||
shutdown_wait: Mutex<()>,
|
||||
}
|
||||
@@ -146,6 +147,7 @@ impl ClientRuntime {
|
||||
caps_rate_limiter: Mutex::new(caps_rate_limiter),
|
||||
network_manager: Mutex::new(std::sync::Weak::new()),
|
||||
agent_manager: Mutex::new(std::sync::Weak::new()),
|
||||
inventory_manager: Mutex::new(None),
|
||||
shutdown_complete: Condvar::new(),
|
||||
shutdown_wait: Mutex::new(()),
|
||||
}
|
||||
@@ -218,6 +220,10 @@ impl ClientRuntime {
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
||||
.take();
|
||||
self.inventory_manager
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
||||
.take();
|
||||
self.http_caps_client
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
||||
@@ -239,6 +245,30 @@ impl ClientRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
/// A non-owning route back to a live client runtime.
|
||||
///
|
||||
/// Manager caches can hold this handle without creating an `Arc` cycle. The
|
||||
/// settings and time provider are immutable client composition data and are
|
||||
/// cloned only when a manager needs to perform an operation.
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ClientWeakHandle {
|
||||
runtime: std::sync::Weak<ClientRuntime>,
|
||||
settings: Settings,
|
||||
time_provider: TimeProvider,
|
||||
}
|
||||
|
||||
impl ClientWeakHandle {
|
||||
pub(crate) fn upgrade(&self) -> Option<GridClient> {
|
||||
Some(GridClient {
|
||||
settings: self.settings.clone(),
|
||||
time_provider: self.time_provider.clone(),
|
||||
runtime: self.runtime.upgrade()?,
|
||||
network_manager: None,
|
||||
agent_manager: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Native owner for the mapped C# `GridClient` lifecycle slice.
|
||||
///
|
||||
/// Construction is side-effect free: it creates no runtime, task, socket, or
|
||||
@@ -386,6 +416,40 @@ impl GridClient {
|
||||
Ok(manager)
|
||||
}
|
||||
|
||||
pub(crate) fn native_weak_handle(&self) -> ClientWeakHandle {
|
||||
ClientWeakHandle {
|
||||
runtime: Arc::downgrade(&self.runtime),
|
||||
settings: self.settings.clone(),
|
||||
time_provider: self.time_provider.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn native_inventory(&self) -> Result<crate::InventoryManager, crate::Error> {
|
||||
let mut cached = self
|
||||
.runtime
|
||||
.inventory_manager
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||
if let Some(inner) = cached.as_ref() {
|
||||
return Ok(
|
||||
crate::inventory_manager::InventoryManager::native_from_inner(Arc::clone(inner)),
|
||||
);
|
||||
}
|
||||
let manager =
|
||||
crate::inventory_manager::InventoryManager::native_new(Some(Arc::new(self.clone())))?;
|
||||
*cached = Some(manager.native_inner());
|
||||
Ok(manager)
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_pass_by_value)] // The mapped C# property setter owns its value.
|
||||
pub(crate) fn native_set_inventory(&mut self, value: crate::InventoryManager) {
|
||||
*self
|
||||
.runtime
|
||||
.inventory_manager
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner) = Some(value.native_inner());
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_pass_by_value)] // The mapped C# property setter owns its value.
|
||||
pub(crate) fn native_set_network(&mut self, value: crate::NetworkManager) {
|
||||
*self
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1462,6 +1462,16 @@ impl Inventory {
|
||||
.and_then(|value| value.clone_as::<T>()))
|
||||
}
|
||||
|
||||
/// Returns the shared item portion regardless of the concrete inventory
|
||||
/// subclass stored for the UUID.
|
||||
pub(crate) fn native_item_value(&self, uuid: UUID) -> Option<InventoryItem> {
|
||||
read(&self.inner.state)
|
||||
.items
|
||||
.get(&uuid)
|
||||
.and_then(InventoryNode::value)
|
||||
.and_then(|value| value.item().cloned())
|
||||
}
|
||||
|
||||
pub fn try_get_value_with_uuid_inventory_base(
|
||||
&self,
|
||||
uuid: UUID,
|
||||
|
||||
4779
crates/libremetaverse/src/inventory_manager.rs
Normal file
4779
crates/libremetaverse/src/inventory_manager.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,7 @@ mod download_manager;
|
||||
mod event_queue;
|
||||
mod gesture;
|
||||
mod inventory;
|
||||
mod inventory_manager;
|
||||
#[rustfmt::skip] // Deterministic machine output is formatted by the pinned generator.
|
||||
mod foliage_catalog;
|
||||
mod generated;
|
||||
|
||||
@@ -1216,6 +1216,10 @@ impl Simulator {
|
||||
.map(|inner| Caps::native_from_inner(inner, self.native_clone_without_caps()))
|
||||
}
|
||||
|
||||
pub(crate) fn native_id(&self) -> UUID {
|
||||
self.data.id
|
||||
}
|
||||
|
||||
pub(crate) fn native_from_weak(data: &Weak<SimulatorData>) -> Option<Self> {
|
||||
data.upgrade().map(|data| Self { caps: None, data })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user