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>;
38
39
40#[derive(Debug)]
45pub struct FunctionImplementation {
46 raw_name: UCStr,
47 raw_func: FREFunction,
48}
49impl FunctionImplementation {
50 pub fn raw_name(&self) -> &UCStr {&self.raw_name}
51 pub fn raw_func(&self) -> FREFunction {self.raw_func}
52 pub const fn new (raw_name: UCStr, raw_func: FREFunction) -> Self {
53 Self { raw_name, raw_func }
54 }
55}
56
57
58#[derive(Debug)]
65pub struct FunctionSet {
66 list: Vec<FRENamedFunction>,
67 map: HashMap<UCStr, usize>,
68}
69impl FunctionSet {
70 pub fn new () -> Self {
71 Self {
72 list: Vec::new(),
73 map: HashMap::new(),
74 }
75 }
76 pub fn with_capacity (capacity: usize) -> Self{
77 Self {
78 list: Vec::with_capacity(capacity),
79 map: HashMap::with_capacity(capacity),
80 }
81 }
82
83 pub fn add (
96 &mut self,
97 name: Option<UCStr>,
98 func_data: Option<Box<dyn Any>>,
99 func_impl: &FunctionImplementation,
100 ) {
101 let name = name.unwrap_or(func_impl.raw_name.clone());
102 let index = self.list.len();
103 self.list.push(FRENamedFunction {
104 name: name.as_ptr(),
105 functionData: if let Some(func_data) = func_data {crate::data::into_raw(func_data).as_ptr()} else {FREData::default()},
106 function: func_impl.raw_func,
107 });
108 let r = self.map.insert(name, index);
109 assert!(r.is_none(), "Method name conflict.");
110 }
111}
112impl Drop for FunctionSet {
113 fn drop(&mut self) {
114 self.list.iter()
115 .map(|i| i.functionData)
116 .for_each(|d| {
117 if let Some(d) = NonNullFREData::new(d) {
118 unsafe {crate::data::drop_from(d)};
119 }
120 });
121 }
122}
123
124
125#[derive(Debug)]
126pub(super) struct MethodSet {
127 registry: Box<[FRENamedFunction]>,
128 dictionary: HashMap<UCStr, usize>,
129}
130impl MethodSet {
131 pub(super) fn get(&self, name: &str) -> Option<(FREFunction, FREData)> {
133 self.dictionary.get(name)
134 .map(|index| {
135 let i = &(self.registry[*index]);
136 (i.function, i.functionData)
137 })
138 }
139}
140impl Drop for MethodSet {
141 fn drop(&mut self) {
142 self.registry.iter()
143 .map(|i| i.functionData)
144 .for_each(|d| {
145 if let Some(d) = NonNullFREData::new(d) {
146 unsafe {crate::data::drop_from(d)};
147 }
148 });
149 }
150}
151impl From<FunctionSet> for MethodSet {
152 fn from(mut value: FunctionSet) -> Self {
153 let registry = std::mem::take(&mut value.list).into_boxed_slice();
154 let dictionary = std::mem::take(&mut value.map);
155 Self { registry, dictionary }
156 }
157}
158impl AsRef<[FRENamedFunction]> for MethodSet {
159 fn as_ref(&self) -> &[FRENamedFunction] {self.registry.as_ref()}
160}