1use 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
349pub 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#[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#[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#[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#[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
897pub 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
1061pub 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
1195impl 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 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 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 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 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 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 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 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 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 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 pub fn pop_into_node(&mut self) -> Option<Node> {
1343 Node::cast(self.pop_object()?.as_ref())
1344 }
1345 pub fn pop_into_camera(&mut self) -> Option<Camera> {
1348 Camera::cast(self.pop_object()?.as_ref())
1349 }
1350 pub fn pop_into_playable(&mut self) -> Option<Playable> {
1353 Playable::cast(self.pop_object()?.as_ref())
1354 }
1355 pub fn pop_into_physics_world(&mut self) -> Option<PhysicsWorld> {
1358 PhysicsWorld::cast(self.pop_object()?.as_ref())
1359 }
1360 pub fn pop_into_body(&mut self) -> Option<Body> {
1363 Body::cast(self.pop_object()?.as_ref())
1364 }
1365 pub fn pop_into_joint(&mut self) -> Option<Joint> {
1368 Joint::cast(self.pop_object()?.as_ref())
1369 }
1370 pub fn pop_cast<T: Clone + 'static>(&mut self) -> Option<T> {
1373 cast::<T>(self.pop_object()?.as_ref())
1374 }
1375 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
1393pub struct Slot {}
1395impl Slot {
1396 pub const ACTION_END: &'static str = "Action";
1422 pub const TAP_FILTER: &'static str = "TapFilter";
1442 pub const TAP_BEGAN: &'static str = "TapBegan";
1461 pub const TAP_ENDED: &'static str = "TapEnded";
1480 pub const TAPPED: &'static str = "Tapped";
1499 pub const TAP_MOVED: &'static str = "TapMoved";
1518 pub const MOUSE_WHEEL: &'static str = "MouseWheel";
1537 pub const GESTURE: &'static str = "Gesture";
1568 pub const ENTER: &'static str = "Enter";
1571 pub const EXIT: &'static str = "Exit";
1574 pub const CLEANUP: &'static str = "Cleanup";
1577 pub const KEY_DOWN: &'static str = "KeyDown";
1599 pub const KEY_UP: &'static str = "KeyUp";
1621 pub const KEY_PRESSED: &'static str = "KeyPressed";
1643 pub const ATTACH_IME: &'static str = "AttachIME";
1645 pub const DETACH_IME: &'static str = "DetachIME";
1647 pub const TEXT_INPUT: &'static str = "TextInput";
1667 pub const TEXT_EDITING: &'static str = "TextEditing";
1694 pub const BUTTON_DOWN: &'static str = "ButtonDown";
1723 pub const BUTTON_UP: &'static str = "ButtonUp";
1752 pub const BUTTON_PRESSED: &'static str = "ButtonPressed";
1782 pub const AXIS: &'static str = "Axis";
1813 pub const ANIMATION_END: &'static str = "AnimationEnd";
1841 pub const BODY_ENTER: &'static str = "BodyEnter";
1867 pub const BODY_LEAVE: &'static str = "BodyLeave";
1893 pub const CONTACT_START: &'static str = "ContactStart";
1925 pub const CONTACT_END: &'static str = "ContactEnd";
1954 pub const FINISHED: &'static str = "Finished";
1956 pub const ALIGN_LAYOUT: &'static str = "AlignLayout";
1981 pub const EFFEK_END: &'static str = "EffekEnd";
1999 pub fn on_action_end<F>(node: &mut dyn INode, mut callback: F)
2008 where
2009 F: FnMut(Action, 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 pub fn on_tap_filter<F>(node: &mut dyn INode, mut callback: F)
2030 where
2031 F: FnMut(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 pub fn on_tap_began<F>(node: &mut dyn INode, mut callback: F)
2053 where
2054 F: FnMut(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 pub fn on_tap_ended<F>(node: &mut dyn INode, mut callback: F)
2076 where
2077 F: FnMut(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 pub fn on_tapped<F>(node: &mut dyn INode, mut callback: F)
2099 where
2100 F: FnMut(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 pub fn on_tap_moved<F>(node: &mut dyn INode, mut callback: F)
2122 where
2123 F: FnMut(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 pub fn on_mouse_wheel<F>(node: &mut dyn INode, mut callback: F)
2145 where
2146 F: FnMut(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 pub fn on_gesture<F>(node: &mut dyn INode, mut callback: F)
2171 where
2172 F: FnMut(
2173 Vec2,
2174 i32,
2175 f32,
2176 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 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 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 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 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 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 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 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 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 pub fn on_text_input<F>(node: &mut dyn INode, mut callback: F)
2360 where
2361 F: FnMut(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 pub fn on_text_editing<F>(node: &mut dyn INode, mut callback: F)
2383 where
2384 F: FnMut(String, 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 pub fn on_button_down<F>(node: &mut dyn INode, button: ButtonName, mut callback: F)
2406 where
2407 F: FnMut(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 pub fn on_button_up<F>(node: &mut dyn INode, button: ButtonName, mut callback: F)
2432 where
2433 F: FnMut(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 pub fn on_button_pressed<F>(node: &mut dyn INode, button: ButtonName, mut callback: F)
2459 where
2460 F: FnMut(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 pub fn on_axis<F>(node: &mut dyn INode, axis: AxisName, mut callback: F)
2487 where
2488 F: FnMut(i32, 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 pub fn on_animation_end<F>(node: &mut dyn IPlayable, mut callback: F)
2516 where
2517 F: FnMut(String, 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 pub fn on_body_enter<F>(node: &mut dyn IBody, mut callback: F)
2540 where
2541 F: FnMut(Body, 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 pub fn on_body_leave<F>(node: &mut dyn IBody, mut callback: F)
2563 where
2564 F: FnMut(Body, 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 pub fn on_contact_start<F>(node: &mut dyn IBody, mut callback: F)
2588 where
2589 F: FnMut(
2590 Body,
2591 Vec2,
2592 Vec2,
2593 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 pub fn on_contact_end<F>(node: &mut dyn IBody, mut callback: F)
2625 where
2626 F: FnMut(Body, Vec2, 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 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 pub fn on_align_layout<F>(node: &mut AlignNode, mut callback: F)
2667 where
2668 F: FnMut(f32, 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 pub fn on_effek_end<F>(node: &mut EffekNode, mut callback: F)
2689 where
2690 F: FnMut(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
2705pub struct GSlot {}
2707impl GSlot {
2708 pub const APP_EVENT: &'static str = "AppEvent";
2726 pub const APP_CHANGE: &'static str = "AppChange";
2744 pub const APP_WS: &'static str = "AppWS";
2766 pub fn on_app_event<F>(node: &mut dyn INode, mut callback: F)
2774 where
2775 F: FnMut(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 pub fn on_app_change<F>(node: &mut dyn INode, mut callback: F)
2796 where
2797 F: FnMut(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 pub fn on_app_ws<F>(node: &mut dyn INode, mut callback: F)
2819 where
2820 F: FnMut(String, 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
2835extern "C" {
2838 fn content_load(filename: i64) -> i64;
2839}
2840
2841impl Content {
2842 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
2861extern "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 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 pub fn get(&self, index: i32) -> Option<Value> {
2902 Value::from(unsafe { array_get(self.raw(), index) })
2903 }
2904 pub fn first(&self) -> Option<Value> {
2906 Value::from(unsafe { array_first(self.raw()) })
2907 }
2908 pub fn last(&self) -> Option<Value> {
2910 Value::from(unsafe { array_last(self.raw()) })
2911 }
2912 pub fn random_object(&self) -> Option<Value> {
2914 Value::from(unsafe { array_random_object(self.raw()) })
2915 }
2916 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 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 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 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 pub fn remove_last(&mut self) -> Option<Value> {
2980 Value::from(unsafe { array_remove_last(self.raw()) })
2981 }
2982 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
2999extern "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 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 pub fn get(&self, key: &str) -> Option<Value> {
3031 Value::from(unsafe { dictionary_get(self.raw(), from_string(key)) })
3032 }
3033}
3034
3035extern "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 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 pub fn get(&self, key: &str) -> Option<Value> {
3069 Value::from(unsafe { entity_get(self.raw(), from_string(key)) })
3070 }
3071 pub fn get_old(&self, key: &str) -> Option<Value> {
3082 Value::from(unsafe { entity_get_old(self.raw(), from_string(key)) })
3083 }
3084}
3085
3086extern "C" {
3089 fn group_watch(group: i64, func: i32, stack: i64);
3090}
3091
3092impl Group {
3093 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 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
3131extern "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 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#[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 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 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
3219impl Node {
3222 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
3242impl Camera {
3245 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
3265impl Playable {
3268 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
3288impl Body {
3291 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
3311impl Joint {
3314 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
3334impl PhysicsWorld {
3337 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#[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#[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#[repr(i32)]
3491#[derive(Copy, Clone, Debug, PartialEq)]
3492pub enum TextAlign {
3493 Left = 0,
3494 Center = 1,
3495 Right = 2,
3496}
3497
3498#[repr(i32)]
3501#[derive(Copy, Clone, Debug, PartialEq)]
3502pub enum BodyType {
3503 Dynamic = 0,
3504 Static = 1,
3505 Kinematic = 2,
3506}
3507
3508#[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 pub fn is_key_down(key: KeyName) -> bool {
3740 Keyboard::_is_key_down(key.as_ref())
3741 }
3742 pub fn is_key_up(key: KeyName) -> bool {
3752 Keyboard::_is_key_up(key.as_ref())
3753 }
3754 pub fn is_key_pressed(key: KeyName) -> bool {
3764 Keyboard::_is_key_pressed(key.as_ref())
3765 }
3766}
3767
3768#[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 pub fn is_button_down(controller_id: i32, button: ButtonName) -> bool {
3844 Controller::_is_button_down(controller_id, button.as_ref())
3845 }
3846 pub fn is_button_up(controller_id: i32, button: ButtonName) -> bool {
3857 Controller::_is_button_up(controller_id, button.as_ref())
3858 }
3859 pub fn is_button_pressed(controller_id: i32, button: ButtonName) -> bool {
3870 Controller::_is_button_pressed(controller_id, button.as_ref())
3871 }
3872 pub fn get_axis(controller_id: i32, axis: AxisName) -> f32 {
3883 Controller::_get_axis(controller_id, axis.as_ref())
3884 }
3885}
3886
3887impl 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
3895extern "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 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 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 GenerateMipmaps = 1 << 0,
5623 RepeatX = 1 << 1,
5625 RepeatY = 1 << 2,
5627 FlipY = 1 << 3,
5629 Premultiplied = 1 << 4,
5631 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 CCW = 1,
5656 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 Left = 1 << 0,
5676 Center = 1 << 1,
5678 Right = 1 << 2,
5680}
5681
5682#[repr(i32)]
5683#[derive(Copy, Clone, Debug, PartialEq)]
5684pub enum NvgVAlign {
5685 Top = 1 << 3,
5687 Middle = 1 << 4,
5689 Bottom = 1 << 5,
5691 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
5721extern "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}