1use super::*;
2
3
4pub type Initializer = fn () -> Option<Box<dyn Any>>;
9
10pub type Finalizer = fn (ext_data: Option<Box<dyn Any>>);
16
17pub type ContextInitializer = fn (ctx: &CurrentContext) -> (Option<Box<dyn Any>>, FunctionSet);
23
24pub type ContextFinalizer = fn (ctx: &CurrentContext);
28
29pub type Function <'a> = fn (ctx: &CurrentContext<'a>, func_data: Option<&mut dyn Any>, args: &[as3::Object<'a>]) -> as3::Object<'a>;
32
33
34#[derive(Debug)]
39pub struct FunctionImplementation {
40 raw_name: UCStr,
41 raw_func: FREFunction,
42}
43impl FunctionImplementation {
44 pub fn raw_name(&self) -> &UCStr {&self.raw_name}
45 pub fn raw_func(&self) -> FREFunction {self.raw_func}
46 pub const fn new (raw_name: UCStr, raw_func: FREFunction) -> Self {
47 Self { raw_name, raw_func }
48 }
49}
50
51
52#[derive(Debug)]
59pub struct FunctionSet {
60 list: Vec<FRENamedFunction>,
61 map: HashMap<UCStr, usize>,
62}
63impl FunctionSet {
64 pub fn new () -> Self {
65 Self {
66 list: Vec::new(),
67 map: HashMap::new(),
68 }
69 }
70 pub fn with_capacity (capacity: usize) -> Self{
71 Self {
72 list: Vec::with_capacity(capacity),
73 map: HashMap::with_capacity(capacity),
74 }
75 }
76
77 pub fn add (
90 &mut self,
91 name: Option<UCStr>,
92 func_data: Option<Box<dyn Any>>,
93 func_impl: &FunctionImplementation,
94 ) {
95 let name = name.unwrap_or(func_impl.raw_name.clone());
96 let index = self.list.len();
97 self.list.push(FRENamedFunction {
98 name: name.as_ptr(),
99 functionData: if let Some(func_data) = func_data {crate::data::into_raw(func_data).as_ptr()} else {FREData::default()},
100 function: func_impl.raw_func,
101 });
102 let r = self.map.insert(name, index);
103 assert!(r.is_none(), "Method name conflict.");
104 }
105}
106impl Drop for FunctionSet {
107 fn drop(&mut self) {
108 self.list.iter()
109 .map(|i| i.functionData)
110 .for_each(|d| {
111 if let Some(d) = NonNullFREData::new(d) {
112 unsafe {crate::data::drop_from(d)};
113 }
114 });
115 }
116}
117
118
119#[derive(Debug)]
120pub(super) struct MethodSet {
121 registry: Box<[FRENamedFunction]>,
122 dictionary: HashMap<UCStr, usize>,
123}
124impl MethodSet {
125 pub(super) fn get(&self, name: &str) -> Option<(FREFunction, FREData)> {
127 self.dictionary.get(name)
128 .map(|index| {
129 let i = &(self.registry[*index]);
130 (i.function, i.functionData)
131 })
132 }
133}
134impl Drop for MethodSet {
135 fn drop(&mut self) {
136 self.registry.iter()
137 .map(|i| i.functionData)
138 .for_each(|d| {
139 if let Some(d) = NonNullFREData::new(d) {
140 unsafe {crate::data::drop_from(d)};
141 }
142 });
143 }
144}
145impl From<FunctionSet> for MethodSet {
146 fn from(mut value: FunctionSet) -> Self {
147 let registry = std::mem::take(&mut value.list).into_boxed_slice();
148 let dictionary = std::mem::take(&mut value.map);
149 Self { registry, dictionary }
150 }
151}
152impl AsRef<[FRENamedFunction]> for MethodSet {
153 fn as_ref(&self) -> &[FRENamedFunction] {self.registry.as_ref()}
154}