Skip to main content

fre_rs/types/
classes.rs

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