Skip to main content

fre_rs/types/
classes.rs

1use super::*;
2
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[repr(transparent)]
6pub struct Array <'a> (NonNullFREObject, PhantomData<&'a()>);
7impl<'a> Array<'a> {
8    const CLASS: UCStr = unsafe {UCStr::from_literal_unchecked(c"Array")};
9    pub fn get_length (self) -> u32 {
10        let mut value = u32::default();
11        let r = unsafe {FREGetArrayLength(self.as_ptr(), &mut value)};
12        debug_assert!(r.is_ok());
13        value
14    }
15    /// [`Err`]=> [FfiError::InsufficientMemory];
16    pub fn set_length (self, value: u32) -> Result<(), FfiError> {
17        let r = unsafe {FRESetArrayLength(self.as_ptr(), value)};
18        if let Ok(e) = FfiError::try_from(r) {
19            Err(e)
20        } else {Ok(())}
21    }
22    pub fn get (self, index: u32) -> Object<'a> {
23        let mut obj = std::ptr::null_mut();
24        let r = unsafe {FREGetArrayElementAt(self.as_ptr(), index, &mut obj)};
25        debug_assert!(r.is_ok());
26        debug_assert!(!obj.is_null());
27        unsafe {transmute(obj)}
28    }
29    pub fn set <O: AsObject<'a>> (self, index: u32, value: O) {
30        let r = unsafe {FRESetArrayElementAt(self.as_ptr(), index, value.as_ptr())};
31        debug_assert!(r.is_ok());
32    }
33    pub fn new (ctx: &CurrentContext<'a>, num_elements: Option<NonNegativeInt>) -> Self {
34        let mut arg = as3::null;
35        let num_elements = num_elements.map(|v|{
36            arg = int::new(ctx, v.get()).as_object();
37            std::slice::from_ref(&arg)
38        });
39        let obj = Object::new(ctx, Self::CLASS, num_elements).unwrap();
40        assert!(!obj.is_null());
41        unsafe {transmute(obj)}
42    }
43    pub fn from_slice (ctx: &CurrentContext<'a>, elements: &[Object<'a>]) -> Self {
44        debug_assert!(elements.len() <= i32::MAX as usize);
45        if elements.len() == 1 && elements[0].get_type() == Type::Number {
46            let arr = Self::new(ctx, NonNegativeInt::new(1));
47            arr.set(0, *unsafe {elements.get_unchecked(0)});
48            arr
49        } else {
50            let obj = Object::new(ctx, Self::CLASS, Some(elements)).unwrap();
51            debug_assert!(!obj.is_null());
52            unsafe {transmute(obj)}
53        }
54    }
55    pub fn extend_from_slice (self, elements: &[Object]) -> u32 {
56        const PUSH: UCStr = unsafe {UCStr::from_literal_unchecked(c"push")};
57        self.call_method(PUSH, Some(elements))
58            .unwrap()
59            .try_into()
60            .unwrap()
61    }
62    pub fn push <O: AsObject<'a>> (self, element: O) -> u32 {
63        let element = element.as_object();
64        let elements = std::slice::from_ref(&element);
65        self.extend_from_slice(elements)
66    }
67    pub fn iter(self) -> ArrayIter<'a> {ArrayIter::new(self)}
68}
69impl<'a> IntoIterator for Array<'a> {
70    type Item = Object<'a>;
71    type IntoIter = ArrayIter<'a>;
72    fn into_iter(self) -> Self::IntoIter {self.iter()}
73}
74unsafe impl<'a> AsObject<'a> for Array<'a> {const TYPE: Type = Type::Array;}
75unsafe impl<'a> TryAs<'a, Array<'a>> for Object<'a> {}
76impl From<Array<'_>> for FREObject {fn from(value: Array) -> Self {value.as_ptr()}}
77impl<'a> From<Array<'a>> for Object<'a> {fn from(value: Array<'a>) -> Self {value.as_object()}}
78impl<'a> TryFrom<Object<'a>> for Array<'a> {type Error = Type; fn try_from (value: Object<'a>) -> Result<Self, Type> {value.try_as()}}
79impl Display for Array<'_> {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {Display::fmt(&self.as_object(), f)}}
80
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
83#[repr(transparent)]
84pub struct Vector <'a> (NonNullFREObject, PhantomData<&'a()>);
85impl<'a> Vector<'a> {
86    pub fn get_length (self) -> u32 {
87        let mut value = u32::default();
88        let r = unsafe {FREGetArrayLength(self.as_ptr(), &mut value)};
89        debug_assert!(r.is_ok());
90        value
91    }
92    /// [`Err`]=> [FfiError::InsufficientMemory], [FfiError::ReadOnly];
93    pub fn set_length (self, value: u32) -> Result<(), FfiError> {
94        let r = unsafe {FRESetArrayLength(self.as_ptr(), value)};
95        if let Ok(e) = FfiError::try_from(r) {
96            Err(e)
97        } else {Ok(())}
98    }
99    /// [`Err`]=> [FfiError::InvalidArgument];
100    pub fn get (self, index: u32) -> Result<Object<'a>, FfiError> {
101        let mut obj = std::ptr::null_mut();
102        let r = unsafe {FREGetArrayElementAt(self.as_ptr(), index, &mut obj)};
103        if let Ok(e) = FfiError::try_from(r) {
104            Err(e)
105        } else {
106            debug_assert!(!obj.is_null());
107            Ok(unsafe {transmute(obj)})
108        }
109    }
110    /// [`Err`]=> [FfiError::TypeMismatch];
111    pub fn set <O: AsObject<'a>> (self, index: u32, value: O) -> Result<(), FfiError> {
112        let r = unsafe {FRESetArrayElementAt(self.as_ptr(), index, value.as_ptr())};
113        if let Ok(e) = FfiError::try_from(r) {
114            Err(e)
115        } else {Ok(())}
116    }
117    pub fn iter(self) -> VectorIter<'a> {VectorIter::new(self)}
118}
119impl<'a> IntoIterator for Vector<'a> {
120    type Item = Object<'a>;
121    type IntoIter = VectorIter<'a>;
122    fn into_iter(self) -> Self::IntoIter {self.iter()}
123}
124unsafe impl<'a> AsObject<'a> for Vector<'a> {const TYPE: Type = Type::Vector;}
125unsafe impl<'a> TryAs<'a, Vector<'a>> for Object<'a> {}
126impl From<Vector<'_>> for FREObject {fn from(value: Vector) -> Self {value.as_ptr()}}
127impl<'a> From<Vector<'a>> for Object<'a> {fn from(value: Vector<'a>) -> Self {value.as_object()}}
128impl<'a> TryFrom<Object<'a>> for Vector<'a> {type Error = Type; fn try_from (value: Object<'a>) -> Result<Self, Type> {value.try_as()}}
129impl Display for Vector<'_> {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {Display::fmt(&self.as_object(), f)}}
130
131
132///
133/// TODO: Implement properties and methods of `flash.utils.ByteArray`.
134///
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
136#[repr(transparent)]
137pub struct ByteArray <'a> (NonNullFREObject, PhantomData<&'a()>);
138impl<'a> ByteArray<'a> {
139    #[allow(unused_variables)]
140    pub fn new (ctx: &CurrentContext<'a>, length: u32) -> Self {
141        let ptr = FREByteArray {length, bytes: std::ptr::null_mut()};
142        let mut obj = std::ptr::null_mut();
143        let r = unsafe {FRENewByteArray(transmute(&ptr), &mut obj)};
144        debug_assert!(r.is_ok());
145        assert!(!obj.is_null());
146        unsafe {transmute(obj)}
147    }
148    #[allow(unused_variables)]
149    pub fn from_bytes (ctx: &CurrentContext<'a>, bytes: impl AsRef<[u8]>) -> Self {
150        let bytes = bytes.as_ref();
151        debug_assert!(bytes.len() <= u32::MAX as usize);
152        let ptr = FREByteArray {length: bytes.len() as u32, bytes: bytes.as_ptr() as FREBytes};
153        let mut obj = std::ptr::null_mut();
154        let r = unsafe {FRENewByteArray(transmute(&ptr), &mut obj)};
155        debug_assert!(r.is_ok());
156        assert!(!obj.is_null());
157        unsafe {transmute(obj)}
158    }
159
160    /// Using [`as3::null`] inside the closure is meaningless and may lead to unintended FFI call ordering.
161    /// 
162    pub fn with <F, R> (self, f: F) -> R
163    where F: FnOnce (&mut [u8]) -> R + Sync
164    {
165        let mut fat = FREByteArray {length: 0, bytes: std::ptr::null_mut()};
166        let result = unsafe {FREAcquireByteArray(self.as_ptr(), &mut fat)};
167        assert!(result.is_ok());
168        assert!(!fat.bytes.is_null());
169        let bytes = unsafe {std::slice::from_raw_parts_mut(fat.bytes, fat.length as usize)};
170        let r = f(bytes);
171        let result = unsafe {FREReleaseByteArray(self.as_ptr())};
172        debug_assert!(result.is_ok());
173        r
174    }
175}
176unsafe impl<'a> AsObject<'a> for ByteArray<'a> {const TYPE: Type = Type::ByteArray;}
177unsafe impl<'a> TryAs<'a, ByteArray<'a>> for Object<'a> {}
178impl From<ByteArray<'_>> for FREObject {fn from(value: ByteArray) -> Self {value.as_ptr()}}
179impl<'a> From<ByteArray<'a>> for Object<'a> {fn from(value: ByteArray<'a>) -> Self {value.as_object()}}
180impl<'a> TryFrom<Object<'a>> for ByteArray<'a> {type Error = Type; fn try_from (value: Object<'a>) -> Result<Self, Type> {value.try_as()}}
181impl Display for ByteArray<'_> {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {Display::fmt(&self.as_object(), f)}}
182
183
184///
185/// TODO: Implement properties and methods of `flash.display.BitmapData`.
186///
187#[derive(Debug, Clone, Copy, PartialEq, Eq)]
188#[repr(transparent)]
189pub struct BitmapData <'a> (NonNullFREObject, PhantomData<&'a()>);
190impl<'a> BitmapData<'a> {
191    /// Using [`as3::null`] inside the closure is meaningless and may lead to unintended FFI call ordering.
192    /// 
193    pub fn with <F, R> (self, f: F) -> R
194    where F: FnOnce (BitmapDataAdapter) -> R + Sync
195    {
196        let mut descriptor = FREBitmapData2::default();
197        let result = unsafe {FREAcquireBitmapData2(self.as_ptr(), &mut descriptor)};
198        assert!(result.is_ok());
199        let r = f(unsafe {BitmapDataAdapter::new(self.as_ptr(), descriptor)});
200        let result = unsafe {FREReleaseBitmapData(self.as_ptr())};
201        debug_assert!(result.is_ok());
202        r
203    }
204}
205unsafe impl<'a> AsObject<'a> for BitmapData<'a> {const TYPE: Type = Type::BitmapData;}
206unsafe impl<'a> TryAs<'a, BitmapData<'a>> for Object<'a> {}
207impl From<BitmapData<'_>> for FREObject {fn from(value: BitmapData) -> Self {value.as_ptr()}}
208impl<'a> From<BitmapData<'a>> for Object<'a> {fn from(value: BitmapData<'a>) -> Self {value.as_object()}}
209impl<'a> TryFrom<Object<'a>> for BitmapData<'a> {type Error = Type; fn try_from (value: Object<'a>) -> Result<Self, Type> {value.try_as()}}
210impl Display for BitmapData<'_> {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {Display::fmt(&self.as_object(), f)}}
211
212
213///
214/// TODO: Implement properties and methods of `flash.display3D.Context3D`.
215///
216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
217#[repr(transparent)]
218pub struct Context3D <'a> (NonNullFREObject, PhantomData<&'a()>);
219impl<'a> Context3D<'a> {
220    pub fn value (self) -> FREHandle {
221        let mut handle = FREHandle::default();
222        let r = unsafe {FREGetNativeContext3DHandle(self.as_ptr(), &mut handle)};
223        debug_assert!(r.is_ok());
224        assert!(!handle.is_null());
225        handle
226    }
227}
228unsafe impl<'a> AsObject<'a> for Context3D<'a> {const TYPE: Type = Type::Context3D;}
229// unsafe impl<'a> TryAs<'a, Context3D<'a>> for Object<'a> {}
230impl From<Context3D<'_>> for FREObject {fn from(value: Context3D) -> Self {value.as_ptr()}}
231impl<'a> From<Context3D<'a>> for Object<'a> {fn from(value: Context3D<'a>) -> Self {value.as_object()}}
232// impl<'a> TryFrom<Object<'a>> for Context3D<'a> {type Error = Type; fn try_from (value: Object<'a>) -> Result<Self, Type> {value.try_as()}}
233impl Display for Context3D<'_> {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {Display::fmt(&self.as_object(), f)}}
234
235
236#[derive(Debug, Clone, Copy, PartialEq, Eq)]
237#[repr(transparent)]
238pub struct ErrorObject <'a> (NonNullFREObject, PhantomData<&'a()>);
239impl<'a> ErrorObject<'a> {
240    #[allow(non_snake_case)]
241    pub fn get_errorID(self) -> i32 {
242        const ERROR_ID: UCStr = unsafe {UCStr::from_literal_unchecked(c"errorID")};
243        let value = self.get_property(ERROR_ID).unwrap().try_into().unwrap();
244        value
245    }
246    const MESSAGE: UCStr = unsafe {UCStr::from_literal_unchecked(c"message")};
247    pub fn get_message(self) -> Option<as3::String<'a>> {
248        let value = self.get_property(Self::MESSAGE).unwrap().try_as().ok();
249        value
250    }
251    pub fn set_message(self, value: Option<as3::String>) {
252        let r = self.set_property(Self::MESSAGE, Object::from(value));
253        debug_assert!(r.is_ok());
254    }
255    const NAME: UCStr = unsafe {UCStr::from_literal_unchecked(c"name")};
256    pub fn get_name(self) -> Option<as3::String<'a>> {
257        let value = self.get_property(Self::NAME).unwrap().try_as().ok();
258        value
259    }
260    pub fn set_name(self, value: Option<as3::String>) {
261        let r = self.set_property(Self::NAME, Object::from(value));
262        debug_assert!(r.is_ok());
263    }
264    const CLASS: UCStr = unsafe {UCStr::from_literal_unchecked(c"Error")};
265    pub fn new (ctx: &CurrentContext<'a>, message: Option<&str>, id: i32) -> Self {
266        let message = message.map(|s|as3::String::new(ctx, s));
267        let id = int::new(ctx, id);
268        let args = vec![message.into(), id.as_object()].into_boxed_slice();
269        let err_obj= Object::new(ctx, Self::CLASS, Some(args.as_ref())).unwrap();
270        assert!(!err_obj.is_null());
271        unsafe {transmute(err_obj)}
272    }
273}
274unsafe impl<'a> AsObject<'a> for ErrorObject<'a> {const TYPE: Type = Type::Error;}
275// unsafe impl<'a> TryAs<'a, ErrorObject<'a>> for Object<'a> {}
276impl From<ErrorObject<'_>> for FREObject {fn from(value: ErrorObject) -> Self {value.as_ptr()}}
277impl<'a> From<ErrorObject<'a>> for Object<'a> {fn from(value: ErrorObject<'a>) -> Self {value.as_object()}}
278// impl<'a> TryFrom<Object<'a>> for ErrorObject<'a> {type Error = Type; fn try_from (value: Object<'a>) -> Result<Self, Type> {value.try_as()}}
279impl Display for ErrorObject<'_> {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {Display::fmt(&self.as_object(), f)}}