1
0

feat: finish bmap-rs

This commit is contained in:
2026-03-01 20:40:15 +08:00
parent 4072285425
commit 49c9b00c11
2 changed files with 150 additions and 24 deletions

View File

@@ -205,9 +205,17 @@ macro_rules! libobj_struct {
}; };
} }
macro_rules! libobj_impl_new { macro_rules! libobj_impl_clone {
($name:ident) => { ($name:ident) => {
impl<'o, P> $name<'o, P> where P: AbstractPointer<'o> + ?Sized {} impl<'o, P> Clone for $name<'o, P> where P: AbstractPointer<'o> + ?Sized {
fn clone(&self) -> Self {
Self {
handle: self.handle,
id: self.id,
parent: PhantomData::<&'o P>,
}
}
}
}; };
} }
@@ -277,8 +285,8 @@ macro_rules! libobj_impl_abstract_object {
{ {
unsafe fn with_parent(_: &'o P, handle: PBMVOID, id: CKID) -> Self { unsafe fn with_parent(_: &'o P, handle: PBMVOID, id: CKID) -> Self {
Self { Self {
handle, handle: handle,
id, id: id,
parent: PhantomData::<&'o P>, parent: PhantomData::<&'o P>,
} }
} }
@@ -287,8 +295,8 @@ macro_rules! libobj_impl_abstract_object {
AO: AbstractObject<'o, P> + ?Sized, AO: AbstractObject<'o, P> + ?Sized,
{ {
Self { Self {
handle, handle: handle,
id, id: id,
parent: PhantomData::<&'o P>, parent: PhantomData::<&'o P>,
} }
} }
@@ -631,6 +639,104 @@ where
} }
} }
type FnGroupObjectGetter =
unsafe extern "C" fn(PBMVOID, CKID, param_in!(CKDWORD), param_out!(CKID)) -> BMBOOL;
pub struct GroupObjectIter<'o, P, O, T>
where
P: AbstractPointer<'o> + ?Sized,
O: AbstractObject<'o, P> + ?Sized,
T: AbstractObject<'o, P>,
{
f: FnGroupObjectGetter,
cnt: usize,
i: usize,
phantom_pointer: PhantomData<P>,
parent: &'o O,
phantom_target: PhantomData<T>,
}
impl<'o, P, O, T> GroupObjectIter<'o, P, O, T>
where
P: AbstractPointer<'o> + ?Sized,
O: AbstractObject<'o, P> + ?Sized,
T: AbstractObject<'o, P>,
{
fn new(parent: &'o O, f: FnGroupObjectGetter, cnt: usize) -> Self {
Self {
f: f,
cnt: cnt,
i: 0,
phantom_pointer: PhantomData,
parent: parent,
phantom_target: PhantomData,
}
}
}
impl<'o, P, O, T> Iterator for GroupObjectIter<'o, P, O, T>
where
P: AbstractPointer<'o> + ?Sized,
O: AbstractObject<'o, P> + ?Sized,
T: AbstractObject<'o, P>,
{
type Item = Result<T>;
fn next(&mut self) -> Option<Self::Item> {
if self.i >= self.cnt {
None
} else {
let mut ckid = MaybeUninit::<CKID>::uninit();
let i = match self.i.try_into() {
Ok(v) => v,
Err(e) => return Some(Err(Error::from(e))),
};
let rv = unsafe {
(self.f)(
self.parent.get_pointer(),
self.parent.get_ckid(),
arg_in!(i),
arg_out!(ckid.as_mut_ptr(), CKID),
)
};
if !rv {
return Some(Err(Error::BadCall));
}
let ckid = unsafe { ckid.assume_init() };
self.i += 1;
Some(Ok(unsafe {
T::with_sibling(self.parent, self.parent.get_pointer(), ckid)
}))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
libiter_size_hint_body!(self.i, self.cnt)
}
}
impl<'o, P, O, T> FusedIterator for GroupObjectIter<'o, P, O, T>
where
P: AbstractPointer<'o> + ?Sized,
O: AbstractObject<'o, P> + ?Sized,
T: AbstractObject<'o, P>,
{
}
impl<'o, P, O, T> ExactSizeIterator for GroupObjectIter<'o, P, O, T>
where
P: AbstractPointer<'o> + ?Sized,
O: AbstractObject<'o, P> + ?Sized,
T: AbstractObject<'o, P>,
{
fn len(&self) -> usize {
libiter_len_body!(self.i, self.cnt)
}
}
// endregion // endregion
// region: Utility Functions // region: Utility Functions
@@ -1215,6 +1321,25 @@ pub trait BMGroupDecl<'o, P>: BMObjectDecl<'o, P>
where where
P: AbstractPointer<'o> + ?Sized + 'o, P: AbstractPointer<'o> + ?Sized + 'o,
{ {
fn add_object(&mut self, member: Option<BM3dObject<'o, P>>) -> Result<()> {
let ckid: CKID = match member {
Some(member) => unsafe { member.get_ckid() },
None => INVALID_CKID,
};
set_copyable_value(self, bmap::BMGroup_AddObject, ckid)
}
fn get_object_count(&self) -> Result<u32> {
get_copyable_value(self, bmap::BMGroup_GetObjectCount)
}
fn get_objects(&'o self) -> Result<GroupObjectIter<'o, P, Self, BM3dObject<'o, P>>> {
Ok(GroupObjectIter::new(
self,
bmap::BMGroup_GetObject,
self.get_object_count()?.try_into()?,
))
}
} }
// endregion // endregion
@@ -1222,41 +1347,41 @@ where
// region: Structs // region: Structs
libobj_struct!(BMObject); libobj_struct!(BMObject);
libobj_impl_new!(BMObject); libobj_impl_clone!(BMObject);
libobj_impl_eq_ord_hash!(BMObject); libobj_impl_eq_ord_hash!(BMObject);
libobj_impl_abstract_object!(BMObject); libobj_impl_abstract_object!(BMObject);
libobj_impl_obj_trait!(BMObject, BMObjectDecl); libobj_impl_obj_trait!(BMObject, BMObjectDecl);
libobj_struct!(BMTexture); libobj_struct!(BMTexture);
libobj_impl_new!(BMTexture); libobj_impl_clone!(BMTexture);
libobj_impl_eq_ord_hash!(BMTexture); libobj_impl_eq_ord_hash!(BMTexture);
libobj_impl_abstract_object!(BMTexture); libobj_impl_abstract_object!(BMTexture);
libobj_impl_obj_trait!(BMTexture, BMObjectDecl); libobj_impl_obj_trait!(BMTexture, BMObjectDecl);
libobj_impl_obj_trait!(BMTexture, BMTextureDecl); libobj_impl_obj_trait!(BMTexture, BMTextureDecl);
libobj_struct!(BMMaterial); libobj_struct!(BMMaterial);
libobj_impl_new!(BMMaterial); libobj_impl_clone!(BMMaterial);
libobj_impl_eq_ord_hash!(BMMaterial); libobj_impl_eq_ord_hash!(BMMaterial);
libobj_impl_abstract_object!(BMMaterial); libobj_impl_abstract_object!(BMMaterial);
libobj_impl_obj_trait!(BMMaterial, BMObjectDecl); libobj_impl_obj_trait!(BMMaterial, BMObjectDecl);
libobj_impl_obj_trait!(BMMaterial, BMMaterialDecl); libobj_impl_obj_trait!(BMMaterial, BMMaterialDecl);
libobj_struct!(BMMesh); libobj_struct!(BMMesh);
libobj_impl_new!(BMMesh); libobj_impl_clone!(BMMesh);
libobj_impl_eq_ord_hash!(BMMesh); libobj_impl_eq_ord_hash!(BMMesh);
libobj_impl_abstract_object!(BMMesh); libobj_impl_abstract_object!(BMMesh);
libobj_impl_obj_trait!(BMMesh, BMObjectDecl); libobj_impl_obj_trait!(BMMesh, BMObjectDecl);
libobj_impl_obj_trait!(BMMesh, BMMeshDecl); libobj_impl_obj_trait!(BMMesh, BMMeshDecl);
libobj_struct!(BM3dEntity); libobj_struct!(BM3dEntity);
libobj_impl_new!(BM3dEntity); libobj_impl_clone!(BM3dEntity);
libobj_impl_eq_ord_hash!(BM3dEntity); libobj_impl_eq_ord_hash!(BM3dEntity);
libobj_impl_abstract_object!(BM3dEntity); libobj_impl_abstract_object!(BM3dEntity);
libobj_impl_obj_trait!(BM3dEntity, BMObjectDecl); libobj_impl_obj_trait!(BM3dEntity, BMObjectDecl);
libobj_impl_obj_trait!(BM3dEntity, BM3dEntityDecl); libobj_impl_obj_trait!(BM3dEntity, BM3dEntityDecl);
libobj_struct!(BM3dObject); libobj_struct!(BM3dObject);
libobj_impl_new!(BM3dObject); libobj_impl_clone!(BM3dObject);
libobj_impl_eq_ord_hash!(BM3dObject); libobj_impl_eq_ord_hash!(BM3dObject);
libobj_impl_abstract_object!(BM3dObject); libobj_impl_abstract_object!(BM3dObject);
libobj_impl_obj_trait!(BM3dObject, BMObjectDecl); libobj_impl_obj_trait!(BM3dObject, BMObjectDecl);
@@ -1264,7 +1389,7 @@ libobj_impl_obj_trait!(BM3dObject, BM3dEntityDecl);
libobj_impl_obj_trait!(BM3dObject, BM3dObjectDecl); libobj_impl_obj_trait!(BM3dObject, BM3dObjectDecl);
libobj_struct!(BMLight); libobj_struct!(BMLight);
libobj_impl_new!(BMLight); libobj_impl_clone!(BMLight);
libobj_impl_eq_ord_hash!(BMLight); libobj_impl_eq_ord_hash!(BMLight);
libobj_impl_abstract_object!(BMLight); libobj_impl_abstract_object!(BMLight);
libobj_impl_obj_trait!(BMLight, BMObjectDecl); libobj_impl_obj_trait!(BMLight, BMObjectDecl);
@@ -1272,7 +1397,7 @@ libobj_impl_obj_trait!(BMLight, BM3dEntityDecl);
libobj_impl_obj_trait!(BMLight, BMLightDecl); libobj_impl_obj_trait!(BMLight, BMLightDecl);
libobj_struct!(BMTargetLight); libobj_struct!(BMTargetLight);
libobj_impl_new!(BMTargetLight); libobj_impl_clone!(BMTargetLight);
libobj_impl_eq_ord_hash!(BMTargetLight); libobj_impl_eq_ord_hash!(BMTargetLight);
libobj_impl_abstract_object!(BMTargetLight); libobj_impl_abstract_object!(BMTargetLight);
libobj_impl_obj_trait!(BMTargetLight, BMObjectDecl); libobj_impl_obj_trait!(BMTargetLight, BMObjectDecl);
@@ -1281,7 +1406,7 @@ libobj_impl_obj_trait!(BMTargetLight, BMLightDecl);
libobj_impl_obj_trait!(BMTargetLight, BMTargetLightDecl); libobj_impl_obj_trait!(BMTargetLight, BMTargetLightDecl);
libobj_struct!(BMCamera); libobj_struct!(BMCamera);
libobj_impl_new!(BMCamera); libobj_impl_clone!(BMCamera);
libobj_impl_eq_ord_hash!(BMCamera); libobj_impl_eq_ord_hash!(BMCamera);
libobj_impl_abstract_object!(BMCamera); libobj_impl_abstract_object!(BMCamera);
libobj_impl_obj_trait!(BMCamera, BMObjectDecl); libobj_impl_obj_trait!(BMCamera, BMObjectDecl);
@@ -1289,7 +1414,7 @@ libobj_impl_obj_trait!(BMCamera, BM3dEntityDecl);
libobj_impl_obj_trait!(BMCamera, BMCameraDecl); libobj_impl_obj_trait!(BMCamera, BMCameraDecl);
libobj_struct!(BMTargetCamera); libobj_struct!(BMTargetCamera);
libobj_impl_new!(BMTargetCamera); libobj_impl_clone!(BMTargetCamera);
libobj_impl_eq_ord_hash!(BMTargetCamera); libobj_impl_eq_ord_hash!(BMTargetCamera);
libobj_impl_abstract_object!(BMTargetCamera); libobj_impl_abstract_object!(BMTargetCamera);
libobj_impl_obj_trait!(BMTargetCamera, BMObjectDecl); libobj_impl_obj_trait!(BMTargetCamera, BMObjectDecl);
@@ -1298,7 +1423,7 @@ libobj_impl_obj_trait!(BMTargetCamera, BMCameraDecl);
libobj_impl_obj_trait!(BMTargetCamera, BMTargetCameraDecl); libobj_impl_obj_trait!(BMTargetCamera, BMTargetCameraDecl);
libobj_struct!(BMGroup); libobj_struct!(BMGroup);
libobj_impl_new!(BMGroup); libobj_impl_clone!(BMGroup);
libobj_impl_eq_ord_hash!(BMGroup); libobj_impl_eq_ord_hash!(BMGroup);
libobj_impl_abstract_object!(BMGroup); libobj_impl_abstract_object!(BMGroup);
libobj_impl_obj_trait!(BMGroup, BMObjectDecl); libobj_impl_obj_trait!(BMGroup, BMObjectDecl);

View File

@@ -85,7 +85,7 @@ mod testsuits {
use super::bmap; use super::bmap;
use bmap::{ use bmap::{
BM3dEntityDecl, BMCameraDecl, BMLightDecl, BMMaterialDecl, BMMeshDecl, BMObjectDecl, BM3dEntityDecl, BMCameraDecl, BMLightDecl, BMMaterialDecl, BMMeshDecl, BMObjectDecl,
BMTextureDecl, BMTextureDecl, BMGroupDecl
}; };
pub fn test(reader: &bmap::BMFileReader) { pub fn test(reader: &bmap::BMFileReader) {
@@ -112,8 +112,9 @@ mod testsuits {
let gp = gp.unwrap(); let gp = gp.unwrap();
println!("{:?}", gp.get_name().unwrap()); println!("{:?}", gp.get_name().unwrap());
for gp_item in gp.get_objects() { for gp_item in gp.get_objects().unwrap() {
println!("\t{}", gp_item.get_name()); let gp_item = gp_item.unwrap();
println!("\t{:?}", gp_item.get_name().unwrap());
} }
} }
} }
@@ -273,14 +274,14 @@ We can not perform Eq test because the length of 3dObject is too short (must gre
// Test HashSet // Test HashSet
let mut test_hashset = HashSet::new(); let mut test_hashset = HashSet::new();
assert!(test_hashset.insert(first_3dobj.clone())); assert!(test_hashset.insert(first_3dobj));
assert!(!test_hashset.insert(first_3dobj_again.clone())); assert!(!test_hashset.insert(first_3dobj_again));
assert!(test_hashset.insert(second_3dobj)); assert!(test_hashset.insert(second_3dobj));
// Test BTreeSet // Test BTreeSet
let mut test_btreeset = BTreeSet::new(); let mut test_btreeset = BTreeSet::new();
assert!(test_btreeset.insert(first_3dobj.clone())); assert!(test_btreeset.insert(first_3dobj));
assert!(!test_btreeset.insert(first_3dobj_again.clone())); assert!(!test_btreeset.insert(first_3dobj_again));
assert!(test_btreeset.insert(second_3dobj)); assert!(test_btreeset.insert(second_3dobj));
} }
} }