use super::ActorBlueprint;
use crate::error::ffi::with_ffi_error;
use autocxx::prelude::*;
use carla_sys::carla_rust::client::{FfiBlueprintLibrary, copy_actor_blueprint};
use cxx::{SharedPtr, let_cxx_string};
use derivative::Derivative;
use static_assertions::assert_impl_all;
#[derive(Clone, Derivative)]
#[derivative(Debug)]
#[repr(transparent)]
pub struct BlueprintLibrary {
#[derivative(Debug = "ignore")]
inner: SharedPtr<FfiBlueprintLibrary>,
}
impl BlueprintLibrary {
pub(crate) fn from_cxx(ptr: SharedPtr<FfiBlueprintLibrary>) -> Option<Self> {
if ptr.is_null() {
None
} else {
Some(Self { inner: ptr })
}
}
pub fn filter(&self, pattern: &str) -> crate::Result<Self> {
let_cxx_string!(pattern = pattern);
let ptr = with_ffi_error("filter", |e| self.inner.filter(&pattern, e))?;
Ok(unsafe { Self::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg(any(carla_version_0915, carla_version_0916, carla_version_0100))]
pub fn filter_by_attribute(&self, name: &str, value: &str) -> crate::Result<Self> {
let_cxx_string!(name = name);
let_cxx_string!(value = value);
let ptr = with_ffi_error("filter_by_attribute", |e| {
self.inner.filter_by_attribute(&name, &value, e)
})?;
Ok(unsafe { Self::from_cxx(ptr).unwrap_unchecked() })
}
pub fn find(&self, key: &str) -> crate::Result<Option<ActorBlueprint>> {
let_cxx_string!(key = key);
let ptr = with_ffi_error("find", |e| self.inner.find(&key, e))?;
unsafe {
let Some(actor_bp) = ptr.as_ref() else {
return Ok(None);
};
let actor_bp = copy_actor_blueprint(actor_bp).within_unique_ptr();
Ok(Some(ActorBlueprint::from_cxx(actor_bp).unwrap_unchecked()))
}
}
pub fn get(&self, index: usize) -> crate::Result<Option<ActorBlueprint>> {
let ptr = with_ffi_error("at", |e| self.inner.at(index, e))?;
unsafe {
let Some(actor_bp) = ptr.as_ref() else {
return Ok(None);
};
let actor_bp = copy_actor_blueprint(actor_bp).within_unique_ptr();
Ok(Some(ActorBlueprint::from_cxx(actor_bp).unwrap_unchecked()))
}
}
pub fn iter(&self) -> impl Iterator<Item = ActorBlueprint> + '_ {
(0..self.len()).map(|idx| unsafe { self.get(idx).unwrap_unchecked().unwrap_unchecked() })
}
pub fn len(&self) -> usize {
self.inner.size()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
assert_impl_all!(BlueprintLibrary: Send, Sync);