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