dora_ssr/
dora.rs

1/* Copyright (c) 2016-2025 Li Jin <dragon-fly@qq.com>
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
7THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
8
9use std::cell::{LazyCell, RefCell};
10use std::{any::Any, ffi::c_void};
11
12mod rect;
13pub use rect::Rect;
14mod array;
15pub use array::Array;
16mod dictionary;
17pub use dictionary::Dictionary;
18mod director;
19pub use director::Director;
20mod app;
21pub use app::App;
22mod entity;
23pub use entity::Entity;
24mod group;
25pub use group::Group;
26mod observer;
27pub use observer::Observer;
28mod path;
29pub use path::Path;
30mod content;
31pub use content::Content;
32mod scheduler;
33pub use scheduler::Scheduler;
34mod camera;
35pub use camera::{Camera, ICamera};
36mod camera_2d;
37pub use camera_2d::Camera2D;
38mod camera_otho;
39pub use camera_otho::CameraOtho;
40mod pass;
41pub use pass::Pass;
42mod effect;
43pub use effect::{Effect, IEffect};
44mod sprite_effect;
45pub use sprite_effect::SpriteEffect;
46mod view;
47pub use view::View;
48mod action_def;
49pub use action_def::ActionDef;
50mod action;
51pub use action::Action;
52mod grabber;
53pub use grabber::Grabber;
54mod node;
55pub use node::{INode, Node};
56mod texture_2d;
57pub use texture_2d::Texture2D;
58mod sprite;
59pub use sprite::Sprite;
60mod grid;
61pub use grid::Grid;
62mod touch;
63pub use touch::Touch;
64mod ease;
65pub use ease::Ease;
66mod label;
67pub use label::Label;
68mod render_target;
69pub use render_target::RenderTarget;
70mod clip_node;
71pub use clip_node::ClipNode;
72mod draw_node;
73pub use draw_node::DrawNode;
74mod vertex_color;
75pub use vertex_color::VertexColor;
76mod line;
77pub use line::Line;
78mod particle;
79pub use particle::Particle;
80mod playable;
81pub use playable::{IPlayable, Playable};
82mod model;
83pub use model::Model;
84mod spine;
85pub use spine::Spine;
86mod dragon_bone;
87pub use dragon_bone::DragonBone;
88mod align_node;
89pub use align_node::AlignNode;
90mod effek_node;
91pub use effek_node::EffekNode;
92mod physics_world;
93pub use tile_node::TileNode;
94mod tile_node;
95pub use physics_world::{IPhysicsWorld, PhysicsWorld};
96mod fixture_def;
97pub use fixture_def::FixtureDef;
98mod body_def;
99pub use body_def::BodyDef;
100mod sensor;
101pub use sensor::Sensor;
102mod body;
103pub use body::{Body, IBody};
104mod joint_def;
105pub use joint_def::JointDef;
106mod joint;
107pub use joint::{IJoint, Joint};
108mod motor_joint;
109pub use motor_joint::MotorJoint;
110mod move_joint;
111pub use move_joint::MoveJoint;
112mod cache;
113pub use cache::Cache;
114mod audio;
115pub use audio::Audio;
116mod audio_bus;
117pub use audio_bus::AudioBus;
118mod audio_source;
119pub use audio_source::AudioSource;
120mod keyboard;
121pub use keyboard::Keyboard;
122mod mouse;
123pub use mouse::Mouse;
124mod controller;
125pub use controller::Controller;
126mod svg;
127pub use svg::SVG;
128mod dbquery;
129pub use dbquery::DBQuery;
130mod dbparams;
131pub use dbparams::DBParams;
132mod dbrecord;
133pub use dbrecord::DBRecord;
134mod db;
135pub use db::DB;
136mod work_book;
137pub use work_book::WorkBook;
138mod work_sheet;
139pub use work_sheet::WorkSheet;
140mod c_45;
141mod q_learner;
142pub mod ml {
143	pub use super::c_45::C45;
144	pub use super::q_learner::QLearner;
145}
146mod http_client;
147pub use http_client::HttpClient;
148mod buffer;
149pub mod platformer;
150pub use buffer::Buffer;
151mod im_gui;
152pub use im_gui::ImGui;
153mod vgpaint;
154pub use vgpaint::VGPaint;
155mod nvg;
156pub use nvg::Nvg;
157mod vgnode;
158pub use vgnode::VGNode;
159
160type ObjectFunc = fn(i64) -> Option<Box<dyn IObject>>;
161
162thread_local! {
163	static OBJECT_MAP: LazyCell<Vec<Option<ObjectFunc>>> = LazyCell::new(|| {
164		let type_funcs = [
165			Array::type_info(),
166			Dictionary::type_info(),
167			Entity::type_info(),
168			Group::type_info(),
169			Observer::type_info(),
170			Scheduler::type_info(),
171			Camera::type_info(),
172			Camera2D::type_info(),
173			CameraOtho::type_info(),
174			Pass::type_info(),
175			Effect::type_info(),
176			SpriteEffect::type_info(),
177			Grabber::type_info(),
178			Action::type_info(),
179			Node::type_info(),
180			Texture2D::type_info(),
181			Sprite::type_info(),
182			Grid::type_info(),
183			Touch::type_info(),
184			Label::type_info(),
185			RenderTarget::type_info(),
186			ClipNode::type_info(),
187			DrawNode::type_info(),
188			Line::type_info(),
189			Particle::type_info(),
190			Playable::type_info(),
191			Model::type_info(),
192			Spine::type_info(),
193			DragonBone::type_info(),
194			AlignNode::type_info(),
195			EffekNode::type_info(),
196			TileNode::type_info(),
197			PhysicsWorld::type_info(),
198			FixtureDef::type_info(),
199			BodyDef::type_info(),
200			Sensor::type_info(),
201			Body::type_info(),
202			JointDef::type_info(),
203			Joint::type_info(),
204			MotorJoint::type_info(),
205			MoveJoint::type_info(),
206			SVG::type_info(),
207			AudioBus::type_info(),
208			AudioSource::type_info(),
209			ml::QLearner::type_info(),
210			platformer::ActionUpdate::type_info(),
211			platformer::Face::type_info(),
212			platformer::BulletDef::type_info(),
213			platformer::Bullet::type_info(),
214			platformer::Visual::type_info(),
215			platformer::behavior::Tree::type_info(),
216			platformer::decision::Tree::type_info(),
217			platformer::Unit::type_info(),
218			platformer::PlatformCamera::type_info(),
219			platformer::PlatformWorld::type_info(),
220			Buffer::type_info(),
221			VGNode::type_info(),
222		];
223		let mut map: Vec<Option<ObjectFunc>> = Vec::new();
224		for pair in type_funcs.iter() {
225			let t = pair.0 as usize;
226			if map.len() < t + 1 {
227				map.resize(t + 1, None);
228			}
229			if map[t].is_some() {
230				panic!("cpp object type id {} duplicated!", t);
231			}
232			map[t] = Some(pair.1);
233		}
234		map
235	});
236	static FUNC_MAP: RefCell<Vec<Box<dyn FnMut()>>> = RefCell::new(Vec::new());
237	static FUNC_AVAILABLE: RefCell<Vec<i32>> = RefCell::new(Vec::new());
238}
239
240extern "C" {
241	fn object_get_id(obj: i64) -> i32;
242	fn object_get_type(obj: i64) -> i32;
243	fn object_retain(obj: i64);
244	fn object_release(obj: i64);
245
246	fn object_to_node(obj: i64) -> i64;
247	fn object_to_camera(obj: i64) -> i64;
248	fn object_to_playable(obj: i64) -> i64;
249	fn object_to_physics_world(obj: i64) -> i64;
250	fn object_to_body(obj: i64) -> i64;
251	fn object_to_joint(obj: i64) -> i64;
252
253	fn str_new(len: i32) -> i64;
254	fn str_len(str: i64) -> i32;
255	fn str_read(dest: *mut c_void, src: i64);
256	fn str_write(dest: i64, src: *const c_void);
257	fn str_release(str: i64);
258
259	fn buf_new_i32(len: i32) -> i64;
260	fn buf_new_i64(len: i32) -> i64;
261	fn buf_new_f32(len: i32) -> i64;
262	fn buf_new_f64(len: i32) -> i64;
263	fn buf_len(v: i64) -> i32;
264	fn buf_read(dest: *mut c_void, src: i64);
265	fn buf_write(dest: i64, src: *const c_void);
266	fn buf_release(v: i64);
267
268	fn value_create_i64(value: i64) -> i64;
269	fn value_create_f64(value: f64) -> i64;
270	fn value_create_str(value: i64) -> i64;
271	fn value_create_bool(value: i32) -> i64;
272	fn value_create_object(value: i64) -> i64;
273	fn value_create_vec2(value: i64) -> i64;
274	fn value_create_size(value: i64) -> i64;
275	fn value_release(value: i64);
276	fn value_into_i64(value: i64) -> i64;
277	fn value_into_f64(value: i64) -> f64;
278	fn value_into_str(value: i64) -> i64;
279	fn value_into_bool(value: i64) -> i32;
280	fn value_into_object(value: i64) -> i64;
281	fn value_into_vec2(value: i64) -> i64;
282	fn value_into_size(value: i64) -> i64;
283	fn value_is_i64(value: i64) -> i32;
284	fn value_is_f64(value: i64) -> i32;
285	fn value_is_str(value: i64) -> i32;
286	fn value_is_bool(value: i64) -> i32;
287	fn value_is_object(value: i64) -> i32;
288	fn value_is_vec2(value: i64) -> i32;
289	fn value_is_size(value: i64) -> i32;
290
291	fn call_stack_create() -> i64;
292	fn call_stack_release(info: i64);
293	fn call_stack_push_i64(info: i64, value: i64);
294	fn call_stack_push_f64(info: i64, value: f64);
295	fn call_stack_push_str(info: i64, value: i64);
296	fn call_stack_push_bool(info: i64, value: i32);
297	fn call_stack_push_object(info: i64, value: i64);
298	fn call_stack_push_vec2(info: i64, value: i64);
299	fn call_stack_push_size(info: i64, value: i64);
300	fn call_stack_pop_i64(info: i64) -> i64;
301	fn call_stack_pop_f64(info: i64) -> f64;
302	fn call_stack_pop_str(info: i64) -> i64;
303	fn call_stack_pop_bool(info: i64) -> i32;
304	fn call_stack_pop_object(info: i64) -> i64;
305	fn call_stack_pop_vec2(info: i64) -> i64;
306	fn call_stack_pop_size(info: i64) -> i64;
307	fn call_stack_pop(info: i64) -> i32;
308	fn call_stack_front_i64(info: i64) -> i32;
309	fn call_stack_front_f64(info: i64) -> i32;
310	fn call_stack_front_str(info: i64) -> i32;
311	fn call_stack_front_bool(info: i64) -> i32;
312	fn call_stack_front_object(info: i64) -> i32;
313	fn call_stack_front_vec2(info: i64) -> i32;
314	fn call_stack_front_size(info: i64) -> i32;
315
316	fn dora_print(msg: i64);
317	fn dora_print_warning(msg: i64);
318	fn dora_print_error(msg: i64);
319
320	fn vec2_add(a: i64, b: i64) -> i64;
321	fn vec2_sub(a: i64, b: i64) -> i64;
322	fn vec2_mul(a: i64, b: i64) -> i64;
323	fn vec2_mul_float(a: i64, b: f32) -> i64;
324	fn vec2_div(a: i64, b: f32) -> i64;
325	fn vec2_distance(a: i64, b: i64) -> f32;
326	fn vec2_distance_squared(a: i64, b: i64) -> f32;
327	fn vec2_length(a: i64) -> f32;
328	fn vec2_angle(a: i64) -> f32;
329	fn vec2_normalize(a: i64) -> i64;
330	fn vec2_perp(a: i64) -> i64;
331	fn vec2_dot(a: i64, b: i64) -> f32;
332	fn vec2_clamp(a: i64, from: i64, to: i64) -> i64;
333
334	fn dora_emit(name: i64, stack: i64);
335}
336
337pub fn print(msg: &str) {
338	unsafe {
339		dora_print(from_string(msg));
340	}
341}
342
343pub fn print_warning(msg: &str) {
344	unsafe {
345		dora_print_warning(from_string(msg));
346	}
347}
348
349pub fn print_error(msg: &str) {
350	unsafe {
351		dora_print_error(from_string(msg));
352	}
353}
354
355/// Emits a global event with the given name and arguments to all listeners registered by `node.gslot()` function.
356///
357/// # Arguments
358///
359/// * eventName - The name of the event to emit.
360/// * stack - The data to pass to the global event listeners.
361///
362/// # Example
363///
364/// ```
365/// let mut node = Node::new();
366/// node.gslot("MyGlobalEvent", Box::new(|stack| {
367/// 	let (arg1, arg2) = match (stack.pop_str(), stack.pop_i64()) {
368/// 		(Some(arg1), Some(arg2)) => (arg1, arg2),
369/// 		_ => return,
370/// 	};
371/// 	p!("Event triggered: {}, {}", arg1, arg2);
372/// }));
373///
374/// emit("MyGlobalEvent", args!("Hello", 123));
375/// ```
376pub fn emit(name: &str, stack: CallStack) {
377	unsafe {
378		dora_emit(from_string(name), stack.raw());
379	}
380}
381
382#[macro_export]
383macro_rules! p {
384	() => {
385		dora_ssr::print("")
386	};
387	($($arg:tt)*) => {{
388		dora_ssr::print((format!($($arg)*)).as_str());
389	}};
390}
391
392/// A record representing a 2D vector with an x and y component.
393#[repr(C)]
394#[derive(Clone, Copy, PartialEq)]
395pub struct Vec2 {
396	pub x: f32,
397	pub y: f32,
398}
399
400impl Vec2 {
401	pub(crate) fn from(value: i64) -> Vec2 {
402		unsafe { LightValue { value: value }.vec2 }
403	}
404	pub(crate) fn into_i64(&self) -> i64 {
405		unsafe { LightValue { vec2: *self }.value }
406	}
407	pub fn new(x: f32, y: f32) -> Vec2 {
408		Vec2 { x: x, y: y }
409	}
410	pub fn zero() -> Vec2 {
411		Vec2 { x: 0.0, y: 0.0 }
412	}
413	pub fn is_zero(&self) -> bool {
414		self.x == 0.0 && self.y == 0.0
415	}
416
417	pub fn distance(&self, other: &Vec2) -> f32 {
418		unsafe { vec2_distance(self.into_i64(), other.into_i64()) }
419	}
420	pub fn distance_squared(&self, other: &Vec2) -> f32 {
421		unsafe { vec2_distance_squared(self.into_i64(), other.into_i64()) }
422	}
423	pub fn length(&self) -> f32 {
424		unsafe { vec2_length(self.into_i64()) }
425	}
426	pub fn angle(&self) -> f32 {
427		unsafe { vec2_angle(self.into_i64()) }
428	}
429	pub fn normalize(&self) -> Vec2 {
430		Vec2::from(unsafe { vec2_normalize(self.into_i64()) })
431	}
432	pub fn perp(&self) -> Vec2 {
433		Vec2::from(unsafe { vec2_perp(self.into_i64()) })
434	}
435	pub fn dot(&self, other: &Vec2) -> f32 {
436		unsafe { vec2_dot(self.into_i64(), other.into_i64()) }
437	}
438	pub fn clamp(&self, from: &Vec2, to: &Vec2) -> Vec2 {
439		Vec2::from(unsafe { vec2_clamp(self.into_i64(), from.into_i64(), to.into_i64()) })
440	}
441}
442
443impl std::ops::Add for Vec2 {
444	type Output = Vec2;
445	fn add(self, other: Vec2) -> Vec2 {
446		Vec2::from(unsafe { vec2_add(self.into_i64(), other.into_i64()) })
447	}
448}
449
450impl std::ops::Sub for Vec2 {
451	type Output = Vec2;
452	fn sub(self, other: Vec2) -> Vec2 {
453		Vec2::from(unsafe { vec2_sub(self.into_i64(), other.into_i64()) })
454	}
455}
456
457impl std::ops::Mul for Vec2 {
458	type Output = Vec2;
459	fn mul(self, other: Vec2) -> Vec2 {
460		Vec2::from(unsafe { vec2_mul(self.into_i64(), other.into_i64()) })
461	}
462}
463
464impl std::ops::Mul<f32> for Vec2 {
465	type Output = Vec2;
466	fn mul(self, other: f32) -> Vec2 {
467		Vec2::from(unsafe { vec2_mul_float(self.into_i64(), other) })
468	}
469}
470
471impl std::ops::Div<f32> for Vec2 {
472	type Output = Vec2;
473	fn div(self, other: f32) -> Vec2 {
474		Vec2::from(unsafe { vec2_div(self.into_i64(), other) })
475	}
476}
477
478/// A size object with a given width and height.
479#[repr(C)]
480#[derive(Clone, Copy, PartialEq)]
481pub struct Size {
482	pub width: f32,
483	pub height: f32,
484}
485
486impl Size {
487	pub fn new(width: f32, height: f32) -> Size {
488		Size { width: width, height: height }
489	}
490	pub fn zero() -> Size {
491		Size { width: 0.0, height: 0.0 }
492	}
493	pub fn is_zero(&self) -> bool {
494		self.width == 0.0 && self.height == 0.0
495	}
496	pub(crate) fn from(value: i64) -> Size {
497		unsafe { LightValue { value: value }.size }
498	}
499	pub(crate) fn into_i64(&self) -> i64 {
500		unsafe { LightValue { size: *self }.value }
501	}
502}
503
504#[repr(C)]
505union LightValue {
506	vec2: Vec2,
507	size: Size,
508	value: i64,
509}
510
511/// A color with red, green, blue, and alpha channels.
512#[repr(C)]
513#[derive(Clone, Copy)]
514pub struct Color {
515	pub b: u8,
516	pub g: u8,
517	pub r: u8,
518	pub a: u8,
519}
520
521#[repr(C)]
522union ColorValue {
523	color: Color,
524	value: i32,
525}
526
527impl Color {
528	pub const WHITE: Color = Color { r: 255, g: 255, b: 255, a: 255 };
529	pub const BLACK: Color = Color { r: 0, g: 0, b: 0, a: 255 };
530	pub const TRANSPARENT: Color = Color { r: 0, g: 0, b: 0, a: 0 };
531	pub fn new(argb: u32) -> Color {
532		let a = argb >> 24;
533		let r = (argb & 0x00ff0000) >> 16;
534		let g = (argb & 0x0000ff00) >> 8;
535		let b = argb & 0x000000ff;
536		Color { r: r as u8, g: g as u8, b: b as u8, a: a as u8 }
537	}
538	pub fn from(argb: i32) -> Color {
539		unsafe { ColorValue { value: argb }.color }
540	}
541	pub fn to_argb(&self) -> u32 {
542		(self.a as u32) << 24 | (self.r as u32) << 16 | (self.g as u32) << 8 | self.b as u32
543	}
544	pub fn to_color3(&self) -> Color3 {
545		Color3 { r: self.r, g: self.g, b: self.b }
546	}
547}
548
549/// A color with red, green and blue channels.
550#[repr(C)]
551#[derive(Clone, Copy)]
552pub struct Color3 {
553	pub b: u8,
554	pub g: u8,
555	pub r: u8,
556}
557
558#[repr(C)]
559#[derive(Clone, Copy)]
560struct Color3a {
561	color3: Color3,
562	a: u8,
563}
564
565#[repr(C)]
566union Color3Value {
567	color3a: Color3a,
568	value: i32,
569}
570
571impl Color3 {
572	pub const WHITE: Color3 = Color3 { r: 255, g: 255, b: 255 };
573	pub const BLACK: Color3 = Color3 { r: 0, g: 0, b: 0 };
574	pub fn new(rgb: u32) -> Color3 {
575		let r = (rgb & 0x00ff0000) >> 16;
576		let g = (rgb & 0x0000ff00) >> 8;
577		let b = rgb & 0x000000ff;
578		Color3 { r: r as u8, g: g as u8, b: b as u8 }
579	}
580	pub fn from(rgb: i32) -> Color3 {
581		unsafe { Color3Value { value: rgb }.color3a.color3 }
582	}
583	pub fn to_rgb(&self) -> u32 {
584		(self.r as u32) << 16 | (self.g as u32) << 8 | self.b as u32
585	}
586}
587
588fn to_string(str: i64) -> String {
589	unsafe {
590		let len = str_len(str) as usize;
591		let mut vec = Vec::with_capacity(len as usize);
592		vec.resize(len, 0);
593		let data = vec.as_mut_ptr() as *mut c_void;
594		str_read(data, str);
595		str_release(str);
596		return String::from_utf8(vec).unwrap();
597	}
598}
599
600fn from_string(s: &str) -> i64 {
601	unsafe {
602		let len = s.len() as i32;
603		let ptr = s.as_ptr();
604		let new_str = str_new(len);
605		str_write(new_str, ptr as *const c_void);
606		return new_str;
607	}
608}
609
610pub(crate) trait IBuf {
611	fn to_buf(&self) -> i64;
612}
613
614impl IBuf for Vec<i32> {
615	fn to_buf(&self) -> i64 {
616		unsafe {
617			let len = self.len() as i32;
618			let ptr = self.as_ptr();
619			let new_vec = buf_new_i32(len);
620			buf_write(new_vec, ptr as *const c_void);
621			return new_vec;
622		}
623	}
624}
625
626impl IBuf for Vec<i64> {
627	fn to_buf(&self) -> i64 {
628		unsafe {
629			let len = self.len() as i32;
630			let ptr = self.as_ptr();
631			let new_vec = buf_new_i64(len);
632			buf_write(new_vec, ptr as *const c_void);
633			return new_vec;
634		}
635	}
636}
637
638impl IBuf for Vec<f32> {
639	fn to_buf(&self) -> i64 {
640		unsafe {
641			let len = self.len() as i32;
642			let ptr = self.as_ptr();
643			let new_vec = buf_new_f32(len);
644			buf_write(new_vec, ptr as *const c_void);
645			return new_vec;
646		}
647	}
648}
649
650impl IBuf for Vec<f64> {
651	fn to_buf(&self) -> i64 {
652		unsafe {
653			let len = self.len() as i32;
654			let ptr = self.as_ptr();
655			let new_vec = buf_new_f64(len);
656			buf_write(new_vec, ptr as *const c_void);
657			return new_vec;
658		}
659	}
660}
661
662pub(crate) struct Vector;
663
664impl Vector {
665	pub fn to_num<T>(v: i64) -> Vec<T>
666	where
667		T: Clone + Default,
668	{
669		unsafe {
670			let len = buf_len(v) as usize;
671			let mut vec: Vec<T> = Vec::with_capacity(len as usize);
672			vec.resize(len, Default::default());
673			let data = vec.as_mut_ptr() as *mut c_void;
674			buf_read(data, v);
675			buf_release(v);
676			return vec;
677		}
678	}
679	pub fn to_str(v: i64) -> Vec<String> {
680		unsafe {
681			let len = buf_len(v) as usize;
682			let mut vec: Vec<i64> = Vec::with_capacity(len as usize);
683			vec.resize(len, Default::default());
684			let data = vec.as_mut_ptr() as *mut c_void;
685			buf_read(data, v);
686			let mut strs = Vec::with_capacity(vec.len());
687			for i in 0..vec.len() {
688				strs.push(to_string(vec[i]));
689			}
690			buf_release(v);
691			strs
692		}
693	}
694	pub fn from_num<T: IBuf>(s: &T) -> i64 {
695		return s.to_buf();
696	}
697	pub fn from_str(s: &Vec<&str>) -> i64 {
698		unsafe {
699			let len = s.len() as i32;
700			let mut strs: Vec<i64> = Vec::with_capacity(s.len());
701			for i in 0..s.len() {
702				strs.push(from_string(s[i]));
703			}
704			let ptr = strs.as_ptr();
705			let new_vec = buf_new_i64(len);
706			buf_write(new_vec, ptr as *const c_void);
707			return new_vec;
708		}
709	}
710	pub fn from_vec2(s: &Vec<Vec2>) -> i64 {
711		unsafe {
712			let len = s.len() as i32;
713			let mut vs: Vec<i64> = Vec::with_capacity(s.len());
714			for i in 0..s.len() {
715				vs.push(LightValue { vec2: s[i] }.value);
716			}
717			let ptr = vs.as_ptr();
718			let new_vec = buf_new_i64(len);
719			buf_write(new_vec, ptr as *const c_void);
720			return new_vec;
721		}
722	}
723	pub fn from_vertex_color(s: &Vec<VertexColor>) -> i64 {
724		unsafe {
725			let len = s.len() as i32;
726			let mut vs: Vec<i64> = Vec::with_capacity(s.len());
727			for i in 0..s.len() {
728				vs.push(s[i].raw());
729			}
730			let ptr = vs.as_ptr();
731			let new_vec = buf_new_i64(len);
732			buf_write(new_vec, ptr as *const c_void);
733			return new_vec;
734		}
735	}
736	pub fn from_action_def(s: &Vec<ActionDef>) -> i64 {
737		unsafe {
738			let len = s.len() as i32;
739			let mut vs: Vec<i64> = Vec::with_capacity(s.len());
740			for i in 0..s.len() {
741				vs.push(s[i].raw());
742			}
743			let ptr = vs.as_ptr();
744			let new_vec = buf_new_i64(len);
745			buf_write(new_vec, ptr as *const c_void);
746			return new_vec;
747		}
748	}
749	pub fn from_btree(s: &Vec<platformer::behavior::Tree>) -> i64 {
750		unsafe {
751			let len = s.len() as i32;
752			let mut vs: Vec<i64> = Vec::with_capacity(s.len());
753			for i in 0..s.len() {
754				vs.push(s[i].raw());
755			}
756			let ptr = vs.as_ptr();
757			let new_vec = buf_new_i64(len);
758			buf_write(new_vec, ptr as *const c_void);
759			return new_vec;
760		}
761	}
762	pub fn from_dtree(s: &Vec<platformer::decision::Tree>) -> i64 {
763		unsafe {
764			let len = s.len() as i32;
765			let mut vs: Vec<i64> = Vec::with_capacity(s.len());
766			for i in 0..s.len() {
767				vs.push(s[i].raw());
768			}
769			let ptr = vs.as_ptr();
770			let new_vec = buf_new_i64(len);
771			buf_write(new_vec, ptr as *const c_void);
772			return new_vec;
773		}
774	}
775}
776
777fn into_object(raw: i64) -> Option<Box<dyn IObject>> {
778	let mut converted: Option<Box<dyn IObject>> = None;
779	OBJECT_MAP.with(|map| converted = map[unsafe { object_get_type(raw) } as usize].unwrap()(raw));
780	converted
781}
782
783fn new_object(raw: i64) -> Option<Box<dyn IObject>> {
784	unsafe {
785		object_retain(raw);
786	}
787	let mut converted: Option<Box<dyn IObject>> = None;
788	OBJECT_MAP.with(|map| converted = map[unsafe { object_get_type(raw) } as usize].unwrap()(raw));
789	converted
790}
791
792fn push_function(func: Box<dyn FnMut()>) -> i32 {
793	#[cfg(target_arch = "wasm32")]
794	let flag = 0x01000000;
795	#[cfg(not(target_arch = "wasm32"))]
796	let flag = 0x00000000;
797	let mut ret_func_id = -1;
798	FUNC_MAP.with_borrow_mut(|map| {
799		if map.len() >= 0xffffff {
800			panic!("too many functions!");
801		}
802		FUNC_AVAILABLE.with_borrow_mut(|available| {
803			if let Some(func_id) = available.pop() {
804				map[func_id as usize] = func;
805				ret_func_id = func_id | flag;
806			} else {
807				map.push(func);
808				ret_func_id = (map.len() - 1) as i32 | flag
809			}
810		})
811	});
812	ret_func_id
813}
814
815#[no_mangle]
816pub extern "C" fn dora_wasm_version() -> i32 {
817	const MAJOR: &str = env!("CARGO_PKG_VERSION_MAJOR");
818	const MINOR: &str = env!("CARGO_PKG_VERSION_MINOR");
819	const PATCH: &str = env!("CARGO_PKG_VERSION_PATCH");
820	(MAJOR.parse::<i32>().unwrap() << 16)
821		| (MINOR.parse::<i32>().unwrap() << 8)
822		| PATCH.parse::<i32>().unwrap()
823}
824
825#[no_mangle]
826pub extern "C" fn call_function(func_id: i32) {
827	let real_id = func_id & 0x00ffffff;
828	let mut func: *mut Box<dyn FnMut()> = std::ptr::null_mut();
829	FUNC_MAP.with_borrow_mut(|map| {
830		func = &mut map[real_id as usize];
831	});
832	unsafe {
833		(*func)();
834	}
835}
836
837fn dummy_func() {
838	panic!("the dummy function should not be called.");
839}
840
841#[no_mangle]
842pub extern "C" fn deref_function(func_id: i32) {
843	let real_id = func_id & 0x00ffffff;
844	FUNC_MAP.with_borrow_mut(|map| {
845		map[real_id as usize] = Box::new(dummy_func);
846		FUNC_AVAILABLE.with_borrow_mut(|available| {
847			available.push(real_id);
848		});
849	});
850}
851
852pub trait IObject {
853	fn raw(&self) -> i64;
854	fn obj(&self) -> &dyn IObject;
855	fn get_id(&self) -> i32 {
856		unsafe { object_get_id(self.raw()) }
857	}
858	fn as_any(&self) -> &dyn Any;
859}
860
861pub struct Object {
862	raw: i64,
863}
864impl IObject for Object {
865	fn raw(&self) -> i64 {
866		self.raw
867	}
868	fn obj(&self) -> &dyn IObject {
869		self
870	}
871	fn as_any(&self) -> &dyn std::any::Any {
872		self
873	}
874}
875impl Drop for Object {
876	fn drop(&mut self) {
877		unsafe {
878			crate::dora::object_release(self.raw);
879		}
880	}
881}
882impl Clone for Object {
883	fn clone(&self) -> Object {
884		unsafe {
885			crate::dora::object_retain(self.raw);
886		}
887		Object { raw: self.raw }
888	}
889}
890impl Object {
891	pub(crate) fn from(raw: i64) -> Option<Object> {
892		match raw {
893			0 => None,
894			_ => Some(Object { raw: raw }),
895		}
896	}
897}
898
899pub fn cast<T: Clone + 'static>(obj: &dyn IObject) -> Option<T> {
900	Some(new_object(obj.raw())?.as_any().downcast_ref::<T>()?.clone())
901}
902
903/// An argument stack for passing values to a function.
904/// The stack is used to pass arguments to a function and to receive return values from a function.
905pub struct CallStack {
906	raw: i64,
907}
908
909pub enum DoraValue<'a> {
910	I32(i32),
911	I64(i64),
912	F32(f32),
913	F64(f64),
914	Bool(bool),
915	Str(&'a str),
916	Object(&'a dyn IObject),
917	Vec2(Vec2),
918	Size(Size),
919}
920
921pub trait IntoValue<'a> {
922	fn dora_val(self) -> DoraValue<'a>;
923	fn val(self) -> Value;
924}
925
926impl<'a> DoraValue<'a> {
927	pub fn push(self, info: &mut CallStack) {
928		match self {
929			DoraValue::I32(x) => info.push_i32(x),
930			DoraValue::I64(x) => info.push_i64(x),
931			DoraValue::F32(x) => info.push_f32(x),
932			DoraValue::F64(x) => info.push_f64(x),
933			DoraValue::Bool(x) => info.push_bool(x),
934			DoraValue::Str(x) => info.push_str(x),
935			DoraValue::Object(x) => info.push_object(x),
936			DoraValue::Vec2(x) => info.push_vec2(&x),
937			DoraValue::Size(x) => info.push_size(&x),
938		}
939	}
940}
941
942impl<'a> IntoValue<'a> for i32 {
943	fn dora_val(self) -> DoraValue<'a> {
944		DoraValue::I32(self)
945	}
946	fn val(self) -> Value {
947		unsafe { Value { raw: value_create_i64(self as i64) } }
948	}
949}
950
951impl<'a> IntoValue<'a> for i64 {
952	fn dora_val(self) -> DoraValue<'a> {
953		DoraValue::I64(self)
954	}
955	fn val(self) -> Value {
956		unsafe { Value { raw: value_create_i64(self) } }
957	}
958}
959
960impl<'a> IntoValue<'a> for f32 {
961	fn dora_val(self) -> DoraValue<'a> {
962		DoraValue::F32(self)
963	}
964	fn val(self) -> Value {
965		unsafe { Value { raw: value_create_f64(self as f64) } }
966	}
967}
968
969impl<'a> IntoValue<'a> for f64 {
970	fn dora_val(self) -> DoraValue<'a> {
971		DoraValue::F64(self)
972	}
973	fn val(self) -> Value {
974		unsafe { Value { raw: value_create_f64(self) } }
975	}
976}
977
978impl<'a> IntoValue<'a> for bool {
979	fn dora_val(self) -> DoraValue<'a> {
980		DoraValue::Bool(self)
981	}
982	fn val(self) -> Value {
983		unsafe { Value { raw: value_create_bool(if self { 1 } else { 0 }) } }
984	}
985}
986
987impl<'a> IntoValue<'a> for &'a str {
988	fn dora_val(self) -> DoraValue<'a> {
989		DoraValue::Str(self)
990	}
991	fn val(self) -> Value {
992		unsafe { Value { raw: value_create_str(from_string(self)) } }
993	}
994}
995
996impl<'a> IntoValue<'a> for &'a dyn IObject {
997	fn dora_val(self) -> DoraValue<'a> {
998		DoraValue::Object(self)
999	}
1000	fn val(self) -> Value {
1001		unsafe { Value { raw: value_create_object(self.raw()) } }
1002	}
1003}
1004
1005impl<'a> IntoValue<'a> for Vec2 {
1006	fn dora_val(self) -> DoraValue<'a> {
1007		DoraValue::Vec2(self)
1008	}
1009	fn val(self) -> Value {
1010		unsafe { Value { raw: value_create_vec2(self.into_i64()) } }
1011	}
1012}
1013
1014impl<'a> IntoValue<'a> for Size {
1015	fn dora_val(self) -> DoraValue<'a> {
1016		DoraValue::Size(self)
1017	}
1018	fn val(self) -> Value {
1019		unsafe { Value { raw: value_create_size(self.into_i64()) } }
1020	}
1021}
1022
1023#[macro_export]
1024macro_rules! args {
1025	( $( $x:expr ),* ) => {
1026		{
1027			let mut stack = dora_ssr::CallStack::new();
1028			$(
1029				dora_ssr::Value::new($x).push(&mut stack);
1030			)*
1031			stack
1032		}
1033	};
1034}
1035
1036#[macro_export]
1037macro_rules! dora_object {
1038	($name: ident) => {
1039		paste::paste! {
1040			 impl IObject for $name {
1041				fn raw(&self) -> i64 { self.raw }
1042				fn obj(&self) -> &dyn IObject { self }
1043				fn as_any(&self) -> &dyn std::any::Any { self }
1044			}
1045			impl Drop for $name {
1046				fn drop(&mut self) { unsafe { crate::dora::object_release(self.raw); } }
1047			}
1048			impl Clone for $name {
1049				fn clone(&self) -> $name {
1050					unsafe { crate::dora::object_retain(self.raw); }
1051					$name { raw: self.raw }
1052				}
1053			}
1054			impl $name {
1055				#[allow(dead_code)]
1056				pub(crate) fn from(raw: i64) -> Option<$name> {
1057					match raw {
1058						0 => None,
1059						_ => Some($name { raw: raw })
1060					}
1061				}
1062			}
1063		}
1064	};
1065}
1066
1067// Value
1068
1069pub struct Value {
1070	raw: i64,
1071}
1072
1073impl Value {
1074	pub fn new<'a, A>(value: A) -> DoraValue<'a>
1075	where
1076		A: IntoValue<'a>,
1077	{
1078		value.dora_val()
1079	}
1080	fn from(raw: i64) -> Option<Value> {
1081		match raw {
1082			0 => None,
1083			_ => Some(Value { raw: raw }),
1084		}
1085	}
1086	pub fn raw(&self) -> i64 {
1087		self.raw
1088	}
1089	pub fn into_i32(&self) -> Option<i32> {
1090		unsafe {
1091			if value_is_i64(self.raw) != 0 {
1092				Some(value_into_i64(self.raw) as i32)
1093			} else {
1094				None
1095			}
1096		}
1097	}
1098	pub fn into_i64(&self) -> Option<i64> {
1099		unsafe {
1100			if value_is_i64(self.raw) != 0 {
1101				Some(value_into_i64(self.raw))
1102			} else {
1103				None
1104			}
1105		}
1106	}
1107	pub fn into_f32(&self) -> Option<f32> {
1108		unsafe {
1109			if value_is_f64(self.raw) != 0 {
1110				Some(value_into_f64(self.raw) as f32)
1111			} else {
1112				None
1113			}
1114		}
1115	}
1116	pub fn into_f64(&self) -> Option<f64> {
1117		unsafe {
1118			if value_is_f64(self.raw) != 0 {
1119				Some(value_into_f64(self.raw))
1120			} else {
1121				None
1122			}
1123		}
1124	}
1125	pub fn into_bool(&self) -> Option<bool> {
1126		unsafe {
1127			if value_is_bool(self.raw) != 0 {
1128				Some(value_into_bool(self.raw) != 0)
1129			} else {
1130				None
1131			}
1132		}
1133	}
1134	pub fn into_str(&self) -> Option<String> {
1135		unsafe {
1136			if value_is_str(self.raw) != 0 {
1137				Some(to_string(value_into_str(self.raw)))
1138			} else {
1139				None
1140			}
1141		}
1142	}
1143	pub fn into_object(&self) -> Option<Box<dyn IObject>> {
1144		unsafe {
1145			if value_is_object(self.raw) != 0 {
1146				into_object(value_into_object(self.raw))
1147			} else {
1148				None
1149			}
1150		}
1151	}
1152	pub fn into_node(&self) -> Option<Node> {
1153		Node::cast(self.into_object()?.as_ref())
1154	}
1155	pub fn into_camera(&self) -> Option<Camera> {
1156		Camera::cast(self.into_object()?.as_ref())
1157	}
1158	pub fn into_playable(&self) -> Option<Playable> {
1159		Playable::cast(self.into_object()?.as_ref())
1160	}
1161	pub fn into_physics_world(&self) -> Option<PhysicsWorld> {
1162		PhysicsWorld::cast(self.into_object()?.as_ref())
1163	}
1164	pub fn into_body(&self) -> Option<Body> {
1165		Body::cast(self.into_object()?.as_ref())
1166	}
1167	pub fn into_joint(&self) -> Option<Joint> {
1168		Joint::cast(self.into_object()?.as_ref())
1169	}
1170	pub fn into_vec2(&self) -> Option<Vec2> {
1171		unsafe {
1172			if value_is_vec2(self.raw) != 0 {
1173				Some(Vec2::from(value_into_vec2(self.raw)))
1174			} else {
1175				None
1176			}
1177		}
1178	}
1179	pub fn into_size(&self) -> Option<Size> {
1180		unsafe {
1181			if value_is_size(self.raw) != 0 {
1182				Some(Size::from(value_into_size(self.raw)))
1183			} else {
1184				None
1185			}
1186		}
1187	}
1188	pub fn cast<T: Clone + 'static>(&self) -> Option<T> {
1189		cast::<T>(self.into_object()?.as_ref())
1190	}
1191}
1192
1193impl Drop for Value {
1194	fn drop(&mut self) {
1195		unsafe {
1196			value_release(self.raw);
1197		}
1198	}
1199}
1200
1201// CallStack
1202
1203impl CallStack {
1204	fn raw(&self) -> i64 {
1205		self.raw
1206	}
1207	pub fn new() -> CallStack {
1208		CallStack { raw: unsafe { call_stack_create() } }
1209	}
1210	pub fn push_i32(&mut self, value: i32) {
1211		unsafe {
1212			call_stack_push_i64(self.raw, value as i64);
1213		}
1214	}
1215	pub fn push_i64(&mut self, value: i64) {
1216		unsafe {
1217			call_stack_push_i64(self.raw, value);
1218		}
1219	}
1220	pub fn push_f32(&mut self, value: f32) {
1221		unsafe {
1222			call_stack_push_f64(self.raw, value as f64);
1223		}
1224	}
1225	pub fn push_f64(&mut self, value: f64) {
1226		unsafe {
1227			call_stack_push_f64(self.raw, value);
1228		}
1229	}
1230	pub fn push_str(&mut self, value: &str) {
1231		unsafe {
1232			call_stack_push_str(self.raw, from_string(value));
1233		}
1234	}
1235	pub fn push_bool(&mut self, value: bool) {
1236		unsafe {
1237			call_stack_push_bool(self.raw, if value { 1 } else { 0 });
1238		}
1239	}
1240	pub fn push_object(&mut self, value: &dyn IObject) {
1241		unsafe {
1242			call_stack_push_object(self.raw, value.raw());
1243		}
1244	}
1245	pub fn push_vec2(&mut self, value: &Vec2) {
1246		unsafe {
1247			call_stack_push_vec2(self.raw, value.into_i64());
1248		}
1249	}
1250	pub fn push_size(&mut self, value: &Size) {
1251		unsafe {
1252			call_stack_push_size(self.raw, value.into_i64());
1253		}
1254	}
1255	/// Pops the value from the stack if it is a i32.
1256	pub fn pop_i32(&mut self) -> Option<i32> {
1257		unsafe {
1258			if call_stack_front_i64(self.raw) != 0 {
1259				Some(call_stack_pop_i64(self.raw) as i32)
1260			} else {
1261				None
1262			}
1263		}
1264	}
1265	/// Pops the value from the stack if it is a i64.
1266	pub fn pop_i64(&mut self) -> Option<i64> {
1267		unsafe {
1268			if call_stack_front_i64(self.raw) != 0 {
1269				Some(call_stack_pop_i64(self.raw))
1270			} else {
1271				None
1272			}
1273		}
1274	}
1275	/// Pops the value from the stack if it is a f32.
1276	pub fn pop_f32(&mut self) -> Option<f32> {
1277		unsafe {
1278			if call_stack_front_f64(self.raw) != 0 {
1279				Some(call_stack_pop_f64(self.raw) as f32)
1280			} else {
1281				None
1282			}
1283		}
1284	}
1285	/// Pops the value from the stack if it is a f64.
1286	pub fn pop_f64(&mut self) -> Option<f64> {
1287		unsafe {
1288			if call_stack_front_f64(self.raw) != 0 {
1289				Some(call_stack_pop_f64(self.raw))
1290			} else {
1291				None
1292			}
1293		}
1294	}
1295	/// Pops the value from the stack if it is a string.
1296	pub fn pop_str(&mut self) -> Option<String> {
1297		unsafe {
1298			if call_stack_front_str(self.raw) != 0 {
1299				Some(to_string(call_stack_pop_str(self.raw)))
1300			} else {
1301				None
1302			}
1303		}
1304	}
1305	/// Pops the value from the stack if it is a bool.
1306	pub fn pop_bool(&mut self) -> Option<bool> {
1307		unsafe {
1308			if call_stack_front_bool(self.raw) != 0 {
1309				Some(call_stack_pop_bool(self.raw) != 0)
1310			} else {
1311				None
1312			}
1313		}
1314	}
1315	/// Pops the value from the stack if it is a Vec2 object.
1316	pub fn pop_vec2(&mut self) -> Option<Vec2> {
1317		unsafe {
1318			if call_stack_front_vec2(self.raw) != 0 {
1319				Some(Vec2::from(call_stack_pop_vec2(self.raw)))
1320			} else {
1321				None
1322			}
1323		}
1324	}
1325	/// Pops the value from the stack if it is a Size object.
1326	pub fn pop_size(&mut self) -> Option<Size> {
1327		unsafe {
1328			if call_stack_front_size(self.raw) != 0 {
1329				Some(Size::from(call_stack_pop_size(self.raw)))
1330			} else {
1331				None
1332			}
1333		}
1334	}
1335	/// Pops the value from the stack if it is an object.
1336	pub fn pop_object(&mut self) -> Option<Box<dyn IObject>> {
1337		unsafe {
1338			if call_stack_front_object(self.raw) != 0 {
1339				let raw = call_stack_pop_object(self.raw);
1340				into_object(raw)
1341			} else {
1342				None
1343			}
1344		}
1345	}
1346	/// Pops the value from the stack and then converts it to a Node. If the value on the stack is not a object or the object can not be converted to a Node, this function returns None.
1347	/// This function is the same as `Node::cast(stack.pop_object()?.as_ref())`.
1348	pub fn pop_into_node(&mut self) -> Option<Node> {
1349		Node::cast(self.pop_object()?.as_ref())
1350	}
1351	/// Pops the value from the stack and then converts it to a Camera. If the value on the stack is not a object or the object can not be converted to a Camera, this function returns None.
1352	/// This function is the same as `Camera::cast(stack.pop_object()?.as_ref())`.
1353	pub fn pop_into_camera(&mut self) -> Option<Camera> {
1354		Camera::cast(self.pop_object()?.as_ref())
1355	}
1356	/// Pops the value from the stack and then converts it to a Playable. If the value on the stack is not a object or the object can not be converted to a Playable, this function returns None.
1357	/// This function is the same as `Playable::cast(stack.pop_object()?.as_ref())`.
1358	pub fn pop_into_playable(&mut self) -> Option<Playable> {
1359		Playable::cast(self.pop_object()?.as_ref())
1360	}
1361	/// Pops the value from the stack and then converts it to a PhysicsWorld. If the value on the stack is not a object or the object can not be converted to a PhysicsWorld, this function returns None.
1362	/// This function is the same as `PhysicsWorld::cast(stack.pop_object()?.as_ref())`.
1363	pub fn pop_into_physics_world(&mut self) -> Option<PhysicsWorld> {
1364		PhysicsWorld::cast(self.pop_object()?.as_ref())
1365	}
1366	/// Pops the value from the stack and then converts it to a Body. If the value on the stack is not a object or the object can not be converted to a Body, this function returns None.
1367	/// This function is the same as `Body::cast(stack.pop_object()?.as_ref())`.
1368	pub fn pop_into_body(&mut self) -> Option<Body> {
1369		Body::cast(self.pop_object()?.as_ref())
1370	}
1371	/// Pops the value from the stack and then converts it to a Joint. If the value on the stack is not a object or the object can not be converted to a Joint, this function returns None.
1372	/// This function is the same as `Joint::cast(stack.pop_object()?.as_ref())`.
1373	pub fn pop_into_joint(&mut self) -> Option<Joint> {
1374		Joint::cast(self.pop_object()?.as_ref())
1375	}
1376	/// Pops a value from the stack and then casts it to the specified type. If the value on the stack is not a object or can not be casted, it returns None.
1377	/// This function is the same as `cast::<T>(stack.pop_object()?.as_ref())`.
1378	pub fn pop_cast<T: Clone + 'static>(&mut self) -> Option<T> {
1379		cast::<T>(self.pop_object()?.as_ref())
1380	}
1381	/// Pops a value from the stack.
1382	/// Returns true if a value was popped, otherwise false.
1383	pub fn pop(&mut self) -> bool {
1384		if unsafe { call_stack_pop(self.raw) } == 0 {
1385			return false;
1386		}
1387		true
1388	}
1389}
1390
1391impl Drop for CallStack {
1392	fn drop(&mut self) {
1393		unsafe {
1394			call_stack_release(self.raw);
1395		}
1396	}
1397}
1398
1399/// An interface for providing Dora SSR built-in node event names.
1400pub struct Slot {}
1401impl Slot {
1402	/// The ActionEnd slot is triggered when an action is finished.
1403	/// Triggers after calling `node.run_action()`, `node.perform()`, `node.run_action_def()` and `node.perform_def()`.
1404	///
1405	/// # Callback Arguments
1406	///
1407	/// * action: Action - The finished action.
1408	/// * target: Node - The node that finished the action.
1409	///
1410	/// # Callback Example
1411	///
1412	/// ```
1413	/// node.perform_def(ActionDef::prop(1.0, 0.0, 100.0, Property::X, EaseType::Linear));
1414	/// node.slot(Slot::ACTION_END, Box::new(|stack| {
1415	/// 	let (
1416	/// 		action,
1417	/// 		node
1418	/// 	) = match (
1419	/// 		stack.pop_cast::<Action>(),
1420	/// 		stack.pop_into_node()
1421	/// 	) {
1422	/// 		(Some(action), Some(node)) => (action, node),
1423	/// 		_ => return,
1424	/// 	};
1425	/// }));
1426	/// ```
1427	pub const ACTION_END: &'static str = "Action";
1428	/// The TapFilter slot is triggered before the TapBegan slot and can be used to filter out certain taps.
1429	/// Triggers after setting `node.set_touch_enabled(true)`.
1430	///
1431	/// # Callback Arguments
1432	///
1433	/// * touch: Touch - The touch that triggered the tap.
1434	///
1435	/// # Callback Example
1436	///
1437	/// ```
1438	/// node.set_touch_enabled(true);
1439	/// node.slot(Slot::TAP_FILTER, Box::new(|stack| {
1440	/// 	let touch = match stack.pop_cast::<Touch>() {
1441	/// 		Some(touch) => touch,
1442	/// 		None => return,
1443	/// 	};
1444	/// 	touch.set_enabled(false);
1445	/// }));
1446	/// ```
1447	pub const TAP_FILTER: &'static str = "TapFilter";
1448	/// The TapBegan slot is triggered when a tap is detected.
1449	/// Triggers after setting `node.set_touch_enabled(true)`.
1450	///
1451	/// # Callback Arguments
1452	///
1453	/// * touch: Touch - The touch that triggered the tap.
1454	///
1455	/// # Callback Example
1456	///
1457	/// ```
1458	/// node.set_touch_enabled(true);
1459	/// node.slot(Slot::TAP_BEGAN, Box::new(|stack| {
1460	/// 	let touch = match stack.pop_cast::<Touch>() {
1461	/// 		Some(touch) => touch,
1462	/// 		None => return,
1463	/// 	};
1464	/// }));
1465	/// ```
1466	pub const TAP_BEGAN: &'static str = "TapBegan";
1467	/// The TapEnded slot is triggered when a tap ends.
1468	/// Triggers after setting `node.set_touch_enabled(true)`.
1469	///
1470	/// # Callback Arguments
1471	///
1472	/// * touch: Touch - The touch that triggered the tap.
1473	///
1474	/// # Callback Example
1475	///
1476	/// ```
1477	/// node.set_touch_enabled(true);
1478	/// node.slot(Slot::TAP_ENDED, Box::new(|stack| {
1479	/// 	let touch = match stack.pop_cast::<Touch>() {
1480	/// 		Some(touch) => touch,
1481	/// 		None => return,
1482	/// 	};
1483	/// }));
1484	/// ```
1485	pub const TAP_ENDED: &'static str = "TapEnded";
1486	/// The Tapped slot is triggered when a tap is detected and has ended.
1487	/// Triggers after setting `node.set_touch_enabled(true)`.
1488	///
1489	/// # Callback Arguments
1490	///
1491	/// * touch: Touch - The touch that triggered the tap.
1492	///
1493	/// # Callback Example
1494	///
1495	/// ```
1496	/// node.set_touch_enabled(true);
1497	/// node.slot(Slot::TAPPED, Box::new(|stack| {
1498	/// 	let touch = match stack.pop_cast::<Touch>() {
1499	/// 		Some(touch) => touch,
1500	/// 		None => return,
1501	/// 	};
1502	/// }));
1503	/// ```
1504	pub const TAPPED: &'static str = "Tapped";
1505	/// The TapMoved slot is triggered when a tap moves.
1506	/// Triggers after setting `node.set_touch_enabled(true)`.
1507	///
1508	/// # Callback Arguments
1509	///
1510	/// * touch: Touch - The touch that triggered the tap.
1511	///
1512	/// # Callback Example
1513	///
1514	/// ```
1515	/// node.set_touch_enabled(true);
1516	/// node.slot(Slot::TAP_MOVED, Box::new(|stack| {
1517	/// 	let touch = match stack.pop_cast::<Touch>() {
1518	/// 		Some(touch) => touch,
1519	/// 		None => return,
1520	/// 	};
1521	/// }));
1522	/// ```
1523	pub const TAP_MOVED: &'static str = "TapMoved";
1524	/// The MouseWheel slot is triggered when the mouse wheel is scrolled.
1525	/// Triggers after setting `node.set_touch_enabled(true)`.
1526	///
1527	/// # Callback Arguments
1528	///
1529	/// * delta: Vec2 - The amount of scrolling that occurred.
1530	///
1531	/// # Callback Example
1532	///
1533	/// ```
1534	/// node.set_touch_enabled(true);
1535	/// node.slot(Slot::MOUSE_WHEEL, Box::new(|stack| {
1536	/// 	let delta = match stack.pop_vec2() {
1537	/// 		Some(delta) => delta,
1538	/// 		None => return,
1539	/// 	};
1540	/// }));
1541	/// ```
1542	pub const MOUSE_WHEEL: &'static str = "MouseWheel";
1543	/// The Gesture slot is triggered when a gesture is recognized.
1544	///
1545	/// # Callback Arguments
1546	///
1547	/// * center: Vec2 - The center of the gesture.
1548	/// * num_fingers: i32 - The number of fingers involved in the gesture.
1549	/// * delta_dist: f32 - The distance the gesture has moved.
1550	/// * delta_angle: f32 - The angle of the gesture.
1551	///
1552	/// # Callback Example
1553	///
1554	/// ```
1555	/// node.set_touch_enabled(true);
1556	/// node.slot(Slot::GESTURE, Box::new(|stack| {
1557	/// 	let (
1558	/// 		center,
1559	/// 		num_fingers,
1560	/// 		delta_dist,
1561	/// 		delta_angle
1562	/// 	) = match (
1563	/// 		stack.pop_vec2(),
1564	/// 		stack.pop_i32(),
1565	/// 		stack.pop_f32(),
1566	/// 		stack.pop_f32()
1567	/// 	) {
1568	/// 		(Some(center), Some(num_fingers), Some(delta_dist), Some(delta_angle)) => (center, num_fingers, delta_dist, delta_angle),
1569	/// 		_ => return,
1570	/// 	};
1571	/// }));
1572	/// ```
1573	pub const GESTURE: &'static str = "Gesture";
1574	/// The Enter slot is triggered when a node is added to the scene graph.
1575	/// Triggers when doing `node.add_child()`.
1576	pub const ENTER: &'static str = "Enter";
1577	/// The Exit slot is triggered when a node is removed from the scene graph.
1578	/// Triggers when doing `node.remove_child()`.
1579	pub const EXIT: &'static str = "Exit";
1580	/// The Cleanup slot is triggered when a node is cleaned up.
1581	/// Triggers only when doing `parent.remove_child(node, true)`.
1582	pub const CLEANUP: &'static str = "Cleanup";
1583	/// The KeyDown slot is triggered when a key is pressed down.
1584	/// Triggers after setting `node.set_keyboard_enabled(true)`.
1585	///
1586	/// # Callback Arguments
1587	///
1588	/// * key_name: String - The name of the key that was pressed.
1589	///
1590	/// # Callback Example
1591	///
1592	/// ```
1593	/// node.set_keyboard_enabled(true);
1594	/// node.slot(Slot::KEY_DOWN, Box::new(|stack| {
1595	/// 	let key_name = match stack.pop_str() {
1596	/// 		Some(key_name) => key_name,
1597	/// 		None => return,
1598	/// 	};
1599	/// 	if key_name == KeyName::Space.as_ref() {
1600	/// 		p!("Space key down!");
1601	/// 	}
1602	/// }));
1603	/// ```
1604	pub const KEY_DOWN: &'static str = "KeyDown";
1605	/// The KeyUp slot is triggered when a key is released.
1606	/// Triggers after setting `node.set_keyboard_enabled(true)`.
1607	///
1608	/// # Callback Arguments
1609	///
1610	/// * key_name: String - The name of the key that was released.
1611	///
1612	/// # Callback Example
1613	///
1614	/// ```
1615	/// node.set_keyboard_enabled(true);
1616	/// node.slot(Slot::KEY_UP, Box::new(|stack| {
1617	/// 	let key_name = match stack.pop_str() {
1618	/// 		Some(key_name) => key_name,
1619	/// 		None => return,
1620	/// 	};
1621	/// 	if key_name == KeyName::Space.as_ref() {
1622	/// 		p!("Space key up!");
1623	/// 	}
1624	/// }));
1625	/// ```
1626	pub const KEY_UP: &'static str = "KeyUp";
1627	/// The KeyPressed slot is triggered when a key is pressed.
1628	/// Triggers after setting `node.set_keyboard_enabled(true)`.
1629	///
1630	/// # Callback Arguments
1631	///
1632	/// * key_name: String - The name of the key that was pressed.
1633	///
1634	/// # Callback Example
1635	///
1636	/// ```
1637	/// node.set_keyboard_enabled(true);
1638	/// node.slot(Slot::KEY_PRESSED, Box::new(|stack| {
1639	/// 	let key_name = match stack.pop_str() {
1640	/// 		Some(key_name) => key_name,
1641	/// 		None => return,
1642	/// 	};
1643	/// 	if key_name == KeyName::Space.as_ref() {
1644	/// 		p!("Space key pressed!");
1645	/// 	}
1646	/// }));
1647	/// ```
1648	pub const KEY_PRESSED: &'static str = "KeyPressed";
1649	/// The AttachIME slot is triggered when the input method editor (IME) is attached (calling `node.attach_ime()`).
1650	pub const ATTACH_IME: &'static str = "AttachIME";
1651	/// The DetachIME slot is triggered when the input method editor (IME) is detached (calling `node.detach_ime()` or manually closing IME).
1652	pub const DETACH_IME: &'static str = "DetachIME";
1653	/// The TextInput slot is triggered when text input is received.
1654	/// Triggers after calling `node.attach_ime()`.
1655	///
1656	/// # Callback Arguments
1657	///
1658	/// * text: String - The text that was input.
1659	///
1660	/// # Callback Example
1661	///
1662	/// ```
1663	/// node.attach_ime();
1664	/// node.slot(Slot::TEXT_INPUT, Box::new(|stack| {
1665	/// 	let text = match stack.pop_str() {
1666	/// 		Some(text) => text,
1667	/// 		None => return,
1668	/// 	};
1669	/// 	p!(text);
1670	/// }));
1671	/// ```
1672	pub const TEXT_INPUT: &'static str = "TextInput";
1673	/// The TextEditing slot is triggered when text is being edited.
1674	/// Triggers after calling `node.attach_ime()`.
1675	///
1676	/// # Callback Arguments
1677	///
1678	/// * text: String - The text that is being edited.
1679	/// * start_pos: i32 - The starting position of the text being edited.
1680	///
1681	/// # Callback Example
1682	///
1683	/// ```
1684	/// node.attach_ime();
1685	/// node.slot(Slot::TEXT_EDITING, Box::new(|stack| {
1686	/// 	let (
1687	/// 		text,
1688	/// 		start_pos
1689	/// 	) = match (
1690	/// 		stack.pop_str(),
1691	/// 		stack.pop_i32()
1692	/// 	) {
1693	/// 		(Some(text), Some(start_pos)) => (text, start_pos),
1694	/// 		_ => return,
1695	/// 	};
1696	/// 	p!(text, start_pos);
1697	/// }));
1698	/// ```
1699	pub const TEXT_EDITING: &'static str = "TextEditing";
1700	/// The ButtonDown slot is triggered when a game controller button is pressed down.
1701	/// Triggers after setting `node.set_controller_enabled(true)`.
1702	///
1703	/// # Callback Arguments
1704	///
1705	/// * controller_id: i32 - The controller id, incrementing from 0 when multiple controllers connected.
1706	/// * button_name: String - The name of the button that was pressed.
1707	///
1708	/// # Callback Example
1709	///
1710	/// ```
1711	/// node.set_controller_enabled(true);
1712	/// node.slot(Slot::BUTTON_DOWN, Box::new(|stack| {
1713	/// 	let (
1714	/// 		controller_id,
1715	/// 		button_name
1716	/// 	) = match (
1717	/// 		stack.pop_i32(),
1718	/// 		stack.pop_str()
1719	/// 	) {
1720	/// 		(Some(controller_id), Some(button_name)) => (controller_id, button_name),
1721	/// 		_ => return,
1722	/// 	};
1723	/// 	if controller_id == 0 && button_name == ButtonName::DPUp.as_ref() {
1724	/// 		p!("DPad up button down!");
1725	/// 	}
1726	/// }));
1727	/// ```
1728	pub const BUTTON_DOWN: &'static str = "ButtonDown";
1729	/// The ButtonUp slot is triggered when a game controller button is released.
1730	/// Triggers after setting `node.set_controller_enabled(true)`.
1731	///
1732	/// # Callback Arguments
1733	///
1734	/// * controller_id: i32 - The controller id, incrementing from 0 when multiple controllers connected.
1735	/// * button_name: String - The name of the button that was released.
1736	///
1737	/// # Callback Example
1738	///
1739	/// ```
1740	/// node.set_controller_enabled(true);
1741	/// node.slot(Slot::BUTTON_UP, Box::new(|stack| {
1742	/// 	let (
1743	/// 		controller_id,
1744	/// 		button_name
1745	/// 	) = match (
1746	/// 		stack.pop_i32(),
1747	/// 		stack.pop_str()
1748	/// 	) {
1749	/// 		(Some(controller_id), Some(button_name)) => (controller_id, button_name),
1750	/// 		_ => return,
1751	/// 	};
1752	/// 	if controller_id == 0 && button_name == ButtonName::DPUp.as_ref() {
1753	/// 		p!("DPad up button up!");
1754	/// 	}
1755	/// }));
1756	/// ```
1757	pub const BUTTON_UP: &'static str = "ButtonUp";
1758	/// The ButtonPressed slot is triggered when a game controller button is being pressed.
1759	/// Triggers after setting `node.set_controller_enabled(true)`.
1760	/// This slot is triggered every frame while the button is being pressed.
1761	///
1762	/// # Callback Arguments
1763	///
1764	/// * controller_id: i32 - The controller id, incrementing from 0 when multiple controllers connected.
1765	/// * button_name: String - The name of the button that is being pressed.
1766	///
1767	/// # Callback Example
1768	///
1769	/// ```
1770	/// node.set_controller_enabled(true);
1771	/// node.slot(Slot::BUTTON_PRESSED, Box::new(|stack| {
1772	/// 	let (
1773	/// 		controller_id,
1774	/// 		button_name
1775	/// 	) = match (
1776	/// 		stack.pop_i32(),
1777	/// 		stack.pop_str()
1778	/// 	) {
1779	/// 		(Some(controller_id), Some(button_name)) => (controller_id, button_name),
1780	/// 		_ => return,
1781	/// 	};
1782	/// 	if controller_id == 0 && button_name == ButtonName::DPUp.as_ref() {
1783	/// 		p!("DPad up button pressed!");
1784	/// 	}
1785	/// }));
1786	/// ```
1787	pub const BUTTON_PRESSED: &'static str = "ButtonPressed";
1788	/// The Axis slot is triggered when a game controller axis changed.
1789	/// Triggers after setting `node.set_controller_enabled(true)`.
1790	///
1791	/// # Callback Arguments
1792	///
1793	/// * controllerId: i32 - The controller id, incrementing from 0 when multiple controllers connected.
1794	/// * axis_name: String - The name of the axis that changed.
1795	/// * axis_value: f32 - The controller axis value ranging from -1.0 to 1.0.
1796	///
1797	/// # Callback Example
1798	///
1799	/// ```
1800	/// node.set_controller_enabled(true);
1801	/// node.slot(Slot::AXIS, Box::new(|stack| {
1802	/// 	let (
1803	/// 		controller_id,
1804	/// 		axis_name,
1805	/// 		axis_value
1806	/// 	) = match (
1807	/// 		stack.pop_i32(),
1808	/// 		stack.pop_str(),
1809	/// 		stack.pop_f32()
1810	/// 	) {
1811	/// 		(Some(controller_id), Some(axis_name), Some(axis_value)) => (controller_id, axis_name, axis_value),
1812	/// 		_ => return,
1813	/// 	};
1814	/// 	if controller_id == 0 && axis_name == AxisName::LeftX.as_ref() {
1815	/// 		p!("Left stick x value {}", axis_value);
1816	/// 	}
1817	/// }));
1818	pub const AXIS: &'static str = "Axis";
1819	/// Triggers after an animation has ended on a Playable instance.
1820	///
1821	/// # Callback Arguments
1822	///
1823	/// * animation_name: String - The name of the animation that ended.
1824	/// * target: Playable - The Playable instance that the animation was played on.
1825	///
1826	/// # Callback Example
1827	///
1828	/// ```
1829	/// playable.play("Walk", false);
1830	/// playable.slot(Slot::ANIMATION_END, Box::new(|stack| {
1831	/// 	let (
1832	/// 		animation_name,
1833	/// 		playable
1834	/// 	) = match (
1835	/// 		stack.pop_str(),
1836	/// 		stack.pop_into_playable()
1837	/// 	) {
1838	/// 		(Some(animation_name), Some(playable)) => (animation_name, playable),
1839	/// 		_ => return,
1840	/// 	};
1841	/// 	if animation_name == "Walk" {
1842	/// 		playable.play("Idle", true);
1843	/// 	}
1844	/// }));
1845	/// ```
1846	pub const ANIMATION_END: &'static str = "AnimationEnd";
1847	/// Triggers when a Body object collides with a sensor object.
1848	/// Triggers when `Body` was attached with sensors.
1849	///
1850	/// # Callback Arguments
1851	///
1852	/// * other: Body - The other Body object that the current Body is colliding with.
1853	/// * sensorTag: i32 - The tag of the sensor that triggered this collision.
1854	///
1855	/// # Callback Example
1856	///
1857	/// ```
1858	/// body.slot(Slot::BODY_ENTER, Box::new(|stack| {
1859	/// 	let (
1860	/// 		other,
1861	/// 		sensor_tag
1862	/// 	) = match (
1863	/// 		stack.pop_into_body(),
1864	/// 		stack.pop_i32()
1865	/// 	) {
1866	/// 		(Some(other), Some(sensor_tag)) => (other, sensor_tag),
1867	/// 		_ => return,
1868	/// 	};
1869	/// 	p!(sensor_tag);
1870	/// }));
1871	/// ```
1872	pub const BODY_ENTER: &'static str = "BodyEnter";
1873	/// Triggers when a `Body` object is no longer colliding with a sensor object.
1874	/// Triggers when `Body` was attached with sensors.
1875	///
1876	/// # Callback Arguments
1877	///
1878	/// * other: Body - The other `Body` object that the current `Body` is no longer colliding with.
1879	/// * sensor_tag: i32 - The tag of the sensor that triggered this collision.
1880	///
1881	/// # Callback Example
1882	///
1883	/// ```
1884	/// body.slot(Slot::BODY_LEAVE, Box::new(|stack| {
1885	/// 	let (
1886	/// 		other,
1887	/// 		sensor_tag
1888	/// 	) = match (
1889	/// 		stack.pop_into_body(),
1890	/// 		stack.pop_i32()
1891	/// 	) {
1892	/// 		(Some(other), Some(sensor_tag)) => (other, sensor_tag),
1893	/// 		_ => return,
1894	/// 	};
1895	/// 	p!(sensor_tag);
1896	/// }));
1897	/// ```
1898	pub const BODY_LEAVE: &'static str = "BodyLeave";
1899	/// Triggers when a `Body` object starts to collide with another object.
1900	/// Triggers after setting `body.set_receiving_contact(true)`.
1901	///
1902	/// # Callback Arguments
1903	///
1904	/// * other: Body - The other `Body` object that the current `Body` is colliding with.
1905	/// * point: Vec2 - The point of collision in world coordinates.
1906	/// * normal: Vec2 - The normal vector of the contact surface in world coordinates.
1907	/// * enabled: bool - Whether the contact is enabled or not. Collisions that are filtered out will still trigger this event, but the enabled state will be false.
1908	///
1909	/// # Callback Example
1910	///
1911	/// ```
1912	/// body.set_receiving_contact(true);
1913	/// body.slot(Slot::CONTACT_START, Box::new(|stack| {
1914	/// 	let (
1915	/// 		other,
1916	/// 		point,
1917	/// 		normal,
1918	/// 		enabled
1919	/// 	) = match (
1920	/// 		stack.pop_into_body(),
1921	/// 		stack.pop_vec2(),
1922	/// 		stack.pop_vec2(),
1923	/// 		stack.pop_bool()
1924	/// 	) {
1925	/// 		(Some(other), Some(point), Some(normal), Some(enabled)) => (other, point, normal, enabled),
1926	/// 		_ => return,
1927	/// 	};
1928	/// }));
1929	/// ```
1930	pub const CONTACT_START: &'static str = "ContactStart";
1931	/// Triggers when a `Body` object stops colliding with another object.
1932	/// Triggers after setting `body.set_receiving_contact(true)`.
1933	///
1934	/// # Callback Arguments
1935	///
1936	/// * other: Body - The other `Body` object that the current `Body` is no longer colliding with.
1937	/// * point: Vec2 - The point of collision in world coordinates.
1938	/// * normal: Vec2 - The normal vector of the contact surface in world coordinates.
1939	///
1940	/// # Callback Example
1941	///
1942	/// ```
1943	/// body.set_receiving_contact(true);
1944	/// body.slot(Slot::CONTACT_END, Box::new(|stack| {
1945	/// 	let (
1946	/// 		other,
1947	/// 		point,
1948	/// 		normal
1949	/// 	) = match (
1950	/// 		stack.pop_into_body(),
1951	/// 		stack.pop_vec2(),
1952	/// 		stack.pop_vec2()
1953	/// 	) {
1954	/// 		(Some(other), Some(point), Some(normal)) => (other, point, normal),
1955	/// 		_ => return,
1956	/// 	};
1957	/// }));
1958	/// ```
1959	pub const CONTACT_END: &'static str = "ContactEnd";
1960	/// Triggered after a `Particle` node started a stop action and then all the active particles end their lives.
1961	pub const FINISHED: &'static str = "Finished";
1962	/// Triggers when the layout of the `AlignNode` is updated.
1963	///
1964	/// # Callback Arguments
1965	///
1966	/// * width: f32 - The width of the `AlignNode`.
1967	/// * height: f32 - The height of the `AlignNode`.
1968	///
1969	/// # Callback Example
1970	///
1971	/// ```
1972	/// align_node.slot(Slot::ALIGN_LAYOUT, Box::new(|stack| {
1973	/// 	let (
1974	/// 		width,
1975	/// 		height
1976	/// 	) = match (
1977	/// 		stack.pop_f32(),
1978	/// 		stack.pop_f32()
1979	/// 	) {
1980	/// 		(Some(width), Some(height)) => (width, height),
1981	/// 		_ => return,
1982	/// 	};
1983	/// 	p!("width: {}, height: {}", width, height);
1984	/// }));
1985	/// ```
1986	pub const ALIGN_LAYOUT: &'static str = "AlignLayout";
1987	/// Triggers when the `EffekseerNode` finishes playing an effect.
1988	///
1989	/// # Callback Arguments
1990	///
1991	/// * handle: i32 - The handle of the effect that finished playing.
1992	///
1993	/// # Callback Example
1994	///
1995	/// ```
1996	/// effekseer_node.slot(Slot::EFFEK_END, Box::new(|stack| {
1997	/// 	let handle = match stack.pop_i32() {
1998	/// 		Some(handle) => handle,
1999	/// 		None => return,
2000	/// 	};
2001	/// 	p!("Effect handle: {}", handle);
2002	/// }));
2003	/// ```
2004	pub const EFFEK_END: &'static str = "EffekEnd";
2005	/// Registers a callback for event triggered when an action is finished.
2006	///
2007	/// # Arguments
2008	///
2009	/// * node: &mut dyn INode - The node to register the callback on.
2010	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2011	/// 	* action: Action - The finished action.
2012	/// 	* target: Node - The node that finished the action.
2013	pub fn on_action_end<F>(node: &mut dyn INode, mut callback: F)
2014	where
2015		F: FnMut(/*action*/ Action, /*node*/ Node) + 'static,
2016	{
2017		node.slot(
2018			Slot::ACTION_END,
2019			Box::new(move |stack| {
2020				let (action, node) = match (stack.pop_cast::<Action>(), stack.pop_into_node()) {
2021					(Some(action), Some(node)) => (action, node),
2022					_ => return,
2023				};
2024				callback(action, node);
2025			}),
2026		);
2027	}
2028	/// Registers a callback for event triggered when a tap is detected and can be used to filter out certain taps.
2029	///
2030	/// # Arguments
2031	///
2032	/// * node: &mut dyn INode - The node to register the callback on.
2033	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2034	/// 	* touch: Touch - The touch that triggered the tap.
2035	pub fn on_tap_filter<F>(node: &mut dyn INode, mut callback: F)
2036	where
2037		F: FnMut(/*touch*/ Touch) + 'static,
2038	{
2039		node.set_touch_enabled(true);
2040		node.slot(
2041			Slot::TAP_FILTER,
2042			Box::new(move |stack| {
2043				let touch = match stack.pop_cast::<Touch>() {
2044					Some(touch) => touch,
2045					None => return,
2046				};
2047				callback(touch);
2048			}),
2049		);
2050	}
2051	/// Registers a callback for event triggered when a tap is detected.
2052	///
2053	/// # Arguments
2054	///
2055	/// * node: &mut dyn INode - The node to register the callback on.
2056	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2057	/// 	* touch: Touch - The touch that triggered the tap.
2058	pub fn on_tap_began<F>(node: &mut dyn INode, mut callback: F)
2059	where
2060		F: FnMut(/*touch*/ Touch) + 'static,
2061	{
2062		node.set_touch_enabled(true);
2063		node.slot(
2064			Slot::TAP_BEGAN,
2065			Box::new(move |stack| {
2066				let touch = match stack.pop_cast::<Touch>() {
2067					Some(touch) => touch,
2068					None => return,
2069				};
2070				callback(touch);
2071			}),
2072		);
2073	}
2074	/// Registers a callback for event triggered when a tap ends.
2075	///
2076	/// # Arguments
2077	///
2078	/// * node: &mut dyn INode - The node to register the callback on.
2079	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2080	/// 	* touch: Touch - The touch that triggered the tap.
2081	pub fn on_tap_ended<F>(node: &mut dyn INode, mut callback: F)
2082	where
2083		F: FnMut(/*touch*/ Touch) + 'static,
2084	{
2085		node.set_touch_enabled(true);
2086		node.slot(
2087			Slot::TAP_ENDED,
2088			Box::new(move |stack| {
2089				let touch = match stack.pop_cast::<Touch>() {
2090					Some(touch) => touch,
2091					None => return,
2092				};
2093				callback(touch);
2094			}),
2095		);
2096	}
2097	/// Registers a callback for event triggered when a tap is detected and has ended.
2098	///
2099	/// # Arguments
2100	///
2101	/// * node: &mut dyn INode - The node to register the callback on.
2102	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2103	/// 	* touch: Touch - The touch that triggered the tap.
2104	pub fn on_tapped<F>(node: &mut dyn INode, mut callback: F)
2105	where
2106		F: FnMut(/*touch*/ Touch) + 'static,
2107	{
2108		node.set_touch_enabled(true);
2109		node.slot(
2110			Slot::TAPPED,
2111			Box::new(move |stack| {
2112				let touch = match stack.pop_cast::<Touch>() {
2113					Some(touch) => touch,
2114					None => return,
2115				};
2116				callback(touch);
2117			}),
2118		);
2119	}
2120	/// Registers a callback for event triggered when a tap moves.
2121	///
2122	/// # Arguments
2123	///
2124	/// * node: &mut dyn INode - The node to register the callback on.
2125	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2126	/// 	* touch: Touch - The touch that triggered the tap.
2127	pub fn on_tap_moved<F>(node: &mut dyn INode, mut callback: F)
2128	where
2129		F: FnMut(/*touch*/ Touch) + 'static,
2130	{
2131		node.set_touch_enabled(true);
2132		node.slot(
2133			Slot::TAP_MOVED,
2134			Box::new(move |stack| {
2135				let touch = match stack.pop_cast::<Touch>() {
2136					Some(touch) => touch,
2137					None => return,
2138				};
2139				callback(touch);
2140			}),
2141		);
2142	}
2143	/// Registers a callback for event triggered when the mouse wheel is scrolled.
2144	///
2145	/// # Arguments
2146	///
2147	/// * node: &mut dyn INode - The node to register the callback on.
2148	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2149	/// 	* delta: Vec2 - The amount of scrolling that occurred.
2150	pub fn on_mouse_wheel<F>(node: &mut dyn INode, mut callback: F)
2151	where
2152		F: FnMut(/*delta*/ Vec2) + 'static,
2153	{
2154		node.set_touch_enabled(true);
2155		node.slot(
2156			Slot::MOUSE_WHEEL,
2157			Box::new(move |stack| {
2158				let delta = match stack.pop_vec2() {
2159					Some(delta) => delta,
2160					None => return,
2161				};
2162				callback(delta);
2163			}),
2164		);
2165	}
2166	/// Registers a callback for event triggered when a multi-touch gesture is recognized.
2167	///
2168	/// # Arguments
2169	///
2170	/// * node: &mut dyn INode - The node to register the callback on.
2171	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2172	/// 	* center: Vec2 - The center of the gesture.
2173	/// 	* num_fingers: i32 - The number of fingers involved in the gesture.
2174	/// 	* delta_dist: f32 - The distance the gesture has moved.
2175	/// 	* delta_angle: f32 - The angle of the gesture.
2176	pub fn on_gesture<F>(node: &mut dyn INode, mut callback: F)
2177	where
2178		F: FnMut(
2179				/*center*/ Vec2,
2180				/*num_fingers*/ i32,
2181				/*delta_dist*/ f32,
2182				/*delta_angle*/ f32,
2183			) + 'static,
2184	{
2185		node.set_touch_enabled(true);
2186		node.slot(
2187			Slot::GESTURE,
2188			Box::new(move |stack| {
2189				let (center, num_fingers, delta_dist, delta_angle) =
2190					match (stack.pop_vec2(), stack.pop_i32(), stack.pop_f32(), stack.pop_f32()) {
2191						(Some(center), Some(num_fingers), Some(delta_dist), Some(delta_angle)) => {
2192							(center, num_fingers, delta_dist, delta_angle)
2193						}
2194						_ => return,
2195					};
2196				callback(center, num_fingers, delta_dist, delta_angle);
2197			}),
2198		);
2199	}
2200	/// Registers a callback for event triggered when a node is added to the scene graph.
2201	///
2202	/// # Arguments
2203	///
2204	/// * node: &mut dyn INode - The node to register the callback on.
2205	/// * callback: F - The callback to be called when the event is triggered.
2206	pub fn on_enter<F>(node: &mut dyn INode, mut callback: F)
2207	where
2208		F: FnMut() + 'static,
2209	{
2210		node.slot(
2211			Slot::ENTER,
2212			Box::new(move |_| {
2213				callback();
2214			}),
2215		);
2216	}
2217	/// Registers a callback for event triggered when a node is removed from the scene graph.
2218	///
2219	/// # Arguments
2220	///
2221	/// * node: &mut dyn INode - The node to register the callback on.
2222	/// * callback: F - The callback to be called when the event is triggered.
2223	pub fn on_exit<F>(node: &mut dyn INode, mut callback: F)
2224	where
2225		F: FnMut() + 'static,
2226	{
2227		node.slot(
2228			Slot::EXIT,
2229			Box::new(move |_| {
2230				callback();
2231			}),
2232		);
2233	}
2234	/// Registers a callback for event triggered when a node is cleaned up.
2235	///
2236	/// # Arguments
2237	///
2238	/// * node: &mut dyn INode - The node to register the callback on.
2239	/// * callback: F - The callback to be called when the event is triggered.
2240	pub fn on_cleanup<F>(node: &mut dyn INode, mut callback: F)
2241	where
2242		F: FnMut() + 'static,
2243	{
2244		node.slot(
2245			Slot::CLEANUP,
2246			Box::new(move |_| {
2247				callback();
2248			}),
2249		);
2250	}
2251	/// Registers a callback for event triggered when a key is pressed down.
2252	///
2253	/// # Arguments
2254	///
2255	/// * node: &mut dyn INode - The node to register the callback on.
2256	/// * key: KeyName - The key to trigger the callback on.
2257	/// * callback: F - The callback to be called when the event is triggered.
2258	pub fn on_key_down<F>(node: &mut dyn INode, key: KeyName, mut callback: F)
2259	where
2260		F: FnMut() + 'static,
2261	{
2262		node.set_keyboard_enabled(true);
2263		node.slot(
2264			Slot::KEY_DOWN,
2265			Box::new(move |stack| {
2266				let key_name = match stack.pop_str() {
2267					Some(key_name) => key_name,
2268					None => return,
2269				};
2270				if key.as_ref() == key_name {
2271					callback();
2272				}
2273			}),
2274		);
2275	}
2276	/// Registers a callback for event triggered when a key is released.
2277	///
2278	/// # Arguments
2279	///
2280	/// * node: &mut dyn INode - The node to register the callback on.
2281	/// * key: KeyName - The key to trigger the callback on.
2282	pub fn on_key_up<F>(node: &mut dyn INode, key: KeyName, mut callback: F)
2283	where
2284		F: FnMut() + 'static,
2285	{
2286		node.set_keyboard_enabled(true);
2287		node.slot(
2288			Slot::KEY_UP,
2289			Box::new(move |stack| {
2290				let key_name = match stack.pop_str() {
2291					Some(key_name) => key_name,
2292					None => return,
2293				};
2294				if key.as_ref() == key_name {
2295					callback();
2296				}
2297			}),
2298		);
2299	}
2300	/// Registers a callback for event triggered when a key is pressed.
2301	///
2302	/// # Arguments
2303	///
2304	/// * node: &mut dyn INode - The node to register the callback on.
2305	/// * key: KeyName - The key to trigger the callback on.
2306	pub fn on_key_pressed<F>(node: &mut dyn INode, key: KeyName, mut callback: F)
2307	where
2308		F: FnMut() + 'static,
2309	{
2310		node.set_keyboard_enabled(true);
2311		node.slot(
2312			Slot::KEY_PRESSED,
2313			Box::new(move |stack| {
2314				let key_name = match stack.pop_str() {
2315					Some(key_name) => key_name,
2316					None => return,
2317				};
2318				if key.as_ref() == key_name {
2319					callback();
2320				}
2321			}),
2322		);
2323	}
2324	/// Registers a callback for event triggered when the input method editor (IME) is attached.
2325	///
2326	/// # Arguments
2327	///
2328	/// * node: &mut dyn INode - The node to register the callback on.
2329	/// * callback: F - The callback to be called when the event is triggered.
2330	pub fn on_attach_ime<F>(node: &mut dyn INode, mut callback: F)
2331	where
2332		F: FnMut() + 'static,
2333	{
2334		node.slot(
2335			Slot::ATTACH_IME,
2336			Box::new(move |_| {
2337				callback();
2338			}),
2339		);
2340	}
2341	/// Registers a callback for event triggered when the input method editor (IME) is detached.
2342	///
2343	/// # Arguments
2344	///
2345	/// * node: &mut dyn INode - The node to register the callback on.
2346	/// * callback: F - The callback to be called when the event is triggered.
2347	pub fn on_detach_ime<F>(node: &mut dyn INode, mut callback: F)
2348	where
2349		F: FnMut() + 'static,
2350	{
2351		node.slot(
2352			Slot::DETACH_IME,
2353			Box::new(move |_| {
2354				callback();
2355			}),
2356		);
2357	}
2358	/// Registers a callback for event triggered when text input is received.
2359	///
2360	/// # Arguments
2361	///
2362	/// * node: &mut dyn INode - The node to register the callback on.
2363	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2364	/// 	* text: String - The text that was input.
2365	pub fn on_text_input<F>(node: &mut dyn INode, mut callback: F)
2366	where
2367		F: FnMut(/*text*/ String) + 'static,
2368	{
2369		node.slot(
2370			Slot::TEXT_INPUT,
2371			Box::new(move |stack| {
2372				let text = match stack.pop_str() {
2373					Some(text) => text,
2374					None => return,
2375				};
2376				callback(text);
2377			}),
2378		);
2379	}
2380	/// Registers a callback for event triggered when text is being edited.
2381	///
2382	/// # Arguments
2383	///
2384	/// * node: &mut dyn INode - The node to register the callback on.
2385	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2386	/// 	* text: String - The text that is being edited.
2387	/// 	* start_pos: i32 - The starting position of the text being edited.
2388	pub fn on_text_editing<F>(node: &mut dyn INode, mut callback: F)
2389	where
2390		F: FnMut(/*text*/ String, /*start_pos*/ i32) + 'static,
2391	{
2392		node.slot(
2393			Slot::TEXT_EDITING,
2394			Box::new(move |stack| {
2395				let (text, start_pos) = match (stack.pop_str(), stack.pop_i32()) {
2396					(Some(text), Some(start_pos)) => (text, start_pos),
2397					_ => return,
2398				};
2399				callback(text, start_pos);
2400			}),
2401		);
2402	}
2403	/// Registers a callback for event triggered when a game controller button is pressed down.
2404	///
2405	/// # Arguments
2406	///
2407	/// * node: &mut dyn INode - The node to register the callback on.
2408	/// * button: ButtonName - The button to trigger the callback on.
2409	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2410	/// 	* controller_id: i32 - The controller id, incrementing from 0 when multiple controllers connected.
2411	pub fn on_button_down<F>(node: &mut dyn INode, button: ButtonName, mut callback: F)
2412	where
2413		F: FnMut(/*controller_id*/ i32) + 'static,
2414	{
2415		node.set_controller_enabled(true);
2416		node.slot(
2417			Slot::BUTTON_DOWN,
2418			Box::new(move |stack| {
2419				let (controller_id, button_name) = match (stack.pop_i32(), stack.pop_str()) {
2420					(Some(controller_id), Some(button_name)) => (controller_id, button_name),
2421					_ => return,
2422				};
2423				if button.as_ref() == button_name {
2424					callback(controller_id);
2425				}
2426			}),
2427		);
2428	}
2429	/// Registers a callback for event triggered when a game controller button is released.
2430	///
2431	/// # Arguments
2432	///
2433	/// * node: &mut dyn INode - The node to register the callback on.
2434	/// * button: ButtonName - The button to trigger the callback on.
2435	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2436	/// 	* controller_id: i32 - The controller id, incrementing from 0 when multiple controllers connected.
2437	pub fn on_button_up<F>(node: &mut dyn INode, button: ButtonName, mut callback: F)
2438	where
2439		F: FnMut(/*controller_id*/ i32) + 'static,
2440	{
2441		node.set_controller_enabled(true);
2442		node.slot(
2443			Slot::BUTTON_UP,
2444			Box::new(move |stack| {
2445				let (controller_id, button_name) = match (stack.pop_i32(), stack.pop_str()) {
2446					(Some(controller_id), Some(button_name)) => (controller_id, button_name),
2447					_ => return,
2448				};
2449				if button.as_ref() == button_name {
2450					callback(controller_id);
2451				}
2452			}),
2453		);
2454	}
2455	/// Registers a callback for event triggered when a game controller button is being pressed.
2456	/// This slot is triggered every frame while the button is being pressed.
2457	///
2458	/// # Arguments
2459	///
2460	/// * node: &mut dyn INode - The node to register the callback on.
2461	/// * button: ButtonName - The button to trigger the callback on.
2462	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2463	/// 	* controller_id: i32 - The controller id, incrementing from 0 when multiple controllers connected.
2464	pub fn on_button_pressed<F>(node: &mut dyn INode, button: ButtonName, mut callback: F)
2465	where
2466		F: FnMut(/*controller_id*/ i32) + 'static,
2467	{
2468		node.set_controller_enabled(true);
2469		node.slot(
2470			Slot::BUTTON_PRESSED,
2471			Box::new(move |stack| {
2472				let (controller_id, button_name) = match (stack.pop_i32(), stack.pop_str()) {
2473					(Some(controller_id), Some(button_name)) => (controller_id, button_name),
2474					_ => return,
2475				};
2476				if button.as_ref() == button_name {
2477					callback(controller_id);
2478				}
2479			}),
2480		);
2481	}
2482	/// Registers a callback for event triggered when a game controller axis changed.
2483	/// This slot is triggered every frame while the axis value changes.
2484	/// The axis value ranges from -1.0 to 1.0.
2485	///
2486	/// # Arguments
2487	///
2488	/// * node: &mut dyn INode - The node to register the callback on.
2489	/// * axis: AxisName - The axis to trigger the callback on.
2490	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2491	/// 	* controller_id: i32 - The controller id, incrementing from 0 when multiple controllers connected.
2492	pub fn on_axis<F>(node: &mut dyn INode, axis: AxisName, mut callback: F)
2493	where
2494		F: FnMut(/*controller_id*/ i32, /*axis_value*/ f32) + 'static,
2495	{
2496		node.set_controller_enabled(true);
2497		node.slot(
2498			Slot::AXIS,
2499			Box::new(move |stack| {
2500				let (controller_id, axis_name, axis_value) =
2501					match (stack.pop_i32(), stack.pop_str(), stack.pop_f32()) {
2502						(Some(controller_id), Some(axis_name), Some(axis_value)) => {
2503							(controller_id, axis_name, axis_value)
2504						}
2505						_ => return,
2506					};
2507				if axis.as_ref() == axis_name {
2508					callback(controller_id, axis_value);
2509				}
2510			}),
2511		);
2512	}
2513	/// Registers a callback for event triggered when an animation has ended on a Playable instance.
2514	///
2515	/// # Arguments
2516	///
2517	/// * node: &mut dyn IPlayable - The node to register the callback on.
2518	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2519	/// 	* animation_name: String - The name of the animation that ended.
2520	/// 	* target: Playable - The Playable instance that the animation was played on.
2521	pub fn on_animation_end<F>(node: &mut dyn IPlayable, mut callback: F)
2522	where
2523		F: FnMut(/*animation_name*/ String, /*target*/ Playable) + 'static,
2524	{
2525		node.slot(
2526			Slot::ANIMATION_END,
2527			Box::new(move |stack| {
2528				let (animation_name, playable) = match (stack.pop_str(), stack.pop_into_playable())
2529				{
2530					(Some(animation_name), Some(playable)) => (animation_name, playable),
2531					_ => return,
2532				};
2533				callback(animation_name, playable);
2534			}),
2535		);
2536	}
2537	/// Registers a callback for event triggered when a Body object collides with a sensor object.
2538	///
2539	/// # Arguments
2540	///
2541	/// * node: &mut dyn IBody - The node to register the callback on.
2542	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2543	/// 	* other: Body - The other Body object that the current Body is colliding with.
2544	/// 	* sensor_tag: i32 - The tag of the sensor that triggered this collision.
2545	pub fn on_body_enter<F>(node: &mut dyn IBody, mut callback: F)
2546	where
2547		F: FnMut(/*other*/ Body, /*sensor_tag*/ i32) + 'static,
2548	{
2549		node.slot(
2550			Slot::BODY_ENTER,
2551			Box::new(move |stack| {
2552				let (other, sensor_tag) = match (stack.pop_into_body(), stack.pop_i32()) {
2553					(Some(other), Some(sensor_tag)) => (other, sensor_tag),
2554					_ => return,
2555				};
2556				callback(other, sensor_tag);
2557			}),
2558		);
2559	}
2560	/// Registers a callback for event triggered when a Body object is no longer colliding with a sensor object.
2561	///
2562	/// # Arguments
2563	///
2564	/// * node: &mut dyn IBody - The node to register the callback on.
2565	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2566	/// 	* other: Body - The other Body object that the current Body is no longer colliding with.
2567	/// 	* sensor_tag: i32 - The tag of the sensor that triggered this collision.
2568	pub fn on_body_leave<F>(node: &mut dyn IBody, mut callback: F)
2569	where
2570		F: FnMut(/*other*/ Body, /*sensor_tag*/ i32) + 'static,
2571	{
2572		node.slot(
2573			Slot::BODY_LEAVE,
2574			Box::new(move |stack| {
2575				let (other, sensor_tag) = match (stack.pop_into_body(), stack.pop_i32()) {
2576					(Some(other), Some(sensor_tag)) => (other, sensor_tag),
2577					_ => return,
2578				};
2579				callback(other, sensor_tag);
2580			}),
2581		);
2582	}
2583	/// Registers a callback for event triggered when a Body object starts to collide with another object.
2584	///
2585	/// # Arguments
2586	///
2587	/// * node: &mut dyn IBody - The node to register the callback on.
2588	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2589	/// 	* other: Body - The other Body object that the current Body is colliding with.
2590	/// 	* point: Vec2 - The point of collision in world coordinates.
2591	/// 	* normal: Vec2 - The normal vector of the contact surface in world coordinates.
2592	/// 	* enabled: bool - Whether the contact is enabled or not. Collisions that are filtered out will still trigger this event, but the enabled state will be false.
2593	pub fn on_contact_start<F>(node: &mut dyn IBody, mut callback: F)
2594	where
2595		F: FnMut(
2596				/*other*/ Body,
2597				/*point*/ Vec2,
2598				/*normal*/ Vec2,
2599				/*enabled*/ bool,
2600			) + 'static,
2601	{
2602		node.set_receiving_contact(true);
2603		node.slot(
2604			Slot::CONTACT_START,
2605			Box::new(move |stack| {
2606				let (other, point, normal, enabled) = match (
2607					stack.pop_into_body(),
2608					stack.pop_vec2(),
2609					stack.pop_vec2(),
2610					stack.pop_bool(),
2611				) {
2612					(Some(other), Some(point), Some(normal), Some(enabled)) => {
2613						(other, point, normal, enabled)
2614					}
2615					_ => return,
2616				};
2617				callback(other, point, normal, enabled);
2618			}),
2619		);
2620	}
2621	/// Registers a callback for event triggered when a Body object stops colliding with another object.
2622	///
2623	/// # Arguments
2624	///
2625	/// * node: &mut dyn IBody - The node to register the callback on.
2626	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2627	/// 	* other: Body - The other Body object that the current Body is no longer colliding with.
2628	/// 	* point: Vec2 - The point of collision in world coordinates.
2629	/// 	* normal: Vec2 - The normal vector of the contact surface in world coordinates.
2630	pub fn on_contact_end<F>(node: &mut dyn IBody, mut callback: F)
2631	where
2632		F: FnMut(/*other*/ Body, /*point*/ Vec2, /*normal*/ Vec2) + 'static,
2633	{
2634		node.set_receiving_contact(true);
2635		node.slot(
2636			Slot::CONTACT_END,
2637			Box::new(move |stack| {
2638				let (other, point, normal) =
2639					match (stack.pop_into_body(), stack.pop_vec2(), stack.pop_vec2()) {
2640						(Some(other), Some(point), Some(normal)) => (other, point, normal),
2641						_ => return,
2642					};
2643				callback(other, point, normal);
2644			}),
2645		);
2646	}
2647	/// Registers a callback for event triggered when a Particle node starts a stop action and then all the active particles end their lives.
2648	///
2649	/// # Arguments
2650	///
2651	/// * node: &mut Particle - The node to register the callback on.
2652	/// * callback: F - The callback to be called when the event is triggered.
2653	pub fn on_finished<F>(node: &mut Particle, mut callback: F)
2654	where
2655		F: FnMut() + 'static,
2656	{
2657		node.slot(
2658			Slot::FINISHED,
2659			Box::new(move |_| {
2660				callback();
2661			}),
2662		);
2663	}
2664	/// Registers a callback for event triggered when the layout of the AlignNode is updated.
2665	///
2666	/// # Arguments
2667	///
2668	/// * node: &mut AlignNode - The node to register the callback on.
2669	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2670	/// 	* width: f32 - The width of the AlignNode.
2671	/// 	* height: f32 - The height of the AlignNode.
2672	pub fn on_align_layout<F>(node: &mut AlignNode, mut callback: F)
2673	where
2674		F: FnMut(/*width*/ f32, /*height*/ f32) + 'static,
2675	{
2676		node.slot(
2677			Slot::ALIGN_LAYOUT,
2678			Box::new(move |stack| {
2679				let (width, height) = match (stack.pop_f32(), stack.pop_f32()) {
2680					(Some(width), Some(height)) => (width, height),
2681					_ => return,
2682				};
2683				callback(width, height);
2684			}),
2685		);
2686	}
2687	/// Registers a callback for event triggered when the EffekseerNode finishes playing an effect.
2688	///
2689	/// # Arguments
2690	///
2691	/// * node: &mut EffekNode - The node to register the callback on.
2692	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2693	/// 	* handle: i32 - The handle of the effect that finished playing.
2694	pub fn on_effek_end<F>(node: &mut EffekNode, mut callback: F)
2695	where
2696		F: FnMut(/*handle*/ i32) + 'static,
2697	{
2698		node.slot(
2699			Slot::EFFEK_END,
2700			Box::new(move |stack| {
2701				let handle = match stack.pop_i32() {
2702					Some(handle) => handle,
2703					None => return,
2704				};
2705				callback(handle);
2706			}),
2707		);
2708	}
2709}
2710
2711/// An interface for providing Dora SSR built-in global event names.
2712pub struct GSlot {}
2713impl GSlot {
2714	/// Triggers when the application receives an event.
2715	///
2716	/// # Callback Arguments
2717	///
2718	/// * event_type: string - The type of the application event. The event type could be "Quit", "LowMemory", "WillEnterBackground", "DidEnterBackground", "WillEnterForeground", "DidEnterForeground".
2719	///
2720	/// # Callback Example
2721	///
2722	/// ```
2723	/// node.gslot(GSlot::APP_EVENT, Box::new(|stack| {
2724	/// 	let event_type = match stack.pop_str() {
2725	/// 		Some(event_type) => event_type,
2726	/// 		None => return,
2727	/// 	};
2728	/// 	p!(event_type);
2729	/// }));
2730	/// ```
2731	pub const APP_EVENT: &'static str = "AppEvent";
2732	/// Triggers when the application settings change.
2733	///
2734	/// # Callback Arguments
2735	///
2736	/// * setting_name: string - The name of the setting that changed. Could be "Locale", "Theme", "FullScreen", "Position", "Size".
2737	///
2738	/// # Callback Example
2739	///
2740	/// ```
2741	/// node.gslot(GSlot::APP_CHANGE, Box::new(|stack| {
2742	/// 	let setting_name = match stack.pop_str() {
2743	/// 		Some(setting_name) => setting_name,
2744	/// 		None => return,
2745	/// 	};
2746	/// 	p!(setting_name);
2747	/// }));
2748	/// ```
2749	pub const APP_CHANGE: &'static str = "AppChange";
2750	/// Triggers when gets an event from a websocket connection.
2751	///
2752	/// # Callback Arguments
2753	///
2754	/// * event_type: string - The event type of the message received. Could be "Open", "Close", "Send", "Receive".
2755	/// * msg: string - The message received.
2756	///
2757	/// # Callback Example
2758	///
2759	/// ```
2760	/// node.gslot(GSlot::APP_WS, Box::new(|stack| {
2761	/// 	let (
2762	/// 		event_type,
2763	/// 		msg
2764	/// 	) = match (stack.pop_str(), stack.pop_str()) {
2765	/// 		(Some(event_type), Some(msg)) => (event_type, msg),
2766	/// 		_ => return,
2767	/// 	};
2768	/// 	p!(event_type, msg);
2769	/// }));
2770	/// ```
2771	pub const APP_WS: &'static str = "AppWS";
2772	/// Registers a callback for event triggered when the application receives an event.
2773	///
2774	/// # Arguments
2775	///
2776	/// * node: &mut dyn INode - The node to register the callback on.
2777	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2778	/// 	* event_type: String - The type of the application event. The event type could be "Quit", "LowMemory", "WillEnterBackground", "DidEnterBackground", "WillEnterForeground", "DidEnterForeground".
2779	pub fn on_app_event<F>(node: &mut dyn INode, mut callback: F)
2780	where
2781		F: FnMut(/*event_type*/ String) + 'static,
2782	{
2783		node.gslot(
2784			GSlot::APP_EVENT,
2785			Box::new(move |stack| {
2786				let event_type = match stack.pop_str() {
2787					Some(event_type) => event_type,
2788					None => return,
2789				};
2790				callback(event_type);
2791			}),
2792		);
2793	}
2794	/// Registers a callback for event triggered when the application settings change.
2795	///
2796	/// # Arguments
2797	///
2798	/// * node: &mut dyn INode - The node to register the callback on.
2799	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2800	/// 	* setting_name: String - The name of the setting that changed. Could be "Locale", "Theme", "FullScreen", "Position", "Size".
2801	pub fn on_app_change<F>(node: &mut dyn INode, mut callback: F)
2802	where
2803		F: FnMut(/*setting_name*/ String) + 'static,
2804	{
2805		node.gslot(
2806			GSlot::APP_CHANGE,
2807			Box::new(move |stack| {
2808				let setting_name = match stack.pop_str() {
2809					Some(setting_name) => setting_name,
2810					None => return,
2811				};
2812				callback(setting_name);
2813			}),
2814		);
2815	}
2816	/// Registers a callback for event triggered when gets an event from a websocket connection.
2817	///
2818	/// # Arguments
2819	///
2820	/// * node: &mut dyn INode - The node to register the callback on.
2821	/// * callback: F - The callback to be called when the event is triggered with the following arguments:
2822	/// 	* event_type: String - The event type of the message received. Could be "Open", "Close", "Send", "Receive".
2823	/// 	* msg: String - The message received.
2824	pub fn on_app_ws<F>(node: &mut dyn INode, mut callback: F)
2825	where
2826		F: FnMut(/*event_type*/ String, /*msg*/ String) + 'static,
2827	{
2828		node.gslot(
2829			GSlot::APP_WS,
2830			Box::new(move |stack| {
2831				let (event_type, msg) = match (stack.pop_str(), stack.pop_str()) {
2832					(Some(event_type), Some(msg)) => (event_type, msg),
2833					_ => return,
2834				};
2835				callback(event_type, msg);
2836			}),
2837		);
2838	}
2839}
2840
2841// Content
2842
2843extern "C" {
2844	fn content_load(filename: i64) -> i64;
2845}
2846
2847impl Content {
2848	/// Loads the content of the file with the specified filename.
2849	///
2850	/// # Arguments
2851	///
2852	/// * `filename` - The name of the file to load.
2853	///
2854	/// # Returns
2855	///
2856	/// * `String` - The content of the loaded file.
2857	pub fn load(filename: &str) -> Option<String> {
2858		let result = unsafe { content_load(from_string(filename)) };
2859		if result > 0 {
2860			Some(to_string(result))
2861		} else {
2862			None
2863		}
2864	}
2865}
2866
2867// Array
2868
2869extern "C" {
2870	fn array_set(array: i64, index: i32, item: i64) -> i32;
2871	fn array_get(array: i64, index: i32) -> i64;
2872	fn array_first(array: i64) -> i64;
2873	fn array_last(array: i64) -> i64;
2874	fn array_random_object(array: i64) -> i64;
2875	fn array_add(array: i64, item: i64);
2876	fn array_insert(array: i64, index: i32, item: i64);
2877	fn array_contains(array: i64, item: i64) -> i32;
2878	fn array_index(array: i64, item: i64) -> i32;
2879	fn array_remove_last(array: i64) -> i64;
2880	fn array_fast_remove(array: i64, item: i64) -> i32;
2881}
2882
2883impl Array {
2884	/// Sets the item at the given index.
2885	///
2886	/// # Arguments
2887	///
2888	/// * `index` - The index to set, should be 0 based.
2889	/// * `item` - The new item value.
2890	pub fn set<'a, T>(&mut self, index: i32, v: T)
2891	where
2892		T: IntoValue<'a>,
2893	{
2894		if unsafe { array_set(self.raw(), index, v.val().raw()) == 0 } {
2895			panic!("Out of bounds, expecting [0, {}), got {}", self.get_count(), index);
2896		}
2897	}
2898	/// Gets the item at the given index.
2899	///
2900	/// # Arguments
2901	///
2902	/// * `index` - The index to get, should be 0 based.
2903	///
2904	/// # Returns
2905	///
2906	/// * `Option<Value>` - The item value.
2907	pub fn get(&self, index: i32) -> Option<Value> {
2908		Value::from(unsafe { array_get(self.raw(), index) })
2909	}
2910	/// The first item in the array.
2911	pub fn first(&self) -> Option<Value> {
2912		Value::from(unsafe { array_first(self.raw()) })
2913	}
2914	/// The last item in the array.
2915	pub fn last(&self) -> Option<Value> {
2916		Value::from(unsafe { array_last(self.raw()) })
2917	}
2918	/// A random item from the array.
2919	pub fn random_object(&self) -> Option<Value> {
2920		Value::from(unsafe { array_random_object(self.raw()) })
2921	}
2922	/// Adds an item to the end of the array.
2923	///
2924	/// # Arguments
2925	///
2926	/// * `item` - The item to add.
2927	pub fn add<'a, T>(&mut self, v: T) -> &mut Self
2928	where
2929		T: IntoValue<'a>,
2930	{
2931		unsafe {
2932			array_add(self.raw(), v.val().raw());
2933		}
2934		self
2935	}
2936	/// Inserts an item at the given index, shifting other items to the right.
2937	///
2938	/// # Arguments
2939	///
2940	/// * `index` - The index to insert at.
2941	/// * `item` - The item to insert.
2942	pub fn insert<'a, T>(&mut self, index: i32, v: T)
2943	where
2944		T: IntoValue<'a>,
2945	{
2946		unsafe {
2947			array_insert(self.raw(), index, v.val().raw());
2948		}
2949	}
2950	/// Checks whether the array contains a given item.
2951	///
2952	/// # Arguments
2953	///
2954	/// * `item` - The item to check.
2955	///
2956	/// # Returns
2957	///
2958	/// * `bool` - True if the item is found, false otherwise.
2959	pub fn contains<'a, T>(&self, v: T) -> bool
2960	where
2961		T: IntoValue<'a>,
2962	{
2963		unsafe { array_contains(self.raw(), v.val().raw()) != 0 }
2964	}
2965	/// Gets the index of a given item.
2966	///
2967	/// # Arguments
2968	///
2969	/// * `item` - The item to search for.
2970	///
2971	/// # Returns
2972	///
2973	/// * `i32` - The index of the item, or -1 if it is not found.
2974	pub fn index<'a, T>(&self, v: T) -> i32
2975	where
2976		T: IntoValue<'a>,
2977	{
2978		unsafe { array_index(self.raw(), v.val().raw()) }
2979	}
2980	/// Removes and returns the last item in the array.
2981	///
2982	/// # Returns
2983	///
2984	/// * `Option<Value>` - The last item removed from the array.
2985	pub fn remove_last(&mut self) -> Option<Value> {
2986		Value::from(unsafe { array_remove_last(self.raw()) })
2987	}
2988	/// Removes the first occurrence of a given item from the array without preserving order.
2989	///
2990	/// # Arguments
2991	///
2992	/// * `item` - The item to remove.
2993	///
2994	/// # Returns
2995	///
2996	/// * `bool` - True if the item was found and removed, false otherwise.
2997	pub fn fast_remove<'a, T>(&mut self, v: T) -> bool
2998	where
2999		T: IntoValue<'a>,
3000	{
3001		unsafe { array_fast_remove(self.raw(), v.val().raw()) != 0 }
3002	}
3003}
3004
3005// Dictionary
3006
3007extern "C" {
3008	fn dictionary_set(dict: i64, key: i64, value: i64);
3009	fn dictionary_get(dict: i64, key: i64) -> i64;
3010}
3011
3012impl Dictionary {
3013	/// A method for setting items in the dictionary.
3014	///
3015	/// # Arguments
3016	///
3017	/// * `key` - The key of the item to set.
3018	/// * `item` - The Item to set for the given key, set to None to delete this key-value pair.
3019	pub fn set<'a, T>(&mut self, key: &str, v: T)
3020	where
3021		T: IntoValue<'a>,
3022	{
3023		unsafe {
3024			dictionary_set(self.raw(), from_string(key), v.val().raw());
3025		}
3026	}
3027	/// A method for accessing items in the dictionary.
3028	///
3029	/// # Arguments
3030	///
3031	/// * `key` - The key of the item to retrieve.
3032	///
3033	/// # Returns
3034	///
3035	/// * `Option<Item>` - The Item with the given key, or None if it does not exist.
3036	pub fn get(&self, key: &str) -> Option<Value> {
3037		Value::from(unsafe { dictionary_get(self.raw(), from_string(key)) })
3038	}
3039}
3040
3041// Entity
3042
3043extern "C" {
3044	fn entity_set(e: i64, k: i64, v: i64);
3045	fn entity_get(e: i64, k: i64) -> i64;
3046	fn entity_get_old(e: i64, k: i64) -> i64;
3047}
3048
3049impl Entity {
3050	/// Sets a property of the entity to a given value.
3051	/// This function will trigger events for Observer objects.
3052	///
3053	/// # Arguments
3054	///
3055	/// * `key` - The name of the property to set.
3056	/// * `item` - The value to set the property to.
3057	pub fn set<'a, T>(&mut self, key: &str, value: T)
3058	where
3059		T: IntoValue<'a>,
3060	{
3061		unsafe {
3062			entity_set(self.raw(), from_string(key), value.val().raw());
3063		}
3064	}
3065	/// Retrieves the value of a property of the entity.
3066	///
3067	/// # Arguments
3068	///
3069	/// * `key` - The name of the property to retrieve the value of.
3070	///
3071	/// # Returns
3072	///
3073	/// * `Option<Value>` - The value of the specified property.
3074	pub fn get(&self, key: &str) -> Option<Value> {
3075		Value::from(unsafe { entity_get(self.raw(), from_string(key)) })
3076	}
3077	/// Retrieves the previous value of a property of the entity.
3078	/// The old values are values before the last change of the component values of the Entity.
3079	///
3080	/// # Arguments
3081	///
3082	/// * `key` - The name of the property to retrieve the previous value of.
3083	///
3084	/// # Returns
3085	///
3086	/// * `Option<Value>` - The previous value of the specified property.
3087	pub fn get_old(&self, key: &str) -> Option<Value> {
3088		Value::from(unsafe { entity_get_old(self.raw(), from_string(key)) })
3089	}
3090}
3091
3092// EntityGroup
3093
3094extern "C" {
3095	fn group_watch(group: i64, func: i32, stack: i64);
3096}
3097
3098impl Group {
3099	/// Watches the group for changes to its entities, calling a function whenever an entity is added or changed.
3100	///
3101	/// # Arguments
3102	///
3103	/// * `callback` - The function to call when an entity is added or changed. Returns true to stop watching.
3104	///
3105	/// # Returns
3106	///
3107	/// * `Group` - The same group, for method chaining.
3108	pub fn watch(&mut self, mut callback: Box<dyn FnMut(&mut CallStack) -> bool>) -> &mut Group {
3109		let mut stack = CallStack::new();
3110		let stack_raw = stack.raw();
3111		let func_id = push_function(Box::new(move || {
3112			let result = callback(&mut stack);
3113			stack.push_bool(result);
3114		}));
3115		unsafe {
3116			group_watch(self.raw(), func_id, stack_raw);
3117		}
3118		self
3119	}
3120	/// Calls a function for each entity in the group.
3121	///
3122	/// # Arguments
3123	///
3124	/// * `visitor` - The function to call for each entity. Returning true inside the function will stop iteration.
3125	///
3126	/// # Returns
3127	///
3128	/// * `bool` - Returns false if all entities were processed, true if the iteration was interrupted.
3129	pub fn each(&self, visitor: Box<dyn FnMut(&Entity) -> bool>) -> bool {
3130		match self.find(visitor) {
3131			Some(_) => true,
3132			None => false,
3133		}
3134	}
3135}
3136
3137// Observer
3138
3139extern "C" {
3140	fn observer_watch(observer: i64, func: i32, stack: i64);
3141}
3142
3143#[repr(i32)]
3144#[derive(Copy, Clone, Debug, PartialEq)]
3145pub enum EntityEvent {
3146	Add = 1,
3147	Change = 2,
3148	AddOrChange = 3,
3149	Remove = 4,
3150}
3151
3152impl Observer {
3153	/// Watches the components changes to entities that match the observer's component filter.
3154	///
3155	/// # Arguments
3156	///
3157	/// * `callback` - The function to call when a change occurs. Returns true to stop watching.
3158	///
3159	/// # Returns
3160	///
3161	/// * `Observer` - The same observer, for method chaining.
3162	pub fn watch(&mut self, mut callback: Box<dyn FnMut(&mut CallStack) -> bool>) -> &mut Observer {
3163		let mut stack = CallStack::new();
3164		let stack_raw = stack.raw();
3165		let func_id = push_function(Box::new(move || {
3166			let result = callback(&mut stack);
3167			stack.push_bool(result);
3168		}));
3169		unsafe {
3170			observer_watch(self.raw(), func_id, stack_raw);
3171		}
3172		self
3173	}
3174}
3175
3176// Director
3177
3178#[cfg(not(target_arch = "wasm32"))]
3179extern "C" {
3180	fn director_get_scheduler() -> i64;
3181	fn director_get_post_scheduler() -> i64;
3182}
3183
3184#[cfg(target_arch = "wasm32")]
3185extern "C" {
3186	fn director_get_wasm_scheduler() -> i64;
3187	fn director_get_post_wasm_scheduler() -> i64;
3188}
3189
3190impl Director {
3191	/// Gets the scheduler for the director.
3192	/// The scheduler is used for scheduling tasks to run for the main game logic.
3193	///
3194	/// # Returns
3195	///
3196	/// * `Scheduler` - The scheduler for the director.
3197	pub fn get_scheduler() -> Scheduler {
3198		#[cfg(target_arch = "wasm32")]
3199		{
3200			Scheduler::from(unsafe { director_get_wasm_scheduler() }).unwrap()
3201		}
3202		#[cfg(not(target_arch = "wasm32"))]
3203		{
3204			Scheduler::from(unsafe { director_get_scheduler() }).unwrap()
3205		}
3206	}
3207	/// Gets the post scheduler for the director.
3208	/// The post scheduler is used for scheduling tasks that should run after the main scheduler has finished.
3209	///
3210	/// # Returns
3211	///
3212	/// * `Scheduler` - The post scheduler for the director.
3213	pub fn get_post_scheduler() -> Scheduler {
3214		#[cfg(target_arch = "wasm32")]
3215		{
3216			Scheduler::from(unsafe { director_get_post_wasm_scheduler() }).unwrap()
3217		}
3218		#[cfg(not(target_arch = "wasm32"))]
3219		{
3220			Scheduler::from(unsafe { director_get_post_scheduler() }).unwrap()
3221		}
3222	}
3223}
3224
3225// Node
3226
3227impl Node {
3228	/// Casts the object to a node.
3229	///
3230	/// # Arguments
3231	///
3232	/// * `obj` - The object to cast.
3233	///
3234	/// # Returns
3235	///
3236	/// * `Option<Node>` - The node if the object is a node, None otherwise.
3237	pub fn cast(obj: &dyn IObject) -> Option<Node> {
3238		let node = Node::from(unsafe { object_to_node(obj.raw()) });
3239		if node.is_some() {
3240			unsafe {
3241				object_retain(obj.raw());
3242			}
3243		}
3244		node
3245	}
3246}
3247
3248// Camera
3249
3250impl Camera {
3251	/// Casts the object to a camera.
3252	///
3253	/// # Arguments
3254	///
3255	/// * `obj` - The object to cast.
3256	///
3257	/// # Returns
3258	///
3259	/// * `Option<Camera>` - The camera if the object is a camera, None otherwise.
3260	pub fn cast(obj: &dyn IObject) -> Option<Camera> {
3261		let camera = Camera::from(unsafe { object_to_camera(obj.raw()) });
3262		if camera.is_some() {
3263			unsafe {
3264				object_retain(obj.raw());
3265			}
3266		}
3267		camera
3268	}
3269}
3270
3271// Playable
3272
3273impl Playable {
3274	/// Casts the object to a playable.
3275	///
3276	/// # Arguments
3277	///
3278	/// * `obj` - The object to cast.
3279	///
3280	/// # Returns
3281	///
3282	/// * `Option<Playable>` - The playable if the object is a playable, None otherwise.
3283	pub fn cast(obj: &dyn IObject) -> Option<Playable> {
3284		let playable = Playable::from(unsafe { object_to_playable(obj.raw()) });
3285		if playable.is_some() {
3286			unsafe {
3287				object_retain(obj.raw());
3288			}
3289		}
3290		playable
3291	}
3292}
3293
3294// Body
3295
3296impl Body {
3297	/// Casts the object to a body.
3298	///
3299	/// # Arguments
3300	///
3301	/// * `obj` - The object to cast.
3302	///
3303	/// # Returns
3304	///
3305	/// * `Option<Body>` - The body if the object is a body, None otherwise.
3306	pub fn cast(obj: &dyn IObject) -> Option<Body> {
3307		let body = Body::from(unsafe { object_to_body(obj.raw()) });
3308		if body.is_some() {
3309			unsafe {
3310				object_retain(obj.raw());
3311			}
3312		}
3313		body
3314	}
3315}
3316
3317// Joint
3318
3319impl Joint {
3320	/// Casts the object to a joint.
3321	///
3322	/// # Arguments
3323	///
3324	/// * `obj` - The object to cast.
3325	///
3326	/// # Returns
3327	///
3328	/// * `Option<Joint>` - The joint if the object is a joint, None otherwise.
3329	pub fn cast(obj: &dyn IObject) -> Option<Joint> {
3330		let joint = Joint::from(unsafe { object_to_joint(obj.raw()) });
3331		if joint.is_some() {
3332			unsafe {
3333				object_retain(obj.raw());
3334			}
3335		}
3336		joint
3337	}
3338}
3339
3340// PhysicsWorld
3341
3342impl PhysicsWorld {
3343	/// Casts the object to a physics world.
3344	///
3345	/// # Arguments
3346	///
3347	/// * `obj` - The object to cast.
3348	///
3349	/// # Returns
3350	///
3351	/// * `Option<PhysicsWorld>` - The physics world if the object is a physics world, None otherwise.
3352	pub fn cast(obj: &dyn IObject) -> Option<PhysicsWorld> {
3353		let physics_world = PhysicsWorld::from(unsafe { object_to_physics_world(obj.raw()) });
3354		if physics_world.is_some() {
3355			unsafe {
3356				object_retain(obj.raw());
3357			}
3358		}
3359		physics_world
3360	}
3361}
3362
3363// Sprite
3364#[repr(i32)]
3365#[derive(Copy, Clone, Debug, PartialEq)]
3366pub enum TextureWrap {
3367	None = 0,
3368	Mirror = 1,
3369	Clamp = 2,
3370	Border = 3,
3371}
3372
3373#[repr(i32)]
3374#[derive(Copy, Clone, Debug, PartialEq)]
3375pub enum TextureFilter {
3376	None = 0,
3377	Point = 1,
3378	Anisotropic = 2,
3379}
3380
3381#[repr(u64)]
3382#[derive(Copy, Clone, Debug, PartialEq)]
3383pub enum BFunc {
3384	Zero = 0x0000000000001000,
3385	One = 0x0000000000002000,
3386	SrcColor = 0x0000000000003000,
3387	InvSrcColor = 0x0000000000004000,
3388	SrcAlpha = 0x0000000000005000,
3389	InvSrcAlpha = 0x0000000000006000,
3390	DstAlpha = 0x0000000000007000,
3391	InvDstAlpha = 0x0000000000008000,
3392	DstColor = 0x0000000000009000,
3393	InvDstColor = 0x000000000000a000,
3394}
3395
3396pub struct BlendFunc {
3397	value: u64,
3398}
3399
3400impl BlendFunc {
3401	pub fn new_seperate(
3402		src_rgb: BFunc,
3403		dst_rgb: BFunc,
3404		src_alpha: BFunc,
3405		dst_alpha: BFunc,
3406	) -> Self {
3407		BlendFunc {
3408			value: (src_rgb as u64
3409				| (dst_rgb as u64) << 4
3410				| src_alpha as u64
3411				| (dst_alpha as u64) << 4)
3412				<< 8,
3413		}
3414	}
3415	pub fn new(src: BFunc, dst: BFunc) -> Self {
3416		BlendFunc::new_seperate(src, dst, src, dst)
3417	}
3418	pub fn from(value: i64) -> Self {
3419		BlendFunc { value: value as u64 }
3420	}
3421	pub(crate) fn to_value(&self) -> i64 {
3422		self.value as i64
3423	}
3424}
3425
3426// Ease
3427
3428#[repr(i32)]
3429#[derive(Copy, Clone, Debug, PartialEq)]
3430pub enum EaseType {
3431	Linear = 0,
3432	InQuad = 1,
3433	OutQuad = 2,
3434	InOutQuad = 3,
3435	InCubic = 4,
3436	OutCubic = 5,
3437	InOutCubic = 6,
3438	InQuart = 7,
3439	OutQuart = 8,
3440	InOutQuart = 9,
3441	InQuint = 10,
3442	OutQuint = 11,
3443	InOutQuint = 12,
3444	InSine = 13,
3445	OutSine = 14,
3446	InOutSine = 15,
3447	InExpo = 16,
3448	OutExpo = 17,
3449	InOutExpo = 18,
3450	InCirc = 19,
3451	OutCirc = 20,
3452	InOutCirc = 21,
3453	InElastic = 22,
3454	OutElastic = 23,
3455	InOutElastic = 24,
3456	InBack = 25,
3457	OutBack = 26,
3458	InOutBack = 27,
3459	InBounce = 28,
3460	OutBounce = 29,
3461	InOutBounce = 30,
3462	OutInQuad = 31,
3463	OutInCubic = 32,
3464	OutInQuart = 33,
3465	OutInQuint = 34,
3466	OutInSine = 35,
3467	OutInExpo = 36,
3468	OutInCirc = 37,
3469	OutInElastic = 38,
3470	OutInBack = 39,
3471	OutInBounce = 40,
3472}
3473
3474#[repr(i32)]
3475#[derive(Copy, Clone, Debug, PartialEq)]
3476pub enum Property {
3477	X = 0,
3478	Y = 1,
3479	Z = 2,
3480	Angle = 3,
3481	AngleX = 4,
3482	AngleY = 5,
3483	ScaleX = 6,
3484	ScaleY = 7,
3485	SkewX = 8,
3486	SkewY = 9,
3487	Width = 10,
3488	Height = 11,
3489	AnchorX = 12,
3490	AnchorY = 13,
3491	Opacity = 14,
3492}
3493
3494// Label
3495
3496#[repr(i32)]
3497#[derive(Copy, Clone, Debug, PartialEq)]
3498pub enum TextAlign {
3499	Left = 0,
3500	Center = 1,
3501	Right = 2,
3502}
3503
3504// BodyDef
3505
3506#[repr(i32)]
3507#[derive(Copy, Clone, Debug, PartialEq)]
3508pub enum BodyType {
3509	Dynamic = 0,
3510	Static = 1,
3511	Kinematic = 2,
3512}
3513
3514// Keyboard
3515
3516#[derive(Copy, Clone, Debug, PartialEq)]
3517pub enum KeyName {
3518	Return,
3519	Escape,
3520	BackSpace,
3521	Tab,
3522	Space,
3523	Exclamation,
3524	DoubleQuote,
3525	Hash,
3526	Percent,
3527	Dollar,
3528	Ampersand,
3529	SingleQuote,
3530	LeftParen,
3531	RightParen,
3532	Asterisk,
3533	Plus,
3534	Comma,
3535	Minus,
3536	Dot,
3537	Slash,
3538	Num1,
3539	Num2,
3540	Num3,
3541	Num4,
3542	Num5,
3543	Num6,
3544	Num7,
3545	Num8,
3546	Num9,
3547	Num0,
3548	Colon,
3549	Semicolon,
3550	LessThan,
3551	Equal,
3552	GreaterThan,
3553	Question,
3554	At,
3555	LeftBracket,
3556	Backslash,
3557	RightBracket,
3558	Caret,
3559	Underscore,
3560	Backtick,
3561	A,
3562	B,
3563	C,
3564	D,
3565	E,
3566	F,
3567	G,
3568	H,
3569	I,
3570	J,
3571	K,
3572	L,
3573	M,
3574	N,
3575	O,
3576	P,
3577	Q,
3578	R,
3579	S,
3580	T,
3581	U,
3582	V,
3583	W,
3584	X,
3585	Y,
3586	Z,
3587	Delete,
3588	CapsLock,
3589	F1,
3590	F2,
3591	F3,
3592	F4,
3593	F5,
3594	F6,
3595	F7,
3596	F8,
3597	F9,
3598	F10,
3599	F11,
3600	F12,
3601	PrintScreen,
3602	ScrollLock,
3603	Pause,
3604	Insert,
3605	Home,
3606	PageUp,
3607	End,
3608	PageDown,
3609	Right,
3610	Left,
3611	Down,
3612	Up,
3613	Application,
3614	LCtrl,
3615	LShift,
3616	LAlt,
3617	LGui,
3618	RCtrl,
3619	RShift,
3620	RAlt,
3621	RGui,
3622}
3623
3624impl AsRef<str> for KeyName {
3625	fn as_ref(&self) -> &str {
3626		match self {
3627			KeyName::Return => "Return",
3628			KeyName::Escape => "Escape",
3629			KeyName::BackSpace => "BackSpace",
3630			KeyName::Tab => "Tab",
3631			KeyName::Space => "Space",
3632			KeyName::Exclamation => "!",
3633			KeyName::DoubleQuote => "\"",
3634			KeyName::Hash => "#",
3635			KeyName::Percent => "%",
3636			KeyName::Dollar => "$",
3637			KeyName::Ampersand => "&",
3638			KeyName::SingleQuote => "'",
3639			KeyName::LeftParen => "(",
3640			KeyName::RightParen => ")",
3641			KeyName::Asterisk => "*",
3642			KeyName::Plus => "+",
3643			KeyName::Comma => ",",
3644			KeyName::Minus => "-",
3645			KeyName::Dot => ".",
3646			KeyName::Slash => "/",
3647			KeyName::Num1 => "1",
3648			KeyName::Num2 => "2",
3649			KeyName::Num3 => "3",
3650			KeyName::Num4 => "4",
3651			KeyName::Num5 => "5",
3652			KeyName::Num6 => "6",
3653			KeyName::Num7 => "7",
3654			KeyName::Num8 => "8",
3655			KeyName::Num9 => "9",
3656			KeyName::Num0 => "0",
3657			KeyName::Colon => ":",
3658			KeyName::Semicolon => ";",
3659			KeyName::LessThan => "<",
3660			KeyName::Equal => "=",
3661			KeyName::GreaterThan => ">",
3662			KeyName::Question => "?",
3663			KeyName::At => "@",
3664			KeyName::LeftBracket => "[",
3665			KeyName::Backslash => "\\",
3666			KeyName::RightBracket => "]",
3667			KeyName::Caret => "^",
3668			KeyName::Underscore => "_",
3669			KeyName::Backtick => "`",
3670			KeyName::A => "A",
3671			KeyName::B => "B",
3672			KeyName::C => "C",
3673			KeyName::D => "D",
3674			KeyName::E => "E",
3675			KeyName::F => "F",
3676			KeyName::G => "G",
3677			KeyName::H => "H",
3678			KeyName::I => "I",
3679			KeyName::J => "J",
3680			KeyName::K => "K",
3681			KeyName::L => "L",
3682			KeyName::M => "M",
3683			KeyName::N => "N",
3684			KeyName::O => "O",
3685			KeyName::P => "P",
3686			KeyName::Q => "Q",
3687			KeyName::R => "R",
3688			KeyName::S => "S",
3689			KeyName::T => "T",
3690			KeyName::U => "U",
3691			KeyName::V => "V",
3692			KeyName::W => "W",
3693			KeyName::X => "X",
3694			KeyName::Y => "Y",
3695			KeyName::Z => "Z",
3696			KeyName::Delete => "Delete",
3697			KeyName::CapsLock => "CapsLock",
3698			KeyName::F1 => "F1",
3699			KeyName::F2 => "F2",
3700			KeyName::F3 => "F3",
3701			KeyName::F4 => "F4",
3702			KeyName::F5 => "F5",
3703			KeyName::F6 => "F6",
3704			KeyName::F7 => "F7",
3705			KeyName::F8 => "F8",
3706			KeyName::F9 => "F9",
3707			KeyName::F10 => "F10",
3708			KeyName::F11 => "F11",
3709			KeyName::F12 => "F12",
3710			KeyName::PrintScreen => "PrintScreen",
3711			KeyName::ScrollLock => "ScrollLock",
3712			KeyName::Pause => "Pause",
3713			KeyName::Insert => "Insert",
3714			KeyName::Home => "Home",
3715			KeyName::PageUp => "PageUp",
3716			KeyName::End => "End",
3717			KeyName::PageDown => "PageDown",
3718			KeyName::Right => "Right",
3719			KeyName::Left => "Left",
3720			KeyName::Down => "Down",
3721			KeyName::Up => "Up",
3722			KeyName::Application => "Application",
3723			KeyName::LCtrl => "LCtrl",
3724			KeyName::LShift => "LShift",
3725			KeyName::LAlt => "LAlt",
3726			KeyName::LGui => "LGui",
3727			KeyName::RCtrl => "RCtrl",
3728			KeyName::RShift => "RShift",
3729			KeyName::RAlt => "RAlt",
3730			KeyName::RGui => "RGui",
3731		}
3732	}
3733}
3734
3735impl Keyboard {
3736	/// Checks whether a key is pressed down in the current frame.
3737	///
3738	/// # Arguments
3739	///
3740	/// * `name` - The name of the key to check.
3741	///
3742	/// # Returns
3743	///
3744	/// * `bool` - `true` if the key is pressed down, `false` otherwise.
3745	pub fn is_key_down(key: KeyName) -> bool {
3746		Keyboard::_is_key_down(key.as_ref())
3747	}
3748	/// Checks whether a key is released in the current frame.
3749	///
3750	/// # Arguments
3751	///
3752	/// * `name` - The name of the key to check.
3753	///
3754	/// # Returns
3755	///
3756	/// * `bool` - `true` if the key is released, `false` otherwise.
3757	pub fn is_key_up(key: KeyName) -> bool {
3758		Keyboard::_is_key_up(key.as_ref())
3759	}
3760	/// Checks whether a key is in pressed state.
3761	///
3762	/// # Arguments
3763	///
3764	/// * `name` - The name of the key to check.
3765	///
3766	/// # Returns
3767	///
3768	/// * `bool` - `true` if the key is in pressed state, `false` otherwise.
3769	pub fn is_key_pressed(key: KeyName) -> bool {
3770		Keyboard::_is_key_pressed(key.as_ref())
3771	}
3772}
3773
3774// Controller
3775
3776#[derive(Copy, Clone, Debug, PartialEq)]
3777pub enum AxisName {
3778	LeftX,
3779	LeftY,
3780	RightX,
3781	RightY,
3782	LeftTrigger,
3783	RightTrigger,
3784}
3785
3786impl AsRef<str> for AxisName {
3787	fn as_ref(&self) -> &str {
3788		match self {
3789			AxisName::LeftX => "leftx",
3790			AxisName::LeftY => "lefty",
3791			AxisName::RightX => "rightx",
3792			AxisName::RightY => "righty",
3793			AxisName::LeftTrigger => "lefttrigger",
3794			AxisName::RightTrigger => "righttrigger",
3795		}
3796	}
3797}
3798
3799#[derive(Copy, Clone, Debug, PartialEq)]
3800pub enum ButtonName {
3801	A,
3802	B,
3803	Back,
3804	DPDown,
3805	DPLeft,
3806	DPRight,
3807	DPUp,
3808	LeftShoulder,
3809	LeftStick,
3810	RightShoulder,
3811	RightStick,
3812	Start,
3813	X,
3814	Y,
3815}
3816
3817impl AsRef<str> for ButtonName {
3818	fn as_ref(&self) -> &str {
3819		match self {
3820			ButtonName::A => "a",
3821			ButtonName::B => "b",
3822			ButtonName::Back => "back",
3823			ButtonName::DPDown => "dpdown",
3824			ButtonName::DPLeft => "dpleft",
3825			ButtonName::DPRight => "dpright",
3826			ButtonName::DPUp => "dpup",
3827			ButtonName::LeftShoulder => "leftshoulder",
3828			ButtonName::LeftStick => "leftstick",
3829			ButtonName::RightShoulder => "rightshoulder",
3830			ButtonName::RightStick => "rightstick",
3831			ButtonName::Start => "start",
3832			ButtonName::X => "x",
3833			ButtonName::Y => "y",
3834		}
3835	}
3836}
3837
3838impl Controller {
3839	/// Checks whether a button is pressed down in the current frame.
3840	///
3841	/// # Arguments
3842	///
3843	/// * `controller_id` - The controller id, incrementing from 0 when multiple controllers are connected.
3844	/// * `name` - The name of the button to check.
3845	///
3846	/// # Returns
3847	///
3848	/// * `bool` - `true` if the button is pressed down, `false` otherwise.
3849	pub fn is_button_down(controller_id: i32, button: ButtonName) -> bool {
3850		Controller::_is_button_down(controller_id, button.as_ref())
3851	}
3852	/// Checks whether a button is released in the current frame.
3853	///
3854	/// # Arguments
3855	///
3856	/// * `controller_id` - The controller id, incrementing from 0 when multiple controllers are connected.
3857	/// * `name` - The name of the button to check.
3858	///
3859	/// # Returns
3860	///
3861	/// * `bool` - `true` if the button is released, `false` otherwise.
3862	pub fn is_button_up(controller_id: i32, button: ButtonName) -> bool {
3863		Controller::_is_button_up(controller_id, button.as_ref())
3864	}
3865	/// Checks whether a button is in pressed state.
3866	///
3867	/// # Arguments
3868	///
3869	/// * `controller_id` - The controller id, incrementing from 0 when multiple controllers are connected.
3870	/// * `name` - The name of the button to check.
3871	///
3872	/// # Returns
3873	///
3874	/// * `bool` - `true` if the button is in pressed state, `false` otherwise.
3875	pub fn is_button_pressed(controller_id: i32, button: ButtonName) -> bool {
3876		Controller::_is_button_pressed(controller_id, button.as_ref())
3877	}
3878	/// Gets the axis value from a given controller.
3879	///
3880	/// # Arguments
3881	///
3882	/// * `controller_id` - The controller id, incrementing from 0 when multiple controllers are connected.
3883	/// * `name` - The name of the controller axis to check.
3884	///
3885	/// # Returns
3886	///
3887	/// * `f32` - The axis value ranging from -1.0 to 1.0.
3888	pub fn get_axis(controller_id: i32, axis: AxisName) -> f32 {
3889		Controller::_get_axis(controller_id, axis.as_ref())
3890	}
3891}
3892
3893// Audio
3894
3895#[repr(i32)]
3896#[derive(Copy, Clone, Debug, PartialEq)]
3897pub enum AttenuationModel {
3898	NoAttenuation = 0,
3899	InverseDistance = 1,
3900	LinearDistance = 2,
3901	ExponentialDistance = 3,
3902}
3903
3904// platformer::ActionUpdate
3905
3906impl platformer::ActionUpdate {
3907	pub fn from_update(mut update: Box<dyn FnMut(f64) -> bool>) -> platformer::ActionUpdate {
3908		platformer::ActionUpdate::new(Box::new(move |_, _, dt| update(dt as f64)))
3909	}
3910}
3911
3912// Blackboard
3913
3914extern "C" {
3915	fn blackboard_set(b: i64, k: i64, v: i64);
3916	fn blackboard_get(b: i64, k: i64) -> i64;
3917}
3918
3919impl platformer::behavior::Blackboard {
3920	/// Sets a value in the blackboard.
3921	///
3922	/// # Arguments
3923	/// * `key` - The key associated with the value.
3924	/// * `value` - The value to be set.
3925	///
3926	/// # Example
3927	///
3928	/// ```
3929	/// blackboard.set("score", 100);
3930	/// ```
3931	pub fn set<'a, T>(&mut self, key: &str, value: T)
3932	where
3933		T: IntoValue<'a>,
3934	{
3935		unsafe {
3936			blackboard_set(self.raw(), from_string(key), value.val().raw());
3937		}
3938	}
3939	/// Retrieves a value from the blackboard.
3940	///
3941	/// # Arguments
3942	///
3943	/// * `key` - The key associated with the value.
3944	///
3945	/// # Returns
3946	///
3947	/// An `Option` containing the value associated with the key, or `None` if the key does not exist.
3948	///
3949	/// # Example
3950	///
3951	/// ```
3952	/// if let Some(score) = blackboard.get("score") {
3953	///     println!("Score: {}", score.into_i32().unwrap());
3954	/// } else {
3955	///     println!("Score not found.");
3956	/// }
3957	/// ```
3958	pub fn get(&self, key: &str) -> Option<Value> {
3959		Value::from(unsafe { blackboard_get(self.raw(), from_string(key)) })
3960	}
3961}
3962
3963pub use enumflags2::BitFlags;
3964use enumflags2::{bitflags, make_bitflags};
3965
3966#[bitflags]
3967#[repr(u32)]
3968#[derive(Copy, Clone, Debug, PartialEq)]
3969pub enum ImGuiSliderFlag {
3970	Logarithmic = 1 << 5,
3971	NoRoundToFormat = 1 << 6,
3972	NoInput = 1 << 7,
3973	WrapAround = 1 << 8,
3974	ClampOnInput = 1 << 9,
3975	ClampZeroRange = 1 << 10,
3976}
3977
3978impl ImGuiSliderFlag {
3979	pub const ALWAYS_CLAMP: BitFlags<Self> = make_bitflags!(Self::{ClampOnInput | ClampZeroRange});
3980}
3981
3982#[bitflags]
3983#[repr(u32)]
3984#[derive(Copy, Clone, Debug, PartialEq)]
3985pub enum ImGuiWindowFlag {
3986	NoTitleBar = 1 << 0,
3987	NoResize = 1 << 1,
3988	NoMove = 1 << 2,
3989	NoScrollbar = 1 << 3,
3990	NoScrollWithMouse = 1 << 4,
3991	NoCollapse = 1 << 5,
3992	AlwaysAutoResize = 1 << 6,
3993	NoBackground = 1 << 7,
3994	NoSavedSettings = 1 << 8,
3995	NoMouseInputs = 1 << 9,
3996	MenuBar = 1 << 10,
3997	HorizontalScrollbar = 1 << 11,
3998	NoFocusOnAppearing = 1 << 12,
3999	NoBringToFrontOnFocus = 1 << 13,
4000	AlwaysVerticalScrollbar = 1 << 14,
4001	AlwaysHorizontalScrollbar = 1 << 15,
4002	NoNavInputs = 1 << 16,
4003	NoNavFocus = 1 << 17,
4004	UnsavedDocument = 1 << 18,
4005}
4006
4007impl ImGuiWindowFlag {
4008	pub const NO_NAV: BitFlags<Self> = make_bitflags!(Self::{NoNavInputs | NoNavFocus});
4009	pub const NO_DECORATION: BitFlags<Self> =
4010		make_bitflags!(Self::{NoTitleBar | NoResize | NoScrollbar | NoCollapse});
4011	pub const NO_INPUTS: BitFlags<Self> =
4012		make_bitflags!(Self::{NoMouseInputs | NoNavInputs | NoNavFocus});
4013}
4014
4015#[bitflags]
4016#[repr(u8)]
4017#[derive(Copy, Clone, Debug, PartialEq)]
4018pub enum ImGuiChildFlag {
4019	Borders = 1 << 0,
4020	AlwaysUseWindowPadding = 1 << 1,
4021	ResizeX = 1 << 2,
4022	ResizeY = 1 << 3,
4023	AutoResizeX = 1 << 4,
4024	AutoResizeY = 1 << 5,
4025	AlwaysAutoResize = 1 << 6,
4026	FrameStyle = 1 << 7,
4027}
4028
4029#[bitflags]
4030#[repr(u32)]
4031#[derive(Copy, Clone, Debug, PartialEq)]
4032pub enum ImGuiInputTextFlag {
4033	CharsDecimal = 1 << 0,
4034	CharsHexadecimal = 1 << 1,
4035	CharsScientific = 1 << 2,
4036	CharsUppercase = 1 << 3,
4037	CharsNoBlank = 1 << 4,
4038	AllowTabInput = 1 << 5,
4039	EnterReturnsTrue = 1 << 6,
4040	EscapeClearsAll = 1 << 7,
4041	CtrlEnterForNewLine = 1 << 8,
4042	ReadOnly = 1 << 9,
4043	Password = 1 << 10,
4044	AlwaysOverwrite = 1 << 11,
4045	AutoSelectAll = 1 << 12,
4046	ParseEmptyRefVal = 1 << 13,
4047	DisplayEmptyRefVal = 1 << 14,
4048	NoHorizontalScroll = 1 << 15,
4049	NoUndoRedo = 1 << 16,
4050	ElideLeft = 1 << 17,
4051	CallbackCompletion = 1 << 18,
4052	CallbackHistory = 1 << 19,
4053	CallbackAlways = 1 << 20,
4054	CallbackCharFilter = 1 << 21,
4055	CallbackResize = 1 << 22,
4056	CallbackEdit = 1 << 23,
4057}
4058
4059#[bitflags]
4060#[repr(u32)]
4061#[derive(Copy, Clone, Debug, PartialEq)]
4062pub enum ImGuiTreeNodeFlag {
4063	Selected = 1 << 0,
4064	Framed = 1 << 1,
4065	AllowOverlap = 1 << 2,
4066	NoTreePushOnOpen = 1 << 3,
4067	NoAutoOpenOnLog = 1 << 4,
4068	DefaultOpen = 1 << 5,
4069	OpenOnDoubleClick = 1 << 6,
4070	OpenOnArrow = 1 << 7,
4071	Leaf = 1 << 8,
4072	Bullet = 1 << 9,
4073	FramePadding = 1 << 10,
4074	SpanAvailWidth = 1 << 11,
4075	SpanFullWidth = 1 << 12,
4076	SpanLabelWidth = 1 << 13,
4077	SpanAllColumns = 1 << 14,
4078	LabelSpanAllColumns = 1 << 15,
4079	NavLeftJumpsToParent = 1 << 17,
4080}
4081
4082impl ImGuiTreeNodeFlag {
4083	pub const COLLAPSING_HEADER: BitFlags<Self> =
4084		make_bitflags!(Self::{Framed | NoTreePushOnOpen | NoAutoOpenOnLog});
4085}
4086
4087#[bitflags]
4088#[repr(u8)]
4089#[derive(Copy, Clone, Debug, PartialEq)]
4090pub enum ImGuiSelectableFlag {
4091	DontClosePopups = 1 << 0,
4092	SpanAllColumns = 1 << 1,
4093	AllowDoubleClick = 1 << 2,
4094	Disabled = 1 << 3,
4095	AllowOverlap = 1 << 4,
4096}
4097
4098#[derive(Copy, Clone, Debug, PartialEq)]
4099pub enum ImGuiCol {
4100	Text,
4101	TextDisabled,
4102	WindowBg,
4103	ChildBg,
4104	PopupBg,
4105	Border,
4106	BorderShadow,
4107	FrameBg,
4108	FrameBgHovered,
4109	FrameBgActive,
4110	TitleBg,
4111	TitleBgActive,
4112	TitleBgCollapsed,
4113	MenuBarBg,
4114	ScrollbarBg,
4115	ScrollbarGrab,
4116	ScrollbarGrabHovered,
4117	ScrollbarGrabActive,
4118	CheckMark,
4119	SliderGrab,
4120	SliderGrabActive,
4121	Button,
4122	ButtonHovered,
4123	ButtonActive,
4124	Header,
4125	HeaderHovered,
4126	HeaderActive,
4127	Separator,
4128	SeparatorHovered,
4129	SeparatorActive,
4130	ResizeGrip,
4131	ResizeGripHovered,
4132	ResizeGripActive,
4133	TabHovered,
4134	Tab,
4135	TabSelected,
4136	TabSelectedOverline,
4137	TabDimmed,
4138	TabDimmedSelected,
4139	TabDimmedSelectedOverline,
4140	PlotLines,
4141	PlotLinesHovered,
4142	PlotHistogram,
4143	PlotHistogramHovered,
4144	TableHeaderBg,
4145	TableBorderStrong,
4146	TableBorderLight,
4147	TableRowBg,
4148	TableRowBgAlt,
4149	TextLink,
4150	TextSelectedBg,
4151	DragDropTarget,
4152	NavCursor,
4153	NavWindowingHighlight,
4154	NavWindowingDimBg,
4155	ModalWindowDimBg,
4156}
4157
4158#[bitflags]
4159#[repr(u32)]
4160#[derive(Copy, Clone, Debug, PartialEq)]
4161pub enum ImGuiColorEditFlag {
4162	NoAlpha = 1 << 1,
4163	NoPicker = 1 << 2,
4164	NoOptions = 1 << 3,
4165	NoSmallPreview = 1 << 4,
4166	NoInputs = 1 << 5,
4167	NoTooltip = 1 << 6,
4168	NoLabel = 1 << 7,
4169	NoSidePreview = 1 << 8,
4170	NoDragDrop = 1 << 9,
4171	NoBorder = 1 << 10,
4172	AlphaOpaque = 1 << 11,
4173	AlphaNoBg = 1 << 12,
4174	AlphaPreviewHalf = 1 << 13,
4175	AlphaBar = 1 << 16,
4176	HDR = 1 << 19,
4177	DisplayRGB = 1 << 20,
4178	DisplayHSV = 1 << 21,
4179	DisplayHex = 1 << 22,
4180	Uint8 = 1 << 23,
4181	Float = 1 << 24,
4182	PickerHueBar = 1 << 25,
4183	PickerHueWheel = 1 << 26,
4184	InputRGB = 1 << 27,
4185	InputHSV = 1 << 28,
4186}
4187
4188impl ImGuiColorEditFlag {
4189	pub const DEFAULT_OPTIONS: BitFlags<Self> =
4190		make_bitflags!(Self::{Uint8 | DisplayRGB | InputRGB | PickerHueBar});
4191}
4192
4193#[derive(Copy, Clone, Debug, PartialEq)]
4194pub enum ImGuiCond {
4195	Always = 1 << 0,
4196	Once = 1 << 1,
4197	FirstUseEver = 1 << 2,
4198	Appearing = 1 << 3,
4199}
4200
4201#[bitflags]
4202#[repr(u32)]
4203#[derive(Copy, Clone, Debug, PartialEq)]
4204pub enum ImGuiTableFlag {
4205	Resizable = 1 << 0,
4206	Reorderable = 1 << 1,
4207	Hideable = 1 << 2,
4208	Sortable = 1 << 3,
4209	NoSavedSettings = 1 << 4,
4210	ContextMenuInBody = 1 << 5,
4211	RowBg = 1 << 6,
4212	BordersInnerH = 1 << 7,
4213	BordersOuterH = 1 << 8,
4214	BordersInnerV = 1 << 9,
4215	BordersOuterV = 1 << 10,
4216	NoBordersInBody = 1 << 11,
4217	NoBordersInBodyUntilResize = 1 << 12,
4218	SizingFixedFit = 1 << 13,
4219	SizingFixedSame = 1 << 14,
4220	SizingStretchSame = 1 << 15,
4221	NoHostExtendX = 1 << 16,
4222	NoHostExtendY = 1 << 17,
4223	NoKeepColumnsVisible = 1 << 18,
4224	PreciseWidths = 1 << 19,
4225	NoClip = 1 << 20,
4226	PadOuterX = 1 << 21,
4227	NoPadOuterX = 1 << 22,
4228	NoPadInnerX = 1 << 23,
4229	ScrollX = 1 << 24,
4230	ScrollY = 1 << 25,
4231	SortMulti = 1 << 26,
4232	SortTristate = 1 << 27,
4233	HighlightHoveredColumn = 1 << 28,
4234}
4235
4236impl ImGuiTableFlag {
4237	pub const BORDERS_H: BitFlags<Self> = make_bitflags!(Self::{BordersInnerH | BordersOuterH});
4238	pub const BORDERS_V: BitFlags<Self> = make_bitflags!(Self::{BordersInnerV | BordersOuterV});
4239	pub const BORDERS_INNER: BitFlags<Self> = make_bitflags!(Self::{BordersInnerV | BordersInnerH});
4240	pub const BORDERS_OUTER: BitFlags<Self> = make_bitflags!(Self::{BordersOuterV | BordersOuterH});
4241	pub const BORDERS: BitFlags<Self> =
4242		make_bitflags!(Self::{BordersInnerV | BordersInnerH | BordersOuterV | BordersOuterH});
4243	pub const SIZING_STRETCH_PROP: BitFlags<Self> =
4244		make_bitflags!(Self::{SizingFixedFit | SizingFixedSame});
4245}
4246
4247#[bitflags]
4248#[repr(u32)]
4249#[derive(Copy, Clone, Debug, PartialEq)]
4250pub enum ImGuiTableColumnFlag {
4251	Disabled = 1 << 0,
4252	DefaultHide = 1 << 1,
4253	DefaultSort = 1 << 2,
4254	WidthStretch = 1 << 3,
4255	WidthFixed = 1 << 4,
4256	NoResize = 1 << 5,
4257	NoReorder = 1 << 6,
4258	NoHide = 1 << 7,
4259	NoClip = 1 << 8,
4260	NoSort = 1 << 9,
4261	NoSortAscending = 1 << 10,
4262	NoSortDescending = 1 << 11,
4263	NoHeaderLabel = 1 << 12,
4264	NoHeaderWidth = 1 << 13,
4265	PreferSortAscending = 1 << 14,
4266	PreferSortDescending = 1 << 15,
4267	IndentEnable = 1 << 16,
4268	IndentDisable = 1 << 17,
4269	AngledHeader = 1 << 18,
4270	IsEnabled = 1 << 24,
4271	IsVisible = 1 << 25,
4272	IsSorted = 1 << 26,
4273	IsHovered = 1 << 27,
4274}
4275
4276#[derive(Copy, Clone, Debug, PartialEq)]
4277pub enum ImGuiPopupButton {
4278	MouseButtonLeft = 0,
4279	MouseButtonRight = 1,
4280	MouseButtonMiddle = 2,
4281}
4282
4283#[bitflags]
4284#[repr(u32)]
4285#[derive(Copy, Clone, Debug, PartialEq)]
4286pub enum ImGuiPopupFlag {
4287	NoReopen = 1 << 5,
4288	NoOpenOverExistingPopup = 1 << 7,
4289	NoOpenOverItems = 1 << 8,
4290	AnyPopupId = 1 << 10,
4291	AnyPopupLevel = 1 << 11,
4292}
4293
4294impl ImGuiPopupFlag {
4295	pub const ANY_POPUP: BitFlags<Self> = make_bitflags!(Self::{AnyPopupId | AnyPopupLevel});
4296}
4297
4298#[derive(Copy, Clone, Debug, PartialEq)]
4299pub enum ImGuiStyleVar {
4300	Alpha = 0,
4301	DisabledAlpha = 1,
4302	WindowRounding = 3,
4303	WindowBorderSize = 4,
4304	ChildRounding = 7,
4305	ChildBorderSize = 8,
4306	PopupRounding = 9,
4307	PopupBorderSize = 10,
4308	FrameRounding = 12,
4309	FrameBorderSize = 13,
4310	IndentSpacing = 16,
4311	ScrollbarSize = 18,
4312	ScrollbarRounding = 19,
4313	GrabMinSize = 20,
4314	GrabRounding = 21,
4315	TabRounding = 22,
4316	TabBarBorderSize = 23,
4317	SeparatorTextBorderSize = 26,
4318}
4319
4320#[derive(Copy, Clone, Debug, PartialEq)]
4321pub enum ImGuiStyleVec2 {
4322	WindowPadding = 2,
4323	WindowMinSize = 5,
4324	WindowTitleAlign = 6,
4325	FramePadding = 11,
4326	ItemSpacing = 14,
4327	ItemInnerSpacing = 15,
4328	CellPadding = 17,
4329	ButtonTextAlign = 24,
4330	SelectableTextAlign = 25,
4331	SeparatorTextAlign = 27,
4332	SeparatorTextPadding = 28,
4333}
4334
4335#[bitflags]
4336#[repr(u32)]
4337#[derive(Copy, Clone, Debug, PartialEq)]
4338pub enum ImGuiItemFlag {
4339	NoTabStop = 1 << 0,
4340	NoNav = 1 << 1,
4341	NoNavDefaultFocus = 1 << 2,
4342	ButtonRepeat = 1 << 3,
4343	AutoClosePopups = 1 << 4,
4344	AllowDuplicateId = 1 << 5,
4345}
4346
4347#[bitflags]
4348#[repr(u8)]
4349#[derive(Copy, Clone, Debug, PartialEq)]
4350pub enum ImGuiTableRowFlag {
4351	Headers = 1 << 0,
4352}
4353
4354#[bitflags]
4355#[repr(u32)]
4356#[derive(Copy, Clone, Debug, PartialEq)]
4357pub enum ImGuiTabBarFlag {
4358	Reorderable = 1 << 0,
4359	AutoSelectNewTabs = 1 << 1,
4360	TabListPopupButton = 1 << 2,
4361	NoCloseWithMiddleMouseButton = 1 << 3,
4362	NoTabListScrollingButtons = 1 << 4,
4363	NoTooltip = 1 << 5,
4364	DrawSelectedOverline = 1 << 6,
4365	FittingPolicyShrink = 1 << 7,
4366	FittingPolicyScroll = 1 << 8,
4367}
4368
4369#[bitflags]
4370#[repr(u32)]
4371#[derive(Copy, Clone, Debug, PartialEq)]
4372pub enum ImGuiTabItemFlag {
4373	UnsavedDocument = 1 << 0,
4374	SetSelected = 1 << 1,
4375	NoCloseWithMiddleMouseButton = 1 << 2,
4376	NoPushId = 1 << 3,
4377	NoTooltip = 1 << 4,
4378	NoReorder = 1 << 5,
4379	Leading = 1 << 6,
4380	Trailing = 1 << 7,
4381	NoAssumedClosure = 1 << 8,
4382}
4383
4384thread_local! {
4385	static IMGUI_STACK: RefCell<CallStack> = RefCell::new(CallStack::new());
4386}
4387
4388impl ImGui {
4389	pub fn begin<C>(name: &str, inside: C)
4390	where
4391		C: FnOnce(),
4392	{
4393		ImGui::begin_opts(name, BitFlags::default(), inside);
4394	}
4395	pub fn begin_opts<C>(name: &str, windows_flags: BitFlags<ImGuiWindowFlag>, inside: C)
4396	where
4397		C: FnOnce(),
4398	{
4399		if ImGui::_begin_opts(name, windows_flags.bits() as i32) {
4400			inside();
4401		}
4402		ImGui::_end();
4403	}
4404	pub fn begin_ret<C>(name: &str, opened: bool, inside: C) -> bool
4405	where
4406		C: FnOnce(),
4407	{
4408		ImGui::begin_ret_opts(name, opened, BitFlags::default(), inside)
4409	}
4410	pub fn begin_ret_opts<C>(
4411		name: &str,
4412		opened: bool,
4413		windows_flags: BitFlags<ImGuiWindowFlag>,
4414		inside: C,
4415	) -> bool
4416	where
4417		C: FnOnce(),
4418	{
4419		let mut changed = false;
4420		let mut result = false;
4421		IMGUI_STACK.with_borrow_mut(|stack| {
4422			stack.push_bool(opened);
4423			changed = ImGui::_begin_ret_opts(name, stack, windows_flags.bits() as i32);
4424			result = stack.pop_bool().unwrap();
4425		});
4426		if result {
4427			inside();
4428		}
4429		ImGui::_end();
4430		changed
4431	}
4432	pub fn begin_child<C>(str_id: &str, inside: C)
4433	where
4434		C: FnOnce(),
4435	{
4436		ImGui::begin_child_opts(
4437			str_id,
4438			&Vec2::zero(),
4439			BitFlags::default(),
4440			BitFlags::default(),
4441			inside,
4442		);
4443	}
4444	pub fn begin_child_opts<C>(
4445		str_id: &str,
4446		size: &crate::dora::Vec2,
4447		child_flags: BitFlags<ImGuiChildFlag>,
4448		window_flags: BitFlags<ImGuiWindowFlag>,
4449		inside: C,
4450	) where
4451		C: FnOnce(),
4452	{
4453		if ImGui::_begin_child_opts(
4454			str_id,
4455			size,
4456			child_flags.bits() as i32,
4457			window_flags.bits() as i32,
4458		) {
4459			inside();
4460		}
4461		ImGui::_end_child();
4462	}
4463	pub fn begin_child_with_id<C>(id: i32, inside: C)
4464	where
4465		C: FnOnce(),
4466	{
4467		ImGui::begin_child_with_id_opts(
4468			id,
4469			&Vec2::zero(),
4470			BitFlags::default(),
4471			BitFlags::default(),
4472			inside,
4473		);
4474	}
4475	pub fn begin_child_with_id_opts<C>(
4476		id: i32,
4477		size: &crate::dora::Vec2,
4478		child_flags: BitFlags<ImGuiChildFlag>,
4479		window_flags: BitFlags<ImGuiWindowFlag>,
4480		inside: C,
4481	) where
4482		C: FnOnce(),
4483	{
4484		if ImGui::_begin_child_with_id_opts(
4485			id,
4486			size,
4487			child_flags.bits() as i32,
4488			window_flags.bits() as i32,
4489		) {
4490			inside();
4491		}
4492		ImGui::_end_child();
4493	}
4494	pub fn collapsing_header_ret(label: &str, opened: bool) -> (bool, bool) {
4495		ImGui::collapsing_header_ret_opts(label, opened, BitFlags::default())
4496	}
4497	pub fn collapsing_header_ret_opts(
4498		label: &str,
4499		opened: bool,
4500		tree_node_flags: BitFlags<ImGuiTreeNodeFlag>,
4501	) -> (bool, bool) {
4502		let mut changed = false;
4503		let mut result = false;
4504		IMGUI_STACK.with_borrow_mut(|stack| {
4505			stack.push_bool(opened);
4506			changed =
4507				ImGui::_collapsing_header_ret_opts(label, stack, tree_node_flags.bits() as i32);
4508			result = stack.pop_bool().unwrap();
4509		});
4510		(changed, result)
4511	}
4512	pub fn selectable_ret(label: &str, selected: bool) -> (bool, bool) {
4513		ImGui::selectable_ret_opts(label, selected, &Vec2::zero(), BitFlags::default())
4514	}
4515	pub fn selectable_ret_opts(
4516		label: &str,
4517		selected: bool,
4518		size: &crate::dora::Vec2,
4519		selectable_flags: BitFlags<ImGuiSelectableFlag>,
4520	) -> (bool, bool) {
4521		let mut changed = false;
4522		let mut result = false;
4523		IMGUI_STACK.with_borrow_mut(|stack| {
4524			stack.push_bool(selected);
4525			changed =
4526				ImGui::_selectable_ret_opts(label, stack, size, selectable_flags.bits() as i32);
4527			result = stack.pop_bool().unwrap();
4528		});
4529		(changed, result)
4530	}
4531	pub fn combo_ret(label: &str, current_item: i32, items: &Vec<&str>) -> (bool, i32) {
4532		ImGui::combo_ret_opts(label, current_item, items, -1)
4533	}
4534	pub fn combo_ret_opts(
4535		label: &str,
4536		current_item: i32,
4537		items: &Vec<&str>,
4538		height_in_items: i32,
4539	) -> (bool, i32) {
4540		let mut changed = false;
4541		let mut result = 0_i32;
4542		IMGUI_STACK.with_borrow_mut(|stack| {
4543			stack.push_i32(current_item);
4544			changed = ImGui::_combo_ret_opts(label, stack, items, height_in_items);
4545			result = stack.pop_i32().unwrap();
4546		});
4547		(changed, result)
4548	}
4549	pub fn drag_float_ret(
4550		label: &str,
4551		v: f32,
4552		v_speed: f32,
4553		v_min: f32,
4554		v_max: f32,
4555	) -> (bool, f32) {
4556		ImGui::drag_float_ret_opts(label, v, v_speed, v_min, v_max, "%.2f", BitFlags::default())
4557	}
4558	pub fn drag_float_ret_opts(
4559		label: &str,
4560		v: f32,
4561		v_speed: f32,
4562		v_min: f32,
4563		v_max: f32,
4564		display_format: &str,
4565		slider_flags: BitFlags<ImGuiSliderFlag>,
4566	) -> (bool, f32) {
4567		let mut changed = false;
4568		let mut result = 0_f32;
4569		IMGUI_STACK.with_borrow_mut(|stack| {
4570			stack.push_f32(v);
4571			changed = ImGui::_drag_float_ret_opts(
4572				label,
4573				stack,
4574				v_speed,
4575				v_min,
4576				v_max,
4577				display_format,
4578				slider_flags.bits() as i32,
4579			);
4580			result = stack.pop_f32().unwrap();
4581		});
4582		(changed, result)
4583	}
4584	pub fn drag_float2_ret(
4585		label: &str,
4586		v1: f32,
4587		v2: f32,
4588		v_speed: f32,
4589		v_min: f32,
4590		v_max: f32,
4591	) -> (bool, f32, f32) {
4592		ImGui::drag_float2_ret_opts(
4593			label,
4594			v1,
4595			v2,
4596			v_speed,
4597			v_min,
4598			v_max,
4599			"%.2f",
4600			BitFlags::default(),
4601		)
4602	}
4603	pub fn drag_float2_ret_opts(
4604		label: &str,
4605		v1: f32,
4606		v2: f32,
4607		v_speed: f32,
4608		v_min: f32,
4609		v_max: f32,
4610		display_format: &str,
4611		slider_flags: BitFlags<ImGuiSliderFlag>,
4612	) -> (bool, f32, f32) {
4613		let mut changed = false;
4614		let mut result1 = 0_f32;
4615		let mut result2 = 0_f32;
4616		IMGUI_STACK.with_borrow_mut(|stack| {
4617			stack.push_f32(v1);
4618			stack.push_f32(v2);
4619			changed = ImGui::_drag_float2_ret_opts(
4620				label,
4621				stack,
4622				v_speed,
4623				v_min,
4624				v_max,
4625				display_format,
4626				slider_flags.bits() as i32,
4627			);
4628			result1 = stack.pop_f32().unwrap();
4629			result2 = stack.pop_f32().unwrap();
4630		});
4631		(changed, result1, result2)
4632	}
4633	pub fn drag_int2_ret(
4634		label: &str,
4635		v1: i32,
4636		v2: i32,
4637		v_speed: f32,
4638		v_min: i32,
4639		v_max: i32,
4640	) -> (bool, i32, i32) {
4641		ImGui::drag_int2_ret_opts(label, v1, v2, v_speed, v_min, v_max, "%d", BitFlags::default())
4642	}
4643	pub fn drag_int2_ret_opts(
4644		label: &str,
4645		v1: i32,
4646		v2: i32,
4647		v_speed: f32,
4648		v_min: i32,
4649		v_max: i32,
4650		display_format: &str,
4651		slider_flags: BitFlags<ImGuiSliderFlag>,
4652	) -> (bool, i32, i32) {
4653		let mut changed = false;
4654		let mut result1 = 0_i32;
4655		let mut result2 = 0_i32;
4656		IMGUI_STACK.with_borrow_mut(|stack| {
4657			stack.push_i32(v1);
4658			stack.push_i32(v2);
4659			changed = ImGui::_drag_int2_ret_opts(
4660				label,
4661				stack,
4662				v_speed,
4663				v_min,
4664				v_max,
4665				display_format,
4666				slider_flags.bits() as i32,
4667			);
4668			result1 = stack.pop_i32().unwrap();
4669			result2 = stack.pop_i32().unwrap();
4670		});
4671		(changed, result1, result2)
4672	}
4673	pub fn input_float_ret(label: &str, v: f32) -> (bool, f32) {
4674		ImGui::input_float_ret_opts(label, v, 0.0, 0.0, "%.2f", BitFlags::default())
4675	}
4676	pub fn input_float_ret_opts(
4677		label: &str,
4678		v: f32,
4679		step: f32,
4680		step_fast: f32,
4681		display_format: &str,
4682		input_text_flags: BitFlags<ImGuiInputTextFlag>,
4683	) -> (bool, f32) {
4684		let mut changed = false;
4685		let mut result = 0_f32;
4686		IMGUI_STACK.with_borrow_mut(|stack| {
4687			stack.push_f32(v);
4688			changed = ImGui::_input_float_ret_opts(
4689				label,
4690				stack,
4691				step,
4692				step_fast,
4693				display_format,
4694				input_text_flags.bits() as i32,
4695			);
4696			result = stack.pop_f32().unwrap();
4697		});
4698		(changed, result)
4699	}
4700	pub fn input_float2_ret(label: &str, v1: f32, v2: f32) -> (bool, f32, f32) {
4701		ImGui::input_float2_ret_opts(label, v1, v2, "%.2f", BitFlags::default())
4702	}
4703	pub fn input_float2_ret_opts(
4704		label: &str,
4705		v1: f32,
4706		v2: f32,
4707		display_format: &str,
4708		input_text_flags: BitFlags<ImGuiInputTextFlag>,
4709	) -> (bool, f32, f32) {
4710		let mut changed = false;
4711		let mut result1 = 0_f32;
4712		let mut result2 = 0_f32;
4713		IMGUI_STACK.with_borrow_mut(|stack| {
4714			stack.push_f32(v1);
4715			stack.push_f32(v2);
4716			changed = ImGui::_input_float2_ret_opts(
4717				label,
4718				stack,
4719				display_format,
4720				input_text_flags.bits() as i32,
4721			);
4722			result1 = stack.pop_f32().unwrap();
4723			result2 = stack.pop_f32().unwrap();
4724		});
4725		(changed, result1, result2)
4726	}
4727	pub fn input_int_ret(label: &str, v: i32) -> (bool, i32) {
4728		ImGui::input_int_ret_opts(label, v, 1, 100, BitFlags::default())
4729	}
4730	pub fn input_int_ret_opts(
4731		label: &str,
4732		v: i32,
4733		step: i32,
4734		step_fast: i32,
4735		input_text_flags: BitFlags<ImGuiInputTextFlag>,
4736	) -> (bool, i32) {
4737		let mut changed = false;
4738		let mut result = 0_i32;
4739		IMGUI_STACK.with_borrow_mut(|stack| {
4740			stack.push_i32(v);
4741			changed = ImGui::_input_int_ret_opts(
4742				label,
4743				stack,
4744				step,
4745				step_fast,
4746				input_text_flags.bits() as i32,
4747			);
4748			result = stack.pop_i32().unwrap();
4749		});
4750		(changed, result)
4751	}
4752	pub fn input_int2_ret(label: &str, v1: i32, v2: i32) -> (bool, i32, i32) {
4753		ImGui::input_int2_ret_opts(label, v1, v2, BitFlags::default())
4754	}
4755	pub fn input_int2_ret_opts(
4756		label: &str,
4757		v1: i32,
4758		v2: i32,
4759		input_text_flags: BitFlags<ImGuiInputTextFlag>,
4760	) -> (bool, i32, i32) {
4761		let mut changed = false;
4762		let mut result1 = 0_i32;
4763		let mut result2 = 0_i32;
4764		IMGUI_STACK.with_borrow_mut(|stack| {
4765			stack.push_i32(v1);
4766			stack.push_i32(v2);
4767			changed = ImGui::_input_int2_ret_opts(label, stack, input_text_flags.bits() as i32);
4768			result1 = stack.pop_i32().unwrap();
4769			result2 = stack.pop_i32().unwrap();
4770		});
4771		(changed, result1, result2)
4772	}
4773	pub fn slider_float_ret(label: &str, v: f32, v_min: f32, v_max: f32) -> (bool, f32) {
4774		ImGui::slider_float_ret_opts(label, v, v_min, v_max, "%.2f", BitFlags::default())
4775	}
4776	pub fn slider_float_ret_opts(
4777		label: &str,
4778		v: f32,
4779		v_min: f32,
4780		v_max: f32,
4781		display_format: &str,
4782		slider_flags: BitFlags<ImGuiSliderFlag>,
4783	) -> (bool, f32) {
4784		let mut changed = false;
4785		let mut result = 0_f32;
4786		IMGUI_STACK.with_borrow_mut(|stack| {
4787			stack.push_f32(v);
4788			changed = ImGui::_slider_float_ret_opts(
4789				label,
4790				stack,
4791				v_min,
4792				v_max,
4793				display_format,
4794				slider_flags.bits() as i32,
4795			);
4796			result = stack.pop_f32().unwrap();
4797		});
4798		(changed, result)
4799	}
4800	pub fn slider_float2_ret(
4801		label: &str,
4802		v1: f32,
4803		v2: f32,
4804		v_min: f32,
4805		v_max: f32,
4806	) -> (bool, f32, f32) {
4807		ImGui::slider_float2_ret_opts(label, v1, v2, v_min, v_max, "%.2f", BitFlags::default())
4808	}
4809	pub fn slider_float2_ret_opts(
4810		label: &str,
4811		v1: f32,
4812		v2: f32,
4813		v_min: f32,
4814		v_max: f32,
4815		display_format: &str,
4816		slider_flags: BitFlags<ImGuiSliderFlag>,
4817	) -> (bool, f32, f32) {
4818		let mut changed = false;
4819		let mut result1 = 0_f32;
4820		let mut result2 = 0_f32;
4821		IMGUI_STACK.with_borrow_mut(|stack| {
4822			stack.push_f32(v1);
4823			stack.push_f32(v2);
4824			changed = ImGui::_slider_float2_ret_opts(
4825				label,
4826				stack,
4827				v_min,
4828				v_max,
4829				display_format,
4830				slider_flags.bits() as i32,
4831			);
4832			result1 = stack.pop_f32().unwrap();
4833			result2 = stack.pop_f32().unwrap();
4834		});
4835		(changed, result1, result2)
4836	}
4837	pub fn drag_float_range2_ret(
4838		label: &str,
4839		v_current_min: f32,
4840		v_current_max: f32,
4841		v_speed: f32,
4842		v_min: f32,
4843		v_max: f32,
4844	) -> (bool, f32, f32) {
4845		ImGui::drag_float_range2_ret_opts(
4846			label,
4847			v_current_min,
4848			v_current_max,
4849			v_speed,
4850			v_min,
4851			v_max,
4852			"%.2f",
4853			"%.2f",
4854			BitFlags::default(),
4855		)
4856	}
4857	pub fn drag_float_range2_ret_opts(
4858		label: &str,
4859		v_current_min: f32,
4860		v_current_max: f32,
4861		v_speed: f32,
4862		v_min: f32,
4863		v_max: f32,
4864		format: &str,
4865		format_max: &str,
4866		slider_flags: BitFlags<ImGuiSliderFlag>,
4867	) -> (bool, f32, f32) {
4868		let mut changed = false;
4869		let mut result1 = 0_f32;
4870		let mut result2 = 0_f32;
4871		IMGUI_STACK.with_borrow_mut(|stack| {
4872			stack.push_f32(v_current_min);
4873			stack.push_f32(v_current_max);
4874			changed = ImGui::_drag_float_range2_ret_opts(
4875				label,
4876				stack,
4877				v_speed,
4878				v_min,
4879				v_max,
4880				format,
4881				format_max,
4882				slider_flags.bits() as i32,
4883			);
4884			result1 = stack.pop_f32().unwrap();
4885			result2 = stack.pop_f32().unwrap();
4886		});
4887		(changed, result1, result2)
4888	}
4889	pub fn drag_int_ret(
4890		label: &str,
4891		value: i32,
4892		v_speed: f32,
4893		v_min: i32,
4894		v_max: i32,
4895	) -> (bool, i32) {
4896		ImGui::drag_int_ret_opts(label, value, v_speed, v_min, v_max, "%d", BitFlags::default())
4897	}
4898	pub fn drag_int_ret_opts(
4899		label: &str,
4900		value: i32,
4901		v_speed: f32,
4902		v_min: i32,
4903		v_max: i32,
4904		display_format: &str,
4905		slider_flags: BitFlags<ImGuiSliderFlag>,
4906	) -> (bool, i32) {
4907		let mut changed = false;
4908		let mut result = 0_i32;
4909		IMGUI_STACK.with_borrow_mut(|stack| {
4910			stack.push_i32(value);
4911			changed = ImGui::_drag_int_ret_opts(
4912				label,
4913				stack,
4914				v_speed,
4915				v_min,
4916				v_max,
4917				display_format,
4918				slider_flags.bits() as i32,
4919			);
4920			result = stack.pop_i32().unwrap();
4921		});
4922		(changed, result)
4923	}
4924	pub fn drag_int_range2_ret(
4925		label: &str,
4926		v_current_min: i32,
4927		v_current_max: i32,
4928		v_speed: f32,
4929		v_min: i32,
4930		v_max: i32,
4931	) -> (bool, i32, i32) {
4932		ImGui::drag_int_range2_ret_opts(
4933			label,
4934			v_current_min,
4935			v_current_max,
4936			v_speed,
4937			v_min,
4938			v_max,
4939			"%d",
4940			"%d",
4941			BitFlags::default(),
4942		)
4943	}
4944	pub fn drag_int_range2_ret_opts(
4945		label: &str,
4946		v_current_min: i32,
4947		v_current_max: i32,
4948		v_speed: f32,
4949		v_min: i32,
4950		v_max: i32,
4951		format: &str,
4952		format_max: &str,
4953		slider_flags: BitFlags<ImGuiSliderFlag>,
4954	) -> (bool, i32, i32) {
4955		let mut changed = false;
4956		let mut result1 = 0_i32;
4957		let mut result2 = 0_i32;
4958		IMGUI_STACK.with_borrow_mut(|stack| {
4959			stack.push_i32(v_current_min);
4960			stack.push_i32(v_current_max);
4961			changed = ImGui::_drag_int_range2_ret_opts(
4962				label,
4963				stack,
4964				v_speed,
4965				v_min,
4966				v_max,
4967				format,
4968				format_max,
4969				slider_flags.bits() as i32,
4970			);
4971			result1 = stack.pop_i32().unwrap();
4972			result2 = stack.pop_i32().unwrap();
4973		});
4974		(changed, result1, result2)
4975	}
4976	pub fn slider_int_ret(label: &str, value: i32, v_min: i32, v_max: i32) -> (bool, i32) {
4977		ImGui::slider_int_ret_opts(label, value, v_min, v_max, "%d", BitFlags::default())
4978	}
4979	pub fn slider_int_ret_opts(
4980		label: &str,
4981		value: i32,
4982		v_min: i32,
4983		v_max: i32,
4984		format: &str,
4985		slider_flags: BitFlags<ImGuiSliderFlag>,
4986	) -> (bool, i32) {
4987		let mut changed = false;
4988		let mut result = 0_i32;
4989		IMGUI_STACK.with_borrow_mut(|stack| {
4990			stack.push_i32(value);
4991			changed = ImGui::_slider_int_ret_opts(
4992				label,
4993				stack,
4994				v_min,
4995				v_max,
4996				format,
4997				slider_flags.bits() as i32,
4998			);
4999			result = stack.pop_i32().unwrap();
5000		});
5001		(changed, result)
5002	}
5003	pub fn slider_int2_ret(
5004		label: &str,
5005		v1: i32,
5006		v2: i32,
5007		v_min: i32,
5008		v_max: i32,
5009	) -> (bool, i32, i32) {
5010		ImGui::slider_int2_ret_opts(label, v1, v2, v_min, v_max, "%d", BitFlags::default())
5011	}
5012	pub fn slider_int2_ret_opts(
5013		label: &str,
5014		v1: i32,
5015		v2: i32,
5016		v_min: i32,
5017		v_max: i32,
5018		display_format: &str,
5019		slider_flags: BitFlags<ImGuiSliderFlag>,
5020	) -> (bool, i32, i32) {
5021		let mut changed = false;
5022		let mut result1 = 0_i32;
5023		let mut result2 = 0_i32;
5024		IMGUI_STACK.with_borrow_mut(|stack| {
5025			stack.push_i32(v1);
5026			stack.push_i32(v2);
5027			changed = ImGui::_slider_int2_ret_opts(
5028				label,
5029				stack,
5030				v_min,
5031				v_max,
5032				display_format,
5033				slider_flags.bits() as i32,
5034			);
5035			result1 = stack.pop_i32().unwrap();
5036			result2 = stack.pop_i32().unwrap();
5037		});
5038		(changed, result1, result2)
5039	}
5040	pub fn v_slider_float_ret(
5041		label: &str,
5042		size: &crate::dora::Vec2,
5043		v: f32,
5044		v_min: f32,
5045		v_max: f32,
5046	) -> (bool, f32) {
5047		ImGui::v_slider_float_ret_opts(label, size, v, v_min, v_max, "%.2f", BitFlags::default())
5048	}
5049	pub fn v_slider_float_ret_opts(
5050		label: &str,
5051		size: &crate::dora::Vec2,
5052		v: f32,
5053		v_min: f32,
5054		v_max: f32,
5055		format: &str,
5056		slider_flags: BitFlags<ImGuiSliderFlag>,
5057	) -> (bool, f32) {
5058		let mut changed = false;
5059		let mut result = 0_f32;
5060		IMGUI_STACK.with_borrow_mut(|stack| {
5061			stack.push_f32(v);
5062			changed = ImGui::_v_slider_float_ret_opts(
5063				label,
5064				size,
5065				stack,
5066				v_min,
5067				v_max,
5068				format,
5069				slider_flags.bits() as i32,
5070			);
5071			result = stack.pop_f32().unwrap();
5072		});
5073		(changed, result)
5074	}
5075	pub fn v_slider_int_ret(
5076		label: &str,
5077		size: &crate::dora::Vec2,
5078		v: i32,
5079		v_min: i32,
5080		v_max: i32,
5081	) -> (bool, i32) {
5082		ImGui::v_slider_int_ret_opts(label, size, v, v_min, v_max, "%d", BitFlags::default())
5083	}
5084	pub fn v_slider_int_ret_opts(
5085		label: &str,
5086		size: &crate::dora::Vec2,
5087		v: i32,
5088		v_min: i32,
5089		v_max: i32,
5090		format: &str,
5091		slider_flags: BitFlags<ImGuiSliderFlag>,
5092	) -> (bool, i32) {
5093		let mut changed = false;
5094		let mut result = 0_i32;
5095		IMGUI_STACK.with_borrow_mut(|stack| {
5096			stack.push_i32(v);
5097			changed = ImGui::_v_slider_int_ret_opts(
5098				label,
5099				size,
5100				stack,
5101				v_min,
5102				v_max,
5103				format,
5104				slider_flags.bits() as i32,
5105			);
5106			result = stack.pop_i32().unwrap();
5107		});
5108		(changed, result)
5109	}
5110	pub fn color_edit3_ret(label: &str, color3: &Color3) -> (bool, Color3) {
5111		ImGui::color_edit3_ret_opts(label, color3, BitFlags::default())
5112	}
5113	pub fn color_edit3_ret_opts(
5114		label: &str,
5115		color3: &Color3,
5116		color_edit_flags: BitFlags<ImGuiColorEditFlag>,
5117	) -> (bool, Color3) {
5118		let mut changed = false;
5119		let mut result = 0_i32;
5120		IMGUI_STACK.with_borrow_mut(|stack| {
5121			stack.push_i32(color3.to_rgb() as i32);
5122			changed = ImGui::_color_edit3_ret_opts(label, stack, color_edit_flags.bits() as i32);
5123			result = stack.pop_i32().unwrap();
5124		});
5125		(changed, Color3::new(result as u32))
5126	}
5127	pub fn color_edit4_ret(label: &str, color: &Color) -> (bool, Color) {
5128		ImGui::color_edit4_ret_opts(label, color, BitFlags::default())
5129	}
5130	pub fn color_edit4_ret_opts(
5131		label: &str,
5132		color: &Color,
5133		color_edit_flags: BitFlags<ImGuiColorEditFlag>,
5134	) -> (bool, Color) {
5135		let mut changed = false;
5136		let mut result = 0_i32;
5137		IMGUI_STACK.with_borrow_mut(|stack| {
5138			stack.push_i32(color.to_argb() as i32);
5139			changed = ImGui::_color_edit4_ret_opts(label, stack, color_edit_flags.bits() as i32);
5140			result = stack.pop_i32().unwrap();
5141		});
5142		(changed, Color::new(result as u32))
5143	}
5144	pub fn checkbox_ret(label: &str, checked: bool) -> (bool, bool) {
5145		let mut changed = false;
5146		let mut result = false;
5147		IMGUI_STACK.with_borrow_mut(|stack| {
5148			stack.push_bool(checked);
5149			changed = ImGui::_checkbox_ret(label, stack);
5150			result = stack.pop_bool().unwrap();
5151		});
5152		(changed, result)
5153	}
5154	pub fn radio_button_ret(label: &str, value: i32, v_button: i32) -> (bool, i32) {
5155		let mut changed = false;
5156		let mut result = 0_i32;
5157		IMGUI_STACK.with_borrow_mut(|stack| {
5158			stack.push_i32(value);
5159			changed = ImGui::_radio_button_ret(label, stack, v_button);
5160			result = stack.pop_i32().unwrap();
5161		});
5162		(changed, result)
5163	}
5164	pub fn list_box_ret(label: &str, current_item: i32, items: &Vec<&str>) -> (bool, i32) {
5165		ImGui::list_box_ret_opts(label, current_item, items, -1)
5166	}
5167	pub fn list_box_ret_opts(
5168		label: &str,
5169		current_item: i32,
5170		items: &Vec<&str>,
5171		height_in_items: i32,
5172	) -> (bool, i32) {
5173		let mut changed = false;
5174		let mut result = 0_i32;
5175		IMGUI_STACK.with_borrow_mut(|stack| {
5176			stack.push_i32(current_item);
5177			changed = ImGui::_list_box_ret_opts(label, stack, items, height_in_items);
5178			result = stack.pop_i32().unwrap();
5179		});
5180		(changed, result)
5181	}
5182	pub fn set_next_window_pos_center() {
5183		ImGui::set_next_window_pos_center_opts(ImGuiCond::Always);
5184	}
5185	pub fn set_next_window_pos_center_opts(set_cond: ImGuiCond) {
5186		ImGui::_set_next_window_pos_center_opts(set_cond as i32);
5187	}
5188	pub fn set_next_window_size(size: &crate::dora::Vec2) {
5189		ImGui::set_next_window_size_opts(size, ImGuiCond::Always);
5190	}
5191	pub fn set_next_window_size_opts(size: &crate::dora::Vec2, set_cond: ImGuiCond) {
5192		ImGui::_set_next_window_size_opts(size, set_cond as i32);
5193	}
5194	pub fn set_next_window_collapsed(collapsed: bool) {
5195		ImGui::set_next_window_collapsed_opts(collapsed, ImGuiCond::Always);
5196	}
5197	pub fn set_next_window_collapsed_opts(collapsed: bool, set_cond: ImGuiCond) {
5198		ImGui::_set_next_window_collapsed_opts(collapsed, set_cond as i32);
5199	}
5200	pub fn set_window_pos(name: &str, pos: &crate::dora::Vec2) {
5201		ImGui::set_window_pos_opts(name, pos, ImGuiCond::Always);
5202	}
5203	pub fn set_window_pos_opts(name: &str, pos: &crate::dora::Vec2, set_cond: ImGuiCond) {
5204		ImGui::_set_window_pos_opts(name, pos, set_cond as i32);
5205	}
5206	pub fn set_window_size(name: &str, size: &crate::dora::Vec2) {
5207		ImGui::set_window_size_opts(name, size, ImGuiCond::Always);
5208	}
5209	pub fn set_window_size_opts(name: &str, size: &crate::dora::Vec2, set_cond: ImGuiCond) {
5210		ImGui::_set_window_size_opts(name, size, set_cond as i32);
5211	}
5212	pub fn set_window_collapsed(name: &str, collapsed: bool) {
5213		ImGui::set_window_collapsed_opts(name, collapsed, ImGuiCond::Always);
5214	}
5215	pub fn set_window_collapsed_opts(name: &str, collapsed: bool, set_cond: ImGuiCond) {
5216		ImGui::_set_window_collapsed_opts(name, collapsed, set_cond as i32);
5217	}
5218	pub fn set_color_edit_options(color_edit_flags: BitFlags<ImGuiColorEditFlag>) {
5219		ImGui::_set_color_edit_options(color_edit_flags.bits() as i32);
5220	}
5221	pub fn input_text(label: &str, buffer: &crate::dora::Buffer) -> bool {
5222		ImGui::input_text_opts(label, buffer, BitFlags::default())
5223	}
5224	pub fn input_text_opts(
5225		label: &str,
5226		buffer: &crate::dora::Buffer,
5227		input_text_flags: BitFlags<ImGuiInputTextFlag>,
5228	) -> bool {
5229		ImGui::_input_text_opts(label, buffer, input_text_flags.bits() as i32)
5230	}
5231	pub fn input_text_multiline(
5232		label: &str,
5233		buffer: &crate::dora::Buffer,
5234		size: &crate::dora::Vec2,
5235	) -> bool {
5236		ImGui::input_text_multiline_opts(label, buffer, size, BitFlags::default())
5237	}
5238	pub fn input_text_multiline_opts(
5239		label: &str,
5240		buffer: &crate::dora::Buffer,
5241		size: &crate::dora::Vec2,
5242		input_text_flags: BitFlags<ImGuiInputTextFlag>,
5243	) -> bool {
5244		ImGui::_input_text_multiline_opts(label, buffer, size, input_text_flags.bits() as i32)
5245	}
5246	pub fn tree_push<C>(str_id: &str, inside: C)
5247	where
5248		C: FnOnce(),
5249	{
5250		ImGui::_tree_push(str_id);
5251		inside();
5252		ImGui::_tree_pop();
5253	}
5254	pub fn tree_node<C>(str_id: &str, text: &str, inside: C)
5255	where
5256		C: FnOnce(),
5257	{
5258		if ImGui::_tree_node(str_id, text) {
5259			inside();
5260			ImGui::_tree_pop();
5261		}
5262	}
5263	pub fn tree_node_ex<C>(label: &str, inside: C)
5264	where
5265		C: FnOnce(),
5266	{
5267		ImGui::tree_node_ex_opts(label, BitFlags::default(), inside)
5268	}
5269	pub fn tree_node_ex_opts<C>(
5270		label: &str,
5271		tree_node_flags: BitFlags<ImGuiTreeNodeFlag>,
5272		inside: C,
5273	) where
5274		C: FnOnce(),
5275	{
5276		if ImGui::_tree_node_ex_opts(label, tree_node_flags.bits() as i32) {
5277			inside();
5278			ImGui::_tree_pop();
5279		}
5280	}
5281	pub fn tree_node_ex_with_id<C>(str_id: &str, text: &str, inside: C)
5282	where
5283		C: FnOnce(),
5284	{
5285		ImGui::tree_node_ex_with_id_opts(str_id, text, BitFlags::default(), inside);
5286	}
5287	pub fn tree_node_ex_with_id_opts<C>(
5288		str_id: &str,
5289		text: &str,
5290		tree_node_flags: BitFlags<ImGuiTreeNodeFlag>,
5291		inside: C,
5292	) where
5293		C: FnOnce(),
5294	{
5295		if ImGui::_tree_node_ex_with_id_opts(str_id, text, tree_node_flags.bits() as i32) {
5296			inside();
5297			ImGui::_tree_pop();
5298		}
5299	}
5300	pub fn set_next_item_open(is_open: bool) {
5301		ImGui::set_next_item_open_opts(is_open, ImGuiCond::Always);
5302	}
5303	pub fn set_next_item_open_opts(is_open: bool, set_cond: ImGuiCond) {
5304		ImGui::_set_next_item_open_opts(is_open, set_cond as i32);
5305	}
5306	pub fn collapsing_header(label: &str) -> bool {
5307		ImGui::collapsing_header_opts(label, BitFlags::default())
5308	}
5309	pub fn collapsing_header_opts(
5310		label: &str,
5311		tree_node_flags: BitFlags<ImGuiTreeNodeFlag>,
5312	) -> bool {
5313		ImGui::_collapsing_header_opts(label, tree_node_flags.bits() as i32)
5314	}
5315	pub fn selectable(label: &str) -> bool {
5316		ImGui::selectable_opts(label, BitFlags::default())
5317	}
5318	pub fn selectable_opts(label: &str, selectable_flags: BitFlags<ImGuiSelectableFlag>) -> bool {
5319		ImGui::_selectable_opts(label, selectable_flags.bits() as i32)
5320	}
5321	pub fn begin_popup<C>(str_id: &str, inside: C)
5322	where
5323		C: FnOnce(),
5324	{
5325		if ImGui::_begin_popup(str_id) {
5326			inside();
5327			ImGui::_end_popup();
5328		}
5329	}
5330	pub fn begin_popup_modal<C>(name: &str, inside: C)
5331	where
5332		C: FnOnce(),
5333	{
5334		ImGui::begin_popup_modal_opts(name, BitFlags::default(), inside);
5335	}
5336	pub fn begin_popup_modal_opts<C>(
5337		name: &str,
5338		windows_flags: BitFlags<ImGuiWindowFlag>,
5339		inside: C,
5340	) where
5341		C: FnOnce(),
5342	{
5343		if ImGui::_begin_popup_modal_opts(name, windows_flags.bits() as i32) {
5344			inside();
5345			ImGui::_end_popup();
5346		}
5347	}
5348	pub fn begin_popup_modal_ret<C>(
5349		name: &str,
5350		opened: bool,
5351		inside: C,
5352	) -> (bool, bool)
5353	where
5354		C: FnOnce(),
5355	{
5356		ImGui::begin_popup_modal_ret_opts(name, opened, BitFlags::default(), inside)
5357	}
5358	pub fn begin_popup_modal_ret_opts<C>(
5359		name: &str,
5360		opened: bool,
5361		windows_flags: BitFlags<ImGuiWindowFlag>,
5362		inside: C,
5363	) -> (bool, bool)
5364	where
5365		C: FnOnce(),
5366	{
5367		let mut changed = false;
5368		let mut result = false;
5369		IMGUI_STACK.with_borrow_mut(|stack| {
5370			stack.push_bool(opened);
5371			changed = ImGui::_begin_popup_modal_ret_opts(name, stack, windows_flags.bits() as i32);
5372			result = stack.pop_bool().unwrap();
5373		});
5374		if changed {
5375			inside();
5376			ImGui::_end_popup();
5377		}
5378		(changed, result)
5379	}
5380	pub fn begin_popup_context_item<C>(name: &str, inside: C)
5381	where
5382		C: FnOnce(),
5383	{
5384		ImGui::begin_popup_context_item_opts(
5385			name,
5386			ImGuiPopupButton::MouseButtonRight,
5387			BitFlags::default(),
5388			inside,
5389		);
5390	}
5391	pub fn begin_popup_context_item_opts<C>(
5392		name: &str,
5393		button: ImGuiPopupButton,
5394		popup_flags: BitFlags<ImGuiPopupFlag>,
5395		inside: C,
5396	) where
5397		C: FnOnce(),
5398	{
5399		if ImGui::_begin_popup_context_item_opts(name, (button as u32 | popup_flags.bits()) as i32)
5400		{
5401			inside();
5402			ImGui::_end_popup();
5403		}
5404	}
5405	pub fn begin_popup_context_window<C>(name: &str, inside: C)
5406	where
5407		C: FnOnce(),
5408	{
5409		ImGui::begin_popup_context_window_opts(
5410			name,
5411			ImGuiPopupButton::MouseButtonRight,
5412			BitFlags::default(),
5413			inside,
5414		);
5415	}
5416	pub fn begin_popup_context_window_opts<C>(
5417		name: &str,
5418		button: ImGuiPopupButton,
5419		popup_flags: BitFlags<ImGuiPopupFlag>,
5420		inside: C,
5421	) where
5422		C: FnOnce(),
5423	{
5424		if ImGui::_begin_popup_context_window_opts(
5425			name,
5426			(button as u32 | popup_flags.bits()) as i32,
5427		) {
5428			inside();
5429			ImGui::_end_popup();
5430		}
5431	}
5432	pub fn begin_popup_context_void<C>(name: &str, inside: C)
5433	where
5434		C: FnOnce(),
5435	{
5436		ImGui::begin_popup_context_void_opts(
5437			name,
5438			ImGuiPopupButton::MouseButtonRight,
5439			BitFlags::default(),
5440			inside,
5441		);
5442	}
5443	pub fn begin_popup_context_void_opts<C>(
5444		name: &str,
5445		button: ImGuiPopupButton,
5446		popup_flags: BitFlags<ImGuiPopupFlag>,
5447		inside: C,
5448	) where
5449		C: FnOnce(),
5450	{
5451		if ImGui::_begin_popup_context_void_opts(name, (button as u32 | popup_flags.bits()) as i32)
5452		{
5453			inside();
5454			ImGui::_end_popup();
5455		}
5456	}
5457	pub fn begin_table<C>(str_id: &str, column: i32, inside: C)
5458	where
5459		C: FnOnce(),
5460	{
5461		ImGui::begin_table_opts(str_id, column, &Vec2::zero(), -1.0, BitFlags::default(), inside);
5462	}
5463	pub fn begin_table_opts<C>(
5464		str_id: &str,
5465		column: i32,
5466		outer_size: &crate::dora::Vec2,
5467		inner_width: f32,
5468		table_flags: BitFlags<ImGuiTableFlag>,
5469		inside: C,
5470	) where
5471		C: FnOnce(),
5472	{
5473		if ImGui::_begin_table_opts(
5474			str_id,
5475			column,
5476			outer_size,
5477			inner_width,
5478			table_flags.bits() as i32,
5479		) {
5480			inside();
5481			ImGui::_end_table();
5482		}
5483	}
5484	pub fn table_setup_column(label: &str, init_width_or_weight: f32) {
5485		ImGui::table_setup_column_opts(label, init_width_or_weight, 0, BitFlags::default())
5486	}
5487	pub fn table_setup_column_opts(
5488		label: &str,
5489		init_width_or_weight: f32,
5490		user_id: i32,
5491		table_column_flags: BitFlags<ImGuiTableColumnFlag>,
5492	) {
5493		ImGui::_table_setup_column_opts(
5494			label,
5495			init_width_or_weight,
5496			user_id,
5497			table_column_flags.bits() as i32,
5498		);
5499	}
5500	pub fn set_next_window_pos(pos: &crate::dora::Vec2) {
5501		ImGui::set_next_window_pos_opts(pos, ImGuiCond::Always, &Vec2::zero());
5502	}
5503	pub fn set_next_window_pos_opts(
5504		pos: &crate::dora::Vec2,
5505		set_cond: ImGuiCond,
5506		pivot: &crate::dora::Vec2,
5507	) {
5508		ImGui::_set_next_window_pos_opts(pos, set_cond as i32, pivot);
5509	}
5510	pub fn push_style_color<C>(col: ImGuiCol, color: &crate::dora::Color, inside: C)
5511	where
5512		C: FnOnce(),
5513	{
5514		ImGui::_push_style_color(col as i32, color);
5515		inside();
5516		ImGui::_pop_style_color(1);
5517	}
5518	pub fn push_style_float<C>(style: ImGuiStyleVar, val: f32, inside: C)
5519	where
5520		C: FnOnce(),
5521	{
5522		ImGui::_push_style_float(style as i32, val);
5523		inside();
5524		ImGui::_pop_style_var(1);
5525	}
5526	pub fn push_style_vec2<C>(style: ImGuiStyleVec2, val: &crate::dora::Vec2, inside: C)
5527	where
5528		C: FnOnce(),
5529	{
5530		ImGui::_push_style_vec2(style as i32, val);
5531		inside();
5532		ImGui::_pop_style_var(1);
5533	}
5534	pub fn color_button(desc_id: &str, col: &crate::dora::Color) -> bool {
5535		ImGui::color_button_opts(desc_id, col, BitFlags::default(), &Vec2::zero())
5536	}
5537	pub fn color_button_opts(
5538		desc_id: &str,
5539		col: &crate::dora::Color,
5540		color_edit_flags: BitFlags<ImGuiColorEditFlag>,
5541		size: &crate::dora::Vec2,
5542	) -> bool {
5543		ImGui::_color_button_opts(desc_id, col, color_edit_flags.bits() as i32, size)
5544	}
5545	pub fn slider_angle_ret(
5546		label: &str,
5547		v: f32,
5548		v_degrees_min: f32,
5549		v_degrees_max: f32,
5550	) -> (bool, f32) {
5551		let mut changed = false;
5552		let mut result = 0_f32;
5553		IMGUI_STACK.with_borrow_mut(|stack| {
5554			stack.push_f32(v);
5555			changed = ImGui::_slider_angle_ret(label, stack, v_degrees_min, v_degrees_max);
5556			result = stack.pop_f32().unwrap();
5557		});
5558		(changed, result)
5559	}
5560	pub fn image_button(str_id: &str, clip_str: &str, size: &crate::dora::Vec2) -> bool {
5561		ImGui::image_button_opts(str_id, clip_str, size, &Color::TRANSPARENT, &Color::WHITE)
5562	}
5563	pub fn table_next_row() {
5564		ImGui::table_next_row_opts(0.0, BitFlags::default());
5565	}
5566	pub fn table_next_row_opts(min_row_height: f32, table_row_flags: BitFlags<ImGuiTableRowFlag>) {
5567		ImGui::_table_next_row_opts(min_row_height, table_row_flags.bits() as i32);
5568	}
5569	pub fn begin_list_box<C>(label: &str, size: &crate::dora::Vec2, inside: C)
5570	where
5571		C: FnOnce(),
5572	{
5573		if ImGui::_begin_list_box(label, size) {
5574			inside();
5575			ImGui::_end_list_box();
5576		}
5577	}
5578	pub fn begin_group<C>(inside: C)
5579	where
5580		C: FnOnce(),
5581	{
5582		ImGui::_begin_group();
5583		inside();
5584		ImGui::_end_group();
5585	}
5586	pub fn begin_disabled<C>(inside: C)
5587	where
5588		C: FnOnce(),
5589	{
5590		ImGui::_begin_disabled();
5591		inside();
5592		ImGui::_end_disabled();
5593	}
5594	pub fn begin_tooltip<C>(inside: C)
5595	where
5596		C: FnOnce(),
5597	{
5598		if ImGui::_begin_tooltip() {
5599			inside();
5600			ImGui::_end_tooltip();
5601		}
5602	}
5603	pub fn begin_main_menu_bar<C>(inside: C)
5604	where
5605		C: FnOnce(),
5606	{
5607		if ImGui::_begin_main_menu_bar() {
5608			inside();
5609			ImGui::_end_main_menu_bar();
5610		}
5611	}
5612	pub fn begin_menu_bar<C>(inside: C)
5613	where
5614		C: FnOnce(),
5615	{
5616		if ImGui::_begin_menu_bar() {
5617			inside();
5618			ImGui::_end_menu_bar();
5619		}
5620	}
5621	pub fn begin_menu<C>(label: &str, enabled: bool, inside: C)
5622	where
5623		C: FnOnce(),
5624	{
5625		if ImGui::_begin_menu(label, enabled) {
5626			inside();
5627			ImGui::_end_menu();
5628		}
5629	}
5630	pub fn push_item_width<C>(width: f32, inside: C)
5631	where
5632		C: FnOnce(),
5633	{
5634		ImGui::_push_item_width(width);
5635		inside();
5636		ImGui::_pop_item_width();
5637	}
5638	pub fn push_text_wrap_pos<C>(wrap_pos_x: f32, inside: C)
5639	where
5640		C: FnOnce(),
5641	{
5642		ImGui::_push_text_wrap_pos(wrap_pos_x);
5643		inside();
5644		ImGui::_pop_text_wrap_pos();
5645	}
5646	pub fn push_item_flag<C>(flags: BitFlags<ImGuiItemFlag>, v: bool, inside: C)
5647	where
5648		C: FnOnce(),
5649	{
5650		ImGui::_push_item_flag(flags.bits() as i32, v);
5651		inside();
5652		ImGui::_pop_item_flag();
5653	}
5654	pub fn push_id<C>(str_id: &str, inside: C)
5655	where
5656		C: FnOnce(),
5657	{
5658		ImGui::_push_id(str_id);
5659		inside();
5660		ImGui::_pop_id();
5661	}
5662	pub fn push_clip_rect<C>(
5663		clip_rect_min: &crate::dora::Vec2,
5664		clip_rect_max: &crate::dora::Vec2,
5665		intersect_with_current_clip_rect: bool,
5666		inside: C,
5667	) where
5668		C: FnOnce(),
5669	{
5670		ImGui::_push_clip_rect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect);
5671		inside();
5672		ImGui::_pop_clip_rect();
5673	}
5674	pub fn begin_tab_bar<C>(str_id: &str, inside: C)
5675	where
5676		C: FnOnce(),
5677	{
5678		if ImGui::_begin_tab_bar(str_id) {
5679			inside();
5680			ImGui::_end_tab_bar();
5681		}
5682	}
5683	pub fn begin_tab_bar_opts<C>(
5684		str_id: &str,
5685		flags: BitFlags<ImGuiTabBarFlag>,
5686		inside: C,
5687	) where
5688		C: FnOnce(),
5689	{
5690		if ImGui::_begin_tab_bar_opts(str_id, flags.bits() as i32) {
5691			inside();
5692			ImGui::_end_tab_bar();
5693		}
5694	}
5695	pub fn begin_tab_item<C>(label: &str, inside: C)
5696	where
5697		C: FnOnce(),
5698	{
5699		if ImGui::_begin_tab_item(label) {
5700			inside();
5701			ImGui::_end_tab_item();
5702		}
5703	}
5704	pub fn begin_tab_item_opts<C>(
5705		label: &str,
5706		flags: BitFlags<ImGuiTabItemFlag>,
5707		inside: C,
5708	) where
5709		C: FnOnce(),
5710	{
5711		if ImGui::_begin_tab_item_opts(label, flags.bits() as i32) {
5712			inside();
5713			ImGui::_end_tab_item();
5714		}
5715	}
5716	pub fn begin_tab_item_ret<C>(label: &str, opened: bool, inside: C) -> bool
5717	where
5718		C: FnOnce(),
5719	{
5720		let mut changed = false;
5721		let mut result = false;
5722		IMGUI_STACK.with_borrow_mut(|stack| {
5723			stack.push_bool(opened);
5724			result = ImGui::_begin_tab_item_ret(label, stack);
5725			changed = stack.pop_bool().unwrap();
5726		});
5727		if result {
5728			inside();
5729			ImGui::_end_tab_item();
5730		}
5731		changed
5732	}
5733	pub fn begin_tab_item_ret_opts<C>(
5734		label: &str,
5735		opened: bool,
5736		flags: BitFlags<ImGuiTabItemFlag>,
5737		inside: C,
5738	) -> bool
5739	where
5740		C: FnOnce(),
5741	{
5742		let mut changed = false;
5743		let mut result = false;
5744		IMGUI_STACK.with_borrow_mut(|stack| {
5745			stack.push_bool(opened);
5746			result = ImGui::_begin_tab_item_ret_opts(label, stack, flags.bits() as i32);
5747			changed = stack.pop_bool().unwrap();
5748		});
5749		if result {
5750			inside();
5751			ImGui::_end_tab_item();
5752		}
5753		changed
5754	}
5755	pub fn tab_item_button_opts(label: &str, flags: BitFlags<ImGuiTabItemFlag>) -> bool {
5756		ImGui::_tab_item_button_opts(label, flags.bits() as i32)
5757	}
5758}
5759
5760#[bitflags]
5761#[repr(u32)]
5762#[derive(Copy, Clone, Debug, PartialEq)]
5763pub enum NvgImageFlag {
5764	/// Generate mipmaps during creation of the image.
5765	GenerateMipmaps = 1 << 0,
5766	/// Repeat image in X direction.
5767	RepeatX = 1 << 1,
5768	/// Repeat image in Y direction.
5769	RepeatY = 1 << 2,
5770	/// Flips (inverses) image in Y direction when rendered.
5771	FlipY = 1 << 3,
5772	/// Image data has premultiplied alpha.
5773	Premultiplied = 1 << 4,
5774	/// Image interpolation is Nearest instead Linear
5775	Nearest = 1 << 5,
5776}
5777
5778#[repr(i32)]
5779#[derive(Copy, Clone, Debug, PartialEq)]
5780pub enum NvgLineCap {
5781	Butt = 0,
5782	Round = 1,
5783	Square = 2,
5784}
5785
5786#[repr(i32)]
5787#[derive(Copy, Clone, Debug, PartialEq)]
5788pub enum NvgLineJoin {
5789	Round = 1,
5790	Bevel = 3,
5791	Miter = 4,
5792}
5793
5794#[repr(i32)]
5795#[derive(Copy, Clone, Debug, PartialEq)]
5796pub enum NvgWinding {
5797	/// Winding for solid shapes
5798	CCW = 1,
5799	/// Winding for holes
5800	CW = 2,
5801}
5802impl NvgWinding {
5803	pub const SOLID: NvgWinding = NvgWinding::CCW;
5804	pub const HOLE: NvgWinding = NvgWinding::CW;
5805}
5806
5807#[repr(i32)]
5808#[derive(Copy, Clone, Debug, PartialEq)]
5809pub enum NvgArcDir {
5810	CCW = 1,
5811	CW = 2,
5812}
5813
5814#[repr(i32)]
5815#[derive(Copy, Clone, Debug, PartialEq)]
5816pub enum NvgHAlign {
5817	/// Default, align text horizontally to left.
5818	Left = 1 << 0,
5819	/// Align text horizontally to center.
5820	Center = 1 << 1,
5821	/// Align text horizontally to right.
5822	Right = 1 << 2,
5823}
5824
5825#[repr(i32)]
5826#[derive(Copy, Clone, Debug, PartialEq)]
5827pub enum NvgVAlign {
5828	/// Align text vertically to top.
5829	Top = 1 << 3,
5830	/// Align text vertically to middle.
5831	Middle = 1 << 4,
5832	/// Align text vertically to bottom.
5833	Bottom = 1 << 5,
5834	/// Default, align text vertically to baseline.
5835	BaseLine = 1 << 6,
5836}
5837
5838impl Nvg {
5839	pub fn create_image(
5840		w: i32,
5841		h: i32,
5842		filename: &str,
5843		image_flags: BitFlags<NvgImageFlag>,
5844	) -> i32 {
5845		Nvg::_create_image(w, h, filename, image_flags.bits() as i32)
5846	}
5847	pub fn line_cap(cap: NvgLineCap) {
5848		Nvg::_line_cap(cap as i32);
5849	}
5850	pub fn line_join(join: NvgLineJoin) {
5851		Nvg::_line_join(join as i32);
5852	}
5853	pub fn path_winding(winding: NvgWinding) {
5854		Nvg::_path_winding(winding as i32);
5855	}
5856	pub fn arc(x: f32, y: f32, r: f32, a0: f32, a1: f32, dir: NvgArcDir) {
5857		Nvg::_arc(x, y, r, a0, a1, dir as i32);
5858	}
5859	pub fn text_align(h_align: NvgHAlign, v_align: NvgVAlign) {
5860		Nvg::_text_align(h_align as i32, v_align as i32);
5861	}
5862}
5863
5864// math
5865
5866extern "C" {
5867	fn math_abs(v: f64) -> f64;
5868	fn math_acos(v: f32) -> f32;
5869	fn math_asin(v: f32) -> f32;
5870	fn math_atan(v: f32) -> f32;
5871	fn math_atan2(y: f32, x: f32) -> f32;
5872	fn math_ceil(v: f32) -> f32;
5873	fn math_cos(v: f32) -> f32;
5874	fn math_deg(v: f32) -> f32;
5875	fn math_exp(v: f32) -> f32;
5876	fn math_floor(v: f32) -> f32;
5877	fn math_fmod(x: f32, y: f32) -> f32;
5878	fn math_log(v: f32) -> f32;
5879	fn math_rad(v: f32) -> f32;
5880	fn math_sin(v: f32) -> f32;
5881	fn math_sqrt(v: f32) -> f32;
5882	fn math_tan(v: f32) -> f32;
5883}
5884
5885pub struct Math {}
5886
5887impl Math {
5888	pub const PI: f32 = std::f32::consts::PI;
5889	pub fn abs(v: f64) -> f64 {
5890		unsafe { math_abs(v) }
5891	}
5892	pub fn acos(v: f32) -> f32 {
5893		unsafe { math_acos(v) }
5894	}
5895	pub fn asin(v: f32) -> f32 {
5896		unsafe { math_asin(v) }
5897	}
5898	pub fn atan(v: f32) -> f32 {
5899		unsafe { math_atan(v) }
5900	}
5901	pub fn atan2(y: f32, x: f32) -> f32 {
5902		unsafe { math_atan2(y, x) }
5903	}
5904	pub fn ceil(v: f32) -> f32 {
5905		unsafe { math_ceil(v) }
5906	}
5907	pub fn cos(v: f32) -> f32 {
5908		unsafe { math_cos(v) }
5909	}
5910	pub fn deg(v: f32) -> f32 {
5911		unsafe { math_deg(v) }
5912	}
5913	pub fn exp(v: f32) -> f32 {
5914		unsafe { math_exp(v) }
5915	}
5916	pub fn floor(v: f32) -> f32 {
5917		unsafe { math_floor(v) }
5918	}
5919	pub fn fmod(x: f32, y: f32) -> f32 {
5920		unsafe { math_fmod(x, y) }
5921	}
5922	pub fn log(v: f32) -> f32 {
5923		unsafe { math_log(v) }
5924	}
5925	pub fn rad(v: f32) -> f32 {
5926		unsafe { math_rad(v) }
5927	}
5928	pub fn sin(v: f32) -> f32 {
5929		unsafe { math_sin(v) }
5930	}
5931	pub fn sqrt(v: f32) -> f32 {
5932		unsafe { math_sqrt(v) }
5933	}
5934	pub fn tan(v: f32) -> f32 {
5935		unsafe { math_tan(v) }
5936	}
5937}
5938
5939use std::future::Future;
5940use std::pin::Pin;
5941use std::task::{Context, Poll};
5942
5943enum State {
5944	Halted,
5945	Running,
5946}
5947
5948pub struct Coroutine {
5949	state: State,
5950}
5951
5952impl Coroutine {
5953	pub fn waiter<'a>(&'a mut self) -> Waiter<'a> {
5954		Waiter { co: self }
5955	}
5956}
5957
5958pub struct Waiter<'a> {
5959	co: &'a mut Coroutine,
5960}
5961
5962impl<'a> Future for Waiter<'a> {
5963	type Output = ();
5964
5965	fn poll(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> {
5966		match self.co.state {
5967			State::Halted => {
5968				self.co.state = State::Running;
5969				Poll::Ready(())
5970			}
5971			State::Running => {
5972				self.co.state = State::Halted;
5973				Poll::Pending
5974			}
5975		}
5976	}
5977}
5978
5979use std::task::{RawWaker, RawWakerVTable, Waker};
5980
5981fn create_waker() -> Waker {
5982	unsafe { Waker::from_raw(RAW_WAKER) }
5983}
5984
5985const RAW_WAKER: RawWaker = RawWaker::new(std::ptr::null(), &VTABLE);
5986const VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake_by_ref, drop);
5987
5988unsafe fn clone(_: *const ()) -> RawWaker {
5989	RAW_WAKER
5990}
5991unsafe fn wake(_: *const ()) {}
5992unsafe fn wake_by_ref(_: *const ()) {}
5993unsafe fn drop(_: *const ()) {}
5994
5995struct Executor {
5996	co: Pin<Box<dyn Future<Output = ()>>>,
5997}
5998
5999impl Executor {
6000	fn new<C, F>(closure: C) -> Self
6001	where
6002		F: Future<Output = ()> + 'static,
6003		C: FnOnce(Coroutine) -> F,
6004	{
6005		let co = Coroutine { state: State::Running };
6006		Executor { co: Box::pin(closure(co)) }
6007	}
6008
6009	fn update(&mut self) -> bool {
6010		let waker = create_waker();
6011		let mut context = Context::from_waker(&waker);
6012		match self.co.as_mut().poll(&mut context) {
6013			Poll::Pending => false,
6014			Poll::Ready(()) => true,
6015		}
6016	}
6017}
6018
6019pub fn once<C, F>(closure: C) -> Box<dyn FnMut(f64) -> bool>
6020where
6021	F: Future<Output = ()> + 'static,
6022	C: FnOnce(Coroutine) -> F,
6023{
6024	let mut executor = Executor::new(closure);
6025	Box::new(move |_| executor.update())
6026}
6027
6028pub fn thread<C, F>(closure: C)
6029where
6030	F: Future<Output = ()> + 'static,
6031	C: FnOnce(Coroutine) -> F,
6032{
6033	let mut executor = Executor::new(closure);
6034	Director::schedule_posted(Box::new(move |_| executor.update()));
6035}
6036
6037#[macro_export]
6038macro_rules! sleep {
6039	($co:expr, $time:expr) => {{
6040		let total = $time;
6041		let mut time: f32 = 0.0;
6042		while time <= total {
6043			time += dora_ssr::App::get_delta_time() as f32;
6044			$co.waiter().await;
6045		}
6046	}};
6047}
6048
6049#[macro_export]
6050macro_rules! cycle {
6051	($co:expr, $time:expr, $closure:expr) => {{
6052		let total = $time;
6053		let mut time: f32 = 0.0;
6054		loop {
6055			$closure(f32::min(time / $time, 1.0));
6056			if time >= total {
6057				break;
6058			}
6059			$co.waiter().await;
6060			time += dora_ssr::App::get_delta_time() as f32;
6061		}
6062	}};
6063}
6064
6065#[macro_export]
6066macro_rules! wait {
6067	($co:expr, $condition:expr) => {
6068		while !$condition {
6069			$co.waiter().await;
6070		}
6071	};
6072}