From 49c9b00c117834f203d7ac1de4c5edb4dee971d0 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sun, 1 Mar 2026 20:40:15 +0800 Subject: [PATCH] feat: finish bmap-rs --- .../BMapBindings/bmap-rs/src/bmap_wrapper.rs | 159 ++++++++++++++++-- Assets/BMapBindings/bmap-rs/tests/complete.rs | 15 +- 2 files changed, 150 insertions(+), 24 deletions(-) diff --git a/Assets/BMapBindings/bmap-rs/src/bmap_wrapper.rs b/Assets/BMapBindings/bmap-rs/src/bmap_wrapper.rs index 23806df..431aabf 100644 --- a/Assets/BMapBindings/bmap-rs/src/bmap_wrapper.rs +++ b/Assets/BMapBindings/bmap-rs/src/bmap_wrapper.rs @@ -205,9 +205,17 @@ macro_rules! libobj_struct { }; } -macro_rules! libobj_impl_new { +macro_rules! libobj_impl_clone { ($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 { Self { - handle, - id, + handle: handle, + id: id, parent: PhantomData::<&'o P>, } } @@ -287,8 +295,8 @@ macro_rules! libobj_impl_abstract_object { AO: AbstractObject<'o, P> + ?Sized, { Self { - handle, - id, + handle: handle, + id: id, 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

, + parent: &'o O, + phantom_target: PhantomData, +} + +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; + + fn next(&mut self) -> Option { + if self.i >= self.cnt { + None + } else { + let mut ckid = MaybeUninit::::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) { + 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 // region: Utility Functions @@ -1215,6 +1321,25 @@ pub trait BMGroupDecl<'o, P>: BMObjectDecl<'o, P> where P: AbstractPointer<'o> + ?Sized + 'o, { + fn add_object(&mut self, member: Option>) -> 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 { + get_copyable_value(self, bmap::BMGroup_GetObjectCount) + } + + fn get_objects(&'o self) -> Result>> { + Ok(GroupObjectIter::new( + self, + bmap::BMGroup_GetObject, + self.get_object_count()?.try_into()?, + )) + } } // endregion @@ -1222,41 +1347,41 @@ where // region: Structs libobj_struct!(BMObject); -libobj_impl_new!(BMObject); +libobj_impl_clone!(BMObject); libobj_impl_eq_ord_hash!(BMObject); libobj_impl_abstract_object!(BMObject); libobj_impl_obj_trait!(BMObject, BMObjectDecl); libobj_struct!(BMTexture); -libobj_impl_new!(BMTexture); +libobj_impl_clone!(BMTexture); libobj_impl_eq_ord_hash!(BMTexture); libobj_impl_abstract_object!(BMTexture); libobj_impl_obj_trait!(BMTexture, BMObjectDecl); libobj_impl_obj_trait!(BMTexture, BMTextureDecl); libobj_struct!(BMMaterial); -libobj_impl_new!(BMMaterial); +libobj_impl_clone!(BMMaterial); libobj_impl_eq_ord_hash!(BMMaterial); libobj_impl_abstract_object!(BMMaterial); libobj_impl_obj_trait!(BMMaterial, BMObjectDecl); libobj_impl_obj_trait!(BMMaterial, BMMaterialDecl); libobj_struct!(BMMesh); -libobj_impl_new!(BMMesh); +libobj_impl_clone!(BMMesh); libobj_impl_eq_ord_hash!(BMMesh); libobj_impl_abstract_object!(BMMesh); libobj_impl_obj_trait!(BMMesh, BMObjectDecl); libobj_impl_obj_trait!(BMMesh, BMMeshDecl); libobj_struct!(BM3dEntity); -libobj_impl_new!(BM3dEntity); +libobj_impl_clone!(BM3dEntity); libobj_impl_eq_ord_hash!(BM3dEntity); libobj_impl_abstract_object!(BM3dEntity); libobj_impl_obj_trait!(BM3dEntity, BMObjectDecl); libobj_impl_obj_trait!(BM3dEntity, BM3dEntityDecl); libobj_struct!(BM3dObject); -libobj_impl_new!(BM3dObject); +libobj_impl_clone!(BM3dObject); libobj_impl_eq_ord_hash!(BM3dObject); libobj_impl_abstract_object!(BM3dObject); libobj_impl_obj_trait!(BM3dObject, BMObjectDecl); @@ -1264,7 +1389,7 @@ libobj_impl_obj_trait!(BM3dObject, BM3dEntityDecl); libobj_impl_obj_trait!(BM3dObject, BM3dObjectDecl); libobj_struct!(BMLight); -libobj_impl_new!(BMLight); +libobj_impl_clone!(BMLight); libobj_impl_eq_ord_hash!(BMLight); libobj_impl_abstract_object!(BMLight); libobj_impl_obj_trait!(BMLight, BMObjectDecl); @@ -1272,7 +1397,7 @@ libobj_impl_obj_trait!(BMLight, BM3dEntityDecl); libobj_impl_obj_trait!(BMLight, BMLightDecl); libobj_struct!(BMTargetLight); -libobj_impl_new!(BMTargetLight); +libobj_impl_clone!(BMTargetLight); libobj_impl_eq_ord_hash!(BMTargetLight); libobj_impl_abstract_object!(BMTargetLight); libobj_impl_obj_trait!(BMTargetLight, BMObjectDecl); @@ -1281,7 +1406,7 @@ libobj_impl_obj_trait!(BMTargetLight, BMLightDecl); libobj_impl_obj_trait!(BMTargetLight, BMTargetLightDecl); libobj_struct!(BMCamera); -libobj_impl_new!(BMCamera); +libobj_impl_clone!(BMCamera); libobj_impl_eq_ord_hash!(BMCamera); libobj_impl_abstract_object!(BMCamera); libobj_impl_obj_trait!(BMCamera, BMObjectDecl); @@ -1289,7 +1414,7 @@ libobj_impl_obj_trait!(BMCamera, BM3dEntityDecl); libobj_impl_obj_trait!(BMCamera, BMCameraDecl); libobj_struct!(BMTargetCamera); -libobj_impl_new!(BMTargetCamera); +libobj_impl_clone!(BMTargetCamera); libobj_impl_eq_ord_hash!(BMTargetCamera); libobj_impl_abstract_object!(BMTargetCamera); libobj_impl_obj_trait!(BMTargetCamera, BMObjectDecl); @@ -1298,7 +1423,7 @@ libobj_impl_obj_trait!(BMTargetCamera, BMCameraDecl); libobj_impl_obj_trait!(BMTargetCamera, BMTargetCameraDecl); libobj_struct!(BMGroup); -libobj_impl_new!(BMGroup); +libobj_impl_clone!(BMGroup); libobj_impl_eq_ord_hash!(BMGroup); libobj_impl_abstract_object!(BMGroup); libobj_impl_obj_trait!(BMGroup, BMObjectDecl); diff --git a/Assets/BMapBindings/bmap-rs/tests/complete.rs b/Assets/BMapBindings/bmap-rs/tests/complete.rs index 8e7bddf..8eebe0a 100644 --- a/Assets/BMapBindings/bmap-rs/tests/complete.rs +++ b/Assets/BMapBindings/bmap-rs/tests/complete.rs @@ -85,7 +85,7 @@ mod testsuits { use super::bmap; use bmap::{ BM3dEntityDecl, BMCameraDecl, BMLightDecl, BMMaterialDecl, BMMeshDecl, BMObjectDecl, - BMTextureDecl, + BMTextureDecl, BMGroupDecl }; pub fn test(reader: &bmap::BMFileReader) { @@ -112,8 +112,9 @@ mod testsuits { let gp = gp.unwrap(); println!("{:?}", gp.get_name().unwrap()); - for gp_item in gp.get_objects() { - println!("\t{}", gp_item.get_name()); + for gp_item in gp.get_objects().unwrap() { + 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 let mut test_hashset = HashSet::new(); - assert!(test_hashset.insert(first_3dobj.clone())); - assert!(!test_hashset.insert(first_3dobj_again.clone())); + assert!(test_hashset.insert(first_3dobj)); + assert!(!test_hashset.insert(first_3dobj_again)); assert!(test_hashset.insert(second_3dobj)); // Test BTreeSet let mut test_btreeset = BTreeSet::new(); - assert!(test_btreeset.insert(first_3dobj.clone())); - assert!(!test_btreeset.insert(first_3dobj_again.clone())); + assert!(test_btreeset.insert(first_3dobj)); + assert!(!test_btreeset.insert(first_3dobj_again)); assert!(test_btreeset.insert(second_3dobj)); } }