1use std::{ffi::c_void, any::Any};
2use once_cell::sync::Lazy;
3
4mod rect;
5pub use rect::Rect;
6mod array;
7pub use array::Array;
8mod dictionary;
9pub use dictionary::Dictionary;
10mod director;
11pub use director::Director;
12mod app;
13pub use app::App;
14mod entity;
15pub use entity::Entity;
16mod group;
17pub use group::Group;
18mod observer;
19pub use observer::Observer;
20mod path;
21pub use path::Path;
22mod content;
23pub use content::Content;
24mod scheduler;
25pub use scheduler::Scheduler;
26mod camera;
27pub use camera::{ICamera, Camera};
28mod camera_2d;
29pub use camera_2d::Camera2D;
30mod camera_otho;
31pub use camera_otho::CameraOtho;
32mod pass;
33pub use pass::Pass;
34mod effect;
35pub use effect::{IEffect, Effect};
36mod sprite_effect;
37pub use sprite_effect::SpriteEffect;
38mod view;
39pub use view::View;
40mod action_def;
41pub use action_def::ActionDef;
42mod action;
43pub use action::Action;
44mod grabber;
45pub use grabber::Grabber;
46mod node;
47pub use node::{INode, Node};
48mod texture_2d;
49pub use texture_2d::Texture2D;
50mod sprite;
51pub use sprite::Sprite;
52mod grid;
53pub use grid::Grid;
54mod touch;
55pub use touch::Touch;
56mod ease;
57pub use ease::Ease;
58mod label;
59pub use label::Label;
60mod render_target;
61pub use render_target::RenderTarget;
62mod clip_node;
63pub use clip_node::ClipNode;
64mod draw_node;
65pub use draw_node::DrawNode;
66mod vertex_color;
67pub use vertex_color::VertexColor;
68mod line;
69pub use line::Line;
70mod particle;
71pub use particle::Particle;
72mod playable;
73pub use playable::{IPlayable, Playable};
74mod model;
75pub use model::Model;
76mod spine;
77pub use spine::Spine;
78mod dragon_bone;
79pub use dragon_bone::DragonBone;
80mod physics_world;
81pub use physics_world::{IPhysicsWorld, PhysicsWorld};
82mod fixture_def;
83pub use fixture_def::FixtureDef;
84mod body_def;
85pub use body_def::BodyDef;
86mod sensor;
87pub use sensor::Sensor;
88mod body;
89pub use body::{IBody, Body};
90mod joint_def;
91pub use joint_def::JointDef;
92mod joint;
93pub use joint::{IJoint, Joint};
94mod motor_joint;
95pub use motor_joint::MotorJoint;
96mod move_joint;
97pub use move_joint::MoveJoint;
98mod cache;
99pub use cache::Cache;
100mod audio;
101pub use audio::Audio;
102mod keyboard;
103pub use keyboard::Keyboard;
104mod svg;
105pub use svg::SVG;
106mod dbquery;
107pub use dbquery::DBQuery;
108mod dbparams;
109pub use dbparams::DBParams;
110mod dbrecord;
111pub use dbrecord::DBRecord;
112mod db;
113pub use db::DB;
114mod c_45;
115mod q_learner;
116pub mod ml {
117 pub use super::c_45::C45;
118 pub use super::q_learner::QLearner;
119}
120pub mod platformer;
121mod buffer;
122pub use buffer::Buffer;
123mod im_gui;
124pub use im_gui::ImGui;
125
126fn none_type(_: i64) -> Option<Box<dyn IObject>> {
127 panic!("'none_type' should not be called!");
128}
129
130static OBJECT_MAP: Lazy<Vec<fn(i64) -> Option<Box<dyn IObject>>>> = Lazy::new(|| {
131 let mut map: Vec<fn(i64) -> Option<Box<dyn IObject>>> = Vec::new();
132 let type_funcs = [
133 Array::type_info(),
134 Dictionary::type_info(),
135 Entity::type_info(),
136 Group::type_info(),
137 Observer::type_info(),
138 Scheduler::type_info(),
139 Camera::type_info(),
140 Camera2D::type_info(),
141 CameraOtho::type_info(),
142 Pass::type_info(),
143 Effect::type_info(),
144 SpriteEffect::type_info(),
145 Grabber::type_info(),
146 Node::type_info(),
147 Texture2D::type_info(),
148 Sprite::type_info(),
149 Grid::type_info(),
150 Touch::type_info(),
151 Label::type_info(),
152 RenderTarget::type_info(),
153 ClipNode::type_info(),
154 DrawNode::type_info(),
155 Line::type_info(),
156 Particle::type_info(),
157 Playable::type_info(),
158 Model::type_info(),
159 Spine::type_info(),
160 DragonBone::type_info(),
161 PhysicsWorld::type_info(),
162 FixtureDef::type_info(),
163 BodyDef::type_info(),
164 Sensor::type_info(),
165 Body::type_info(),
166 JointDef::type_info(),
167 Joint::type_info(),
168 MotorJoint::type_info(),
169 MoveJoint::type_info(),
170 SVG::type_info(),
171 ml::QLearner::type_info(),
172 platformer::Face::type_info(),
173 platformer::BulletDef::type_info(),
174 platformer::Bullet::type_info(),
175 platformer::Visual::type_info(),
176 platformer::behavior::Tree::type_info(),
177 platformer::decision::Tree::type_info(),
178 platformer::Unit::type_info(),
179 platformer::PlatformCamera::type_info(),
180 platformer::PlatformWorld::type_info(),
181 Buffer::type_info(),
182 ];
183 for pair in type_funcs.iter() {
184 let t = pair.0 as usize;
185 if map.len() < t + 1 {
186 map.resize(t + 1, none_type);
187 }
188 if map[t] != none_type {
189 panic!("cpp object type id {} duplicated!", t);
190 }
191 map[t] = pair.1;
192 }
193 map
194});
195static mut FUNC_MAP: Vec<Box<dyn FnMut()>> = Vec::new();
196static mut FUNC_AVAILABLE: Vec<i32> = Vec::new();
197
198extern "C" {
199 fn object_get_id(obj: i64) -> i32;
200 fn object_get_type(obj: i64) -> i32;
201 fn object_retain(obj: i64);
202 fn object_release(obj: i64);
203
204 fn str_new(len: i32) -> i64;
205 fn str_len(str: i64) -> i32;
206 fn str_read(dest: *mut c_void, src: i64);
207 fn str_write(dest: i64, src: *const c_void);
208 fn str_release(str: i64);
209
210 fn buf_new_i32(len: i32) -> i64;
211 fn buf_new_i64(len: i32) -> i64;
212 fn buf_new_f32(len: i32) -> i64;
213 fn buf_new_f64(len: i32) -> i64;
214 fn buf_len(v: i64) -> i32;
215 fn buf_read(dest: *mut c_void, src: i64);
216 fn buf_write(dest: i64, src: *const c_void);
217 fn buf_release(v: i64);
218
219 fn value_create_i64(value: i64) -> i64;
220 fn value_create_f64(value: f64) -> i64;
221 fn value_create_str(value: i64) -> i64;
222 fn value_create_bool(value: i32) -> i64;
223 fn value_create_object(value: i64) -> i64;
224 fn value_create_vec2(value: i64) -> i64;
225 fn value_create_size(value: i64) -> i64;
226 fn value_release(value: i64);
227 fn value_into_i64(value: i64) -> i64;
228 fn value_into_f64(value: i64) -> f64;
229 fn value_into_str(value: i64) -> i64;
230 fn value_into_bool(value: i64) -> i32;
231 fn value_into_object(value: i64) -> i64;
232 fn value_into_vec2(value: i64) -> i64;
233 fn value_into_size(value: i64) -> i64;
234 fn value_is_i64(value: i64) -> i32;
235 fn value_is_f64(value: i64) -> i32;
236 fn value_is_str(value: i64) -> i32;
237 fn value_is_bool(value: i64) -> i32;
238 fn value_is_object(value: i64) -> i32;
239 fn value_is_vec2(value: i64) -> i32;
240 fn value_is_size(value: i64) -> i32;
241
242 fn call_stack_create() -> i64;
243 fn call_stack_release(info: i64);
244 fn call_stack_push_i64(info: i64, value: i64);
245 fn call_stack_push_f64(info: i64, value: f64);
246 fn call_stack_push_str(info: i64, value: i64);
247 fn call_stack_push_bool(info: i64, value: i32);
248 fn call_stack_push_object(info: i64, value: i64);
249 fn call_stack_push_vec2(info: i64, value: i64);
250 fn call_stack_push_size(info: i64, value: i64);
251 fn call_stack_pop_i64(info: i64) -> i64;
252 fn call_stack_pop_f64(info: i64) -> f64;
253 fn call_stack_pop_str(info: i64) -> i64;
254 fn call_stack_pop_bool(info: i64) -> i32;
255 fn call_stack_pop_object(info: i64) -> i64;
256 fn call_stack_pop_vec2(info: i64) -> i64;
257 fn call_stack_pop_size(info: i64) -> i64;
258 fn call_stack_pop(info: i64) -> i32;
259 fn call_stack_front_i64(info: i64) -> i32;
260 fn call_stack_front_f64(info: i64) -> i32;
261 fn call_stack_front_str(info: i64) -> i32;
262 fn call_stack_front_bool(info: i64) -> i32;
263 fn call_stack_front_object(info: i64) -> i32;
264 fn call_stack_front_vec2(info: i64) -> i32;
265 fn call_stack_front_size(info: i64) -> i32;
266
267 fn dora_print(msg: i64);
268}
269
270pub fn print(msg: &str) {
271 unsafe { dora_print(from_string(msg)); }
272}
273
274#[macro_export]
275macro_rules! p {
276 () => {
277 dorothy_ssr::print("\n")
278 };
279 ($($arg:tt)*) => {{
280 dorothy_ssr::print((format!($($arg)*) + "\n").as_str());
281 }};
282}
283
284#[repr(C)]
285#[derive(Clone, Copy)]
286#[derive(PartialEq)]
287pub struct Vec2 {
288 pub x: f32,
289 pub y: f32
290}
291
292impl Vec2 {
293 pub fn from(value: i64) -> Vec2 {
294 unsafe { LightValue { value: value }.vec2 }
295 }
296 pub fn zero() -> Vec2 {
297 Vec2 { x: 0.0, y: 0.0 }
298 }
299 pub fn into_i64(&self) -> i64 {
300 unsafe { LightValue { vec2: *self }.value }
301 }
302 pub fn is_zero(&self) -> bool {
303 self.x == 0.0 && self.y == 0.0
304 }
305}
306
307#[repr(C)]
308#[derive(Clone, Copy)]
309#[derive(PartialEq)]
310pub struct Size {
311 pub width: f32,
312 pub height: f32
313}
314
315impl Size {
316 pub fn from(value: i64) -> Size {
317 unsafe { LightValue { value: value }.size }
318 }
319 pub fn zero() -> Size {
320 Size { width: 0.0, height: 0.0 }
321 }
322 pub fn into_i64(&self) -> i64 {
323 unsafe { LightValue { size: *self }.value }
324 }
325 pub fn is_zero(&self) -> bool {
326 self.width == 0.0 && self.height == 0.0
327 }
328}
329
330#[repr(C)]
331union LightValue {
332 vec2: Vec2,
333 size: Size,
334 value: i64,
335}
336
337#[repr(C)]
338#[derive(Clone, Copy)]
339pub struct Color {
340 pub r: u8,
341 pub g: u8,
342 pub b: u8,
343 pub a: u8
344}
345
346#[repr(C)]
347union ColorValue {
348 color: Color,
349 value: i32,
350}
351
352impl Color {
353 pub fn new(argb: u32) -> Color {
354 let a = argb >> 24;
355 let r = (argb & 0x00ff0000) >> 16;
356 let g = (argb & 0x0000ff00) >> 8;
357 let b = argb & 0x000000ff;
358 Color { r: r as u8, g: g as u8, b: b as u8, a: a as u8 }
359 }
360 pub fn from(agbr: i32) -> Color {
361 unsafe { ColorValue{ value: agbr }.color }
362 }
363 pub fn to_argb(&self) -> u32 {
364 (self.a as u32) << 24 | (self.r as u32) << 16 | (self.g as u32) << 8 | self.b as u32
365 }
366 pub fn to_color3(&self) -> Color3 {
367 Color3 { r: self.r, g: self.g, b: self.b }
368 }
369}
370
371#[repr(C)]
372#[derive(Clone, Copy)]
373pub struct Color3 {
374 pub r: u8,
375 pub g: u8,
376 pub b: u8
377}
378
379#[repr(C)]
380#[derive(Clone, Copy)]
381struct Color3a {
382 color3: Color3,
383 a: u8
384}
385
386#[repr(C)]
387union Color3Value {
388 color3a: Color3a,
389 value: i32,
390}
391
392impl Color3 {
393 pub fn new(rgb: u32) -> Color3 {
394 let r = (rgb & 0x00ff0000) >> 16;
395 let g = (rgb & 0x0000ff00) >> 8;
396 let b = rgb & 0x000000ff;
397 Color3 { r: r as u8, g: g as u8, b: b as u8 }
398 }
399 pub fn from(gbr: i32) -> Color3 {
400 unsafe { Color3Value { value: gbr }.color3a.color3 }
401 }
402 pub fn to_rgb(&self) -> u32 {
403 (self.r as u32) << 16 | (self.g as u32) << 8 | self.b as u32
404 }
405}
406
407fn to_string(str: i64) -> String {
408 unsafe {
409 let len = str_len(str) as usize;
410 let mut vec = Vec::with_capacity(len as usize);
411 vec.resize(len, 0);
412 let data = vec.as_mut_ptr() as *mut c_void;
413 str_read(data, str);
414 str_release(str);
415 return String::from_utf8(vec).unwrap();
416 }
417}
418
419fn from_string(s: &str) -> i64 {
420 unsafe {
421 let len = s.len() as i32;
422 let ptr = s.as_ptr();
423 let new_str = str_new(len);
424 str_write(new_str, ptr as *const c_void);
425 return new_str;
426 }
427}
428
429pub struct Vector;
430
431impl Vector {
432 pub fn to_i32(v: i64) -> Vec<i32> {
433 unsafe {
434 let len = buf_len(v) as usize;
435 let mut vec: Vec<i32> = Vec::with_capacity(len as usize);
436 vec.resize(len, Default::default());
437 let data = vec.as_mut_ptr() as *mut c_void;
438 buf_read(data, v);
439 buf_release(v);
440 return vec;
441 }
442 }
443 pub fn to_i64(v: i64) -> Vec<i64> {
444 unsafe {
445 let len = buf_len(v) as usize;
446 let mut vec: Vec<i64> = Vec::with_capacity(len as usize);
447 vec.resize(len, Default::default());
448 let data = vec.as_mut_ptr() as *mut c_void;
449 buf_read(data, v);
450 buf_release(v);
451 return vec;
452 }
453 }
454 pub fn to_f32(v: i64) -> Vec<f32> {
455 unsafe {
456 let len = buf_len(v) as usize;
457 let mut vec: Vec<f32> = Vec::with_capacity(len as usize);
458 vec.resize(len, Default::default());
459 let data = vec.as_mut_ptr() as *mut c_void;
460 buf_read(data, v);
461 buf_release(v);
462 return vec;
463 }
464 }
465 pub fn to_f64(v: i64) -> Vec<f64> {
466 unsafe {
467 let len = buf_len(v) as usize;
468 let mut vec: Vec<f64> = Vec::with_capacity(len as usize);
469 vec.resize(len, Default::default());
470 let data = vec.as_mut_ptr() as *mut c_void;
471 buf_read(data, v);
472 buf_release(v);
473 return vec;
474 }
475 }
476 pub fn to_str(v: i64) -> Vec<String> {
477 unsafe {
478 let len = buf_len(v) as usize;
479 let mut vec: Vec<i64> = Vec::with_capacity(len as usize);
480 vec.resize(len, Default::default());
481 let data = vec.as_mut_ptr() as *mut c_void;
482 buf_read(data, v);
483 let mut strs = Vec::with_capacity(vec.len());
484 for i in 0..vec.len() {
485 strs.push(to_string(vec[i]));
486 }
487 buf_release(v);
488 strs
489 }
490 }
491 pub fn from_i32(s: &Vec<i32>) -> i64 {
492 unsafe {
493 let len = s.len() as i32;
494 let ptr = s.as_ptr();
495 let new_vec = buf_new_i32(len);
496 buf_write(new_vec, ptr as *const c_void);
497 return new_vec;
498 }
499 }
500 pub fn from_i64(s: &Vec<i64>) -> i64 {
501 unsafe {
502 let len = s.len() as i32;
503 let ptr = s.as_ptr();
504 let new_vec = buf_new_i64(len);
505 buf_write(new_vec, ptr as *const c_void);
506 return new_vec;
507 }
508 }
509 pub fn from_f32(s: &Vec<f32>) -> i64 {
510 unsafe {
511 let len = s.len() as i32;
512 let ptr = s.as_ptr();
513 let new_vec = buf_new_f32(len);
514 buf_write(new_vec, ptr as *const c_void);
515 return new_vec;
516 }
517 }
518 pub fn from_f64(s: &Vec<f64>) -> i64 {
519 unsafe {
520 let len = s.len() as i32;
521 let ptr = s.as_ptr();
522 let new_vec = buf_new_f64(len);
523 buf_write(new_vec, ptr as *const c_void);
524 return new_vec;
525 }
526 }
527 pub fn from_str(s: &Vec<&str>) -> i64 {
528 unsafe {
529 let len = s.len() as i32;
530 let mut strs: Vec<i64> = Vec::with_capacity(s.len());
531 for i in 0..s.len() {
532 strs.push(from_string(s[i]));
533 }
534 let ptr = strs.as_ptr();
535 let new_vec = buf_new_i64(len);
536 buf_write(new_vec, ptr as *const c_void);
537 return new_vec;
538 }
539 }
540 pub fn from_vec2(s: &Vec<Vec2>) -> i64 {
541 unsafe {
542 let len = s.len() as i32;
543 let mut vs: Vec<i64> = Vec::with_capacity(s.len());
544 for i in 0..s.len() {
545 vs.push(LightValue { vec2: s[i] }.value);
546 }
547 let ptr = vs.as_ptr();
548 let new_vec = buf_new_i64(len);
549 buf_write(new_vec, ptr as *const c_void);
550 return new_vec;
551 }
552 }
553 pub fn from_vertex_color(s: &Vec<VertexColor>) -> i64 {
554 unsafe {
555 let len = s.len() as i32;
556 let mut vs: Vec<i64> = Vec::with_capacity(s.len());
557 for i in 0..s.len() {
558 vs.push(s[i].raw());
559 }
560 let ptr = vs.as_ptr();
561 let new_vec = buf_new_i64(len);
562 buf_write(new_vec, ptr as *const c_void);
563 return new_vec;
564 }
565 }
566 pub fn from_action_def(s: &Vec<ActionDef>) -> i64 {
567 unsafe {
568 let len = s.len() as i32;
569 let mut vs: Vec<i64> = Vec::with_capacity(s.len());
570 for i in 0..s.len() {
571 vs.push(s[i].raw());
572 }
573 let ptr = vs.as_ptr();
574 let new_vec = buf_new_i64(len);
575 buf_write(new_vec, ptr as *const c_void);
576 return new_vec;
577 }
578 }
579 pub fn from_btree(s: &Vec<platformer::behavior::Tree>) -> i64 {
580 unsafe {
581 let len = s.len() as i32;
582 let mut vs: Vec<i64> = Vec::with_capacity(s.len());
583 for i in 0..s.len() {
584 vs.push(s[i].raw());
585 }
586 let ptr = vs.as_ptr();
587 let new_vec = buf_new_i64(len);
588 buf_write(new_vec, ptr as *const c_void);
589 return new_vec;
590 }
591 }
592 pub fn from_dtree(s: &Vec<platformer::decision::Tree>) -> i64 {
593 unsafe {
594 let len = s.len() as i32;
595 let mut vs: Vec<i64> = Vec::with_capacity(s.len());
596 for i in 0..s.len() {
597 vs.push(s[i].raw());
598 }
599 let ptr = vs.as_ptr();
600 let new_vec = buf_new_i64(len);
601 buf_write(new_vec, ptr as *const c_void);
602 return new_vec;
603 }
604 }
605}
606
607fn get_object(raw: i64) -> Option<Box<dyn IObject>> {
608 unsafe { OBJECT_MAP[object_get_type(raw) as usize](raw) }
609}
610
611fn push_function(func: Box<dyn FnMut()>) -> i32 {
612 unsafe {
613 if let Some(func_id) = FUNC_AVAILABLE.pop() {
614 FUNC_MAP[func_id as usize] = func;
615 func_id
616 } else {
617 FUNC_MAP.push(func);
618 (FUNC_MAP.len() - 1) as i32
619 }
620 }
621}
622
623#[no_mangle]
624pub extern fn call_function(func_id: i32) {
625 unsafe { FUNC_MAP[func_id as usize](); }
626}
627
628fn dummy_func() {
629 panic!("the dummy function should not be called.");
630}
631
632#[no_mangle]
633pub extern fn deref_function(func_id: i32) {
634 unsafe {
635 FUNC_MAP[func_id as usize] = Box::new(dummy_func);
636 FUNC_AVAILABLE.push(func_id);
637 }
638}
639
640pub trait IObject {
641 fn raw(&self) -> i64;
642 fn obj(&self) -> &dyn IObject;
643 fn get_id(&self) -> i32 { unsafe { object_get_id(self.raw()) } }
644 fn as_any(&self) -> &dyn Any;
645}
646
647pub struct Object { raw: i64 }
648impl IObject for Object {
649 fn raw(&self) -> i64 { self.raw }
650 fn obj(&self) -> &dyn IObject { self }
651 fn as_any(&self) -> &dyn std::any::Any { self }
652}
653impl Drop for Object {
654 fn drop(&mut self) { unsafe { crate::dora::object_release(self.raw); } }
655}
656impl Clone for Object {
657 fn clone(&self) -> Object {
658 unsafe { crate::dora::object_retain(self.raw); }
659 Object { raw: self.raw }
660 }
661}
662impl Object {
663 pub fn from(raw: i64) -> Option<Object> {
664 match raw {
665 0 => None,
666 _ => Some(Object { raw: raw })
667 }
668 }
669}
670
671pub fn cast<T: Clone + 'static>(obj: &dyn IObject) -> Option<T> {
672 Some(obj.as_any().downcast_ref::<T>()?.clone())
673}
674
675pub struct CallStack { raw: i64 }
676
677pub enum DoraValue<'a> {
678 I32(i32),
679 I64(i64),
680 F32(f32),
681 F64(f64),
682 Bool(bool),
683 Str(&'a str),
684 Object(&'a dyn IObject),
685 Vec2(Vec2),
686 Size(Size),
687}
688
689pub trait IntoValue<'a> {
690 fn dora_val(self) -> DoraValue<'a>;
691 fn val(self) -> Value;
692}
693
694impl<'a> DoraValue<'a> {
695 pub fn push(self, info: &mut CallStack) {
696 match self {
697 DoraValue::I32(x) => { info.push_i32(x); },
698 DoraValue::I64(x) => { info.push_i64(x); },
699 DoraValue::F32(x) => { info.push_f32(x); },
700 DoraValue::F64(x) => { info.push_f64(x); },
701 DoraValue::Bool(x) => { info.push_bool(x); },
702 DoraValue::Str(x) => { info.push_str(x); },
703 DoraValue::Object(x) => { info.push_object(x); },
704 DoraValue::Vec2(x) => { info.push_vec2(&x); },
705 DoraValue::Size(x) => { info.push_size(&x); },
706 }
707 }
708}
709
710impl<'a> IntoValue<'a> for i32 {
711 fn dora_val(self) -> DoraValue<'a> { DoraValue::I32(self) }
712 fn val(self) -> Value {
713 unsafe { Value{ raw: value_create_i64(self as i64) } }
714 }
715}
716
717impl<'a> IntoValue<'a> for i64 {
718 fn dora_val(self) -> DoraValue<'a> { DoraValue::I64(self) }
719 fn val(self) -> Value {
720 unsafe { Value{ raw: value_create_i64(self) } }
721 }
722}
723
724impl<'a> IntoValue<'a> for f32 {
725 fn dora_val(self) -> DoraValue<'a> { DoraValue::F32(self) }
726 fn val(self) -> Value {
727 unsafe { Value{ raw: value_create_f64(self as f64) } }
728 }
729}
730
731impl<'a> IntoValue<'a> for f64 {
732 fn dora_val(self) -> DoraValue<'a> { DoraValue::F64(self) }
733 fn val(self) -> Value {
734 unsafe { Value{ raw: value_create_f64(self) } }
735 }
736}
737
738impl<'a> IntoValue<'a> for bool {
739 fn dora_val(self) -> DoraValue<'a> { DoraValue::Bool(self) }
740 fn val(self) -> Value {
741 unsafe { Value{ raw: value_create_bool(if self { 1 } else { 0 }) } }
742 }
743}
744
745impl<'a> IntoValue<'a> for &'a str {
746 fn dora_val(self) -> DoraValue<'a> { DoraValue::Str(self) }
747 fn val(self) -> Value {
748 unsafe { Value{ raw: value_create_str(from_string(self)) } }
749 }
750}
751
752impl<'a> IntoValue<'a> for &'a dyn IObject {
753 fn dora_val(self) -> DoraValue<'a> { DoraValue::Object(self) }
754 fn val(self) -> Value {
755 unsafe { Value{ raw: value_create_object(self.raw()) } }
756 }
757}
758
759impl<'a> IntoValue<'a> for Vec2 {
760 fn dora_val(self) -> DoraValue<'a> { DoraValue::Vec2(self) }
761 fn val(self) -> Value {
762 unsafe { Value{ raw: value_create_vec2(self.into_i64()) } }
763 }
764}
765
766impl<'a> IntoValue<'a> for Size {
767 fn dora_val(self) -> DoraValue<'a> { DoraValue::Size(self) }
768 fn val(self) -> Value {
769 unsafe { Value{ raw: value_create_size(self.into_i64()) } }
770 }
771}
772
773#[macro_export]
774macro_rules! args {
775 ( $( $x:expr ),* ) => {
776 {
777 let mut stack = dorothy_ssr::CallStack::new();
778 $(
779 dorothy_ssr::Value::new($x).push(&mut stack);
780 )*
781 stack
782 }
783 };
784}
785
786#[macro_export]
787macro_rules! dora_object {
788 ($name: ident) => {
789 paste::paste! {
790 impl IObject for $name {
791 fn raw(&self) -> i64 { self.raw }
792 fn obj(&self) -> &dyn IObject { self }
793 fn as_any(&self) -> &dyn std::any::Any { self }
794 }
795 impl Drop for $name {
796 fn drop(&mut self) { unsafe { crate::dora::object_release(self.raw); } }
797 }
798 impl Clone for $name {
799 fn clone(&self) -> $name {
800 unsafe { crate::dora::object_retain(self.raw); }
801 $name { raw: self.raw }
802 }
803 }
804 impl $name {
805 pub fn from(raw: i64) -> Option<$name> {
806 match raw {
807 0 => None,
808 _ => Some($name { raw: raw })
809 }
810 }
811 }
812 }
813 };
814}
815
816pub struct Value { raw: i64 }
819
820impl Value {
821 pub fn new<'a, A>(value: A) -> DoraValue<'a>
822 where A: IntoValue<'a> {
823 value.dora_val()
824 }
825 fn from(raw: i64) -> Option<Value> {
826 match raw {
827 0 => { None },
828 _ => { Some(Value { raw: raw }) }
829 }
830 }
831 pub fn raw(&self) -> i64 { self.raw }
832 pub fn into_i32(&self) -> Option<i32> {
833 unsafe {
834 if value_is_i64(self.raw) != 0 {
835 Some(value_into_i64(self.raw) as i32)
836 } else { None }
837 }
838 }
839 pub fn into_i64(&self) -> Option<i64> {
840 unsafe {
841 if value_is_i64(self.raw) != 0 {
842 Some(value_into_i64(self.raw))
843 } else { None }
844 }
845 }
846 pub fn into_f32(&self) -> Option<f32> {
847 unsafe {
848 if value_is_f64(self.raw) != 0 {
849 Some(value_into_f64(self.raw) as f32)
850 } else { None }
851 }
852 }
853 pub fn into_f64(&self) -> Option<f64> {
854 unsafe {
855 if value_is_f64(self.raw) != 0 {
856 Some(value_into_f64(self.raw))
857 } else { None }
858 }
859 }
860 pub fn into_bool(&self) -> Option<bool> {
861 unsafe {
862 if value_is_bool(self.raw) != 0 {
863 Some(value_into_bool(self.raw) != 0)
864 } else { None }
865 }
866 }
867 pub fn into_str(&self) -> Option<String> {
868 unsafe {
869 if value_is_str(self.raw) != 0 {
870 Some(to_string(value_into_str(self.raw)))
871 } else { None }
872 }
873 }
874 pub fn into_object(&self) -> Option<Box<dyn IObject>> {
875 unsafe {
876 if value_is_object(self.raw) != 0 {
877 get_object(value_into_object(self.raw))
878 } else { None }
879 }
880 }
881 pub fn into_vec2(&self) -> Option<Vec2> {
882 unsafe {
883 if value_is_vec2(self.raw) != 0 {
884 Some(Vec2::from(value_into_vec2(self.raw)))
885 } else { None }
886 }
887 }
888 pub fn into_size(&self) -> Option<Size> {
889 unsafe {
890 if value_is_size(self.raw) != 0 {
891 Some(Size::from(value_into_size(self.raw)))
892 } else { None }
893 }
894 }
895 pub fn cast<T: Clone + 'static>(&self) -> Option<T> {
896 cast::<T>(self.into_object()?.as_ref())
897 }
898}
899
900impl Drop for Value {
901 fn drop(&mut self) { unsafe { value_release(self.raw); } }
902}
903
904impl CallStack {
907 fn raw(&self) -> i64 {
908 self.raw
909 }
910 pub fn new() -> CallStack {
911 CallStack { raw: unsafe { call_stack_create() } }
912 }
913 pub fn push_i32(&mut self, value: i32) {
914 unsafe { call_stack_push_i64(self.raw, value as i64); }
915 }
916 pub fn push_i64(&mut self, value: i64) {
917 unsafe { call_stack_push_i64(self.raw, value); }
918 }
919 pub fn push_f32(&mut self, value: f32) {
920 unsafe { call_stack_push_f64(self.raw, value as f64); }
921 }
922 pub fn push_f64(&mut self, value: f64) {
923 unsafe { call_stack_push_f64(self.raw, value); }
924 }
925 pub fn push_str(&mut self, value: &str) {
926 unsafe { call_stack_push_str(self.raw, from_string(value)); }
927 }
928 pub fn push_bool(&mut self, value: bool) {
929 unsafe { call_stack_push_bool(self.raw, if value { 1 } else { 0 }); }
930 }
931 pub fn push_object(&mut self, value: &dyn IObject) {
932 unsafe { call_stack_push_object(self.raw, value.raw()); }
933 }
934 pub fn push_vec2(&mut self, value: &Vec2) {
935 unsafe { call_stack_push_vec2(self.raw, value.into_i64()); }
936 }
937 pub fn push_size(&mut self, value: &Size) {
938 unsafe { call_stack_push_size(self.raw, value.into_i64()); }
939 }
940 pub fn pop_i32(&mut self) -> Option<i32> {
941 unsafe {
942 if call_stack_front_i64(self.raw) != 0 {
943 Some(call_stack_pop_i64(self.raw) as i32)
944 } else { None }
945 }
946 }
947 pub fn pop_i64(&mut self) -> Option<i64> {
948 unsafe {
949 if call_stack_front_i64(self.raw) != 0 {
950 Some(call_stack_pop_i64(self.raw))
951 } else { None }
952 }
953 }
954 pub fn pop_f32(&mut self) -> Option<f32> {
955 unsafe {
956 if call_stack_front_f64(self.raw) != 0 {
957 Some(call_stack_pop_f64(self.raw) as f32)
958 } else { None }
959 }
960 }
961 pub fn pop_f64(&mut self) -> Option<f64> {
962 unsafe {
963 if call_stack_front_f64(self.raw) != 0 {
964 Some(call_stack_pop_f64(self.raw))
965 } else { None }
966 }
967 }
968 pub fn pop_str(&mut self) -> Option<String> {
969 unsafe {
970 if call_stack_front_str(self.raw) != 0 {
971 Some(to_string(call_stack_pop_str(self.raw)))
972 } else { None }
973 }
974 }
975 pub fn pop_bool(&mut self) -> Option<bool> {
976 unsafe {
977 if call_stack_front_bool(self.raw) != 0 {
978 Some(call_stack_pop_bool(self.raw) != 0)
979 } else { None }
980 }
981 }
982 pub fn pop_object(&mut self) -> Option<Box<dyn IObject>> {
983 unsafe {
984 if call_stack_front_object(self.raw) != 0 {
985 let raw = call_stack_pop_object(self.raw);
986 get_object(raw)
987 } else { None }
988 }
989 }
990 pub fn pop_cast<T: Clone + 'static>(&mut self) -> Option<T> {
991 unsafe {
992 if call_stack_front_object(self.raw) != 0 {
993 let raw = call_stack_pop_object(self.raw);
994 cast::<T>(get_object(raw)?.as_ref())
995 } else { None }
996 }
997 }
998 pub fn pop_vec2(&mut self) -> Option<Vec2> {
999 unsafe {
1000 if call_stack_front_vec2(self.raw) != 0 {
1001 Some(Vec2::from(call_stack_pop_vec2(self.raw)))
1002 } else { None }
1003 }
1004 }
1005 pub fn pop_size(&mut self) -> Option<Size> {
1006 unsafe {
1007 if call_stack_front_size(self.raw) != 0 {
1008 Some(Size::from(call_stack_pop_size(self.raw)))
1009 } else { None }
1010 }
1011 }
1012 pub fn pop(&mut self) {
1013 if unsafe { call_stack_pop(self.raw) } == 0 {
1014 panic!("pop from empty call stack!");
1015 }
1016 }
1017}
1018
1019impl Drop for CallStack {
1020 fn drop(&mut self) { unsafe { call_stack_release(self.raw); } }
1021}
1022
1023extern "C" {
1026 fn array_set(array: i64, index: i32, item: i64) -> i32;
1027 fn array_get(array: i64, index: i32) -> i64;
1028 fn array_first(array: i64) -> i64;
1029 fn array_last(array: i64) -> i64;
1030 fn array_random_object(array: i64) -> i64;
1031 fn array_add(array: i64, item: i64);
1032 fn array_insert(array: i64, index: i32, item: i64);
1033 fn array_contains(array: i64, item: i64) -> i32;
1034 fn array_index(array: i64, item: i64) -> i32;
1035 fn array_remove_last(array: i64) -> i64;
1036 fn array_fast_remove(array: i64, item: i64) -> i32;
1037}
1038
1039impl Array {
1040 pub fn set<'a, T>(&mut self, index: i32, v: T) where T: IntoValue<'a> {
1041 if unsafe { array_set(self.raw(), index, v.val().raw()) == 0 } {
1042 panic!("Out of bounds, expecting [0, {}), got {}", self.get_count(), index);
1043 }
1044 }
1045 pub fn get(&self, index: i32) -> Option<Value> {
1046 Value::from(unsafe { array_get(self.raw(), index) })
1047 }
1048 pub fn first(&self) -> Option<Value> {
1049 Value::from(unsafe { array_first(self.raw()) })
1050 }
1051 pub fn last(&self) -> Option<Value> {
1052 Value::from(unsafe { array_last(self.raw()) })
1053 }
1054 pub fn random_object(&self) -> Option<Value> {
1055 Value::from(unsafe { array_random_object(self.raw()) })
1056 }
1057 pub fn add<'a, T>(&mut self, v: T) where T: IntoValue<'a> {
1058 unsafe { array_add(self.raw(), v.val().raw()); }
1059 }
1060 pub fn insert<'a, T>(&mut self, index: i32, v: T) where T: IntoValue<'a> {
1061 unsafe { array_insert(self.raw(), index, v.val().raw()); }
1062 }
1063 pub fn contains<'a, T>(&self, v: T) -> bool where T: IntoValue<'a> {
1064 unsafe { array_contains(self.raw(), v.val().raw()) != 0 }
1065 }
1066 pub fn index<'a, T>(&self, v: T) -> i32 where T: IntoValue<'a> {
1067 unsafe { array_index(self.raw(), v.val().raw()) }
1068 }
1069 pub fn remove_last(&mut self) -> Option<Value> {
1070 Value::from(unsafe { array_remove_last(self.raw()) })
1071 }
1072 pub fn fast_remove<'a, T>(&mut self, v: T) -> bool where T: IntoValue<'a> {
1073 unsafe { array_fast_remove(self.raw(), v.val().raw()) != 0 }
1074 }
1075}
1076
1077extern "C" {
1080 fn dictionary_set(dict: i64, key: i64, value: i64);
1081 fn dictionary_get(dict: i64, key: i64) -> i64;
1082}
1083
1084impl Dictionary {
1085 pub fn set<'a, T>(&mut self, key: &str, v: T) where T: IntoValue<'a> {
1086 unsafe { dictionary_set(self.raw(), from_string(key), v.val().raw()); }
1087 }
1088 pub fn get(&self, key: &str) -> Option<Value> {
1089 Value::from(unsafe { dictionary_get(self.raw(), from_string(key)) })
1090 }
1091}
1092
1093extern "C" {
1096 fn entity_set(e: i64, k: i64, v: i64);
1097 fn entity_get(e: i64, k: i64) -> i64;
1098 fn entity_get_old(e: i64, k: i64) -> i64;
1099}
1100
1101impl Entity {
1102 pub fn set<'a, T>(&mut self, key: &str, value: T) where T: IntoValue<'a> {
1103 unsafe { entity_set(self.raw(), from_string(key), value.val().raw()); }
1104 }
1105 pub fn get(&self, key: &str) -> Option<Value> {
1106 Value::from(unsafe { entity_get(self.raw(), from_string(key)) })
1107 }
1108 pub fn get_old(&self, key: &str) -> Option<Value> {
1109 Value::from(unsafe { entity_get_old(self.raw(), from_string(key)) })
1110 }
1111}
1112
1113extern "C" {
1116 fn group_watch(group: i64, func: i32, stack: i64);
1117}
1118
1119impl Group {
1120 pub fn watch(&mut self, mut func: Box<dyn FnMut(&mut CallStack)>) {
1121 let mut stack = CallStack::new();
1122 let stack_raw = stack.raw();
1123 let func_id = push_function(Box::new(move || { func(&mut stack); }));
1124 unsafe { group_watch(self.raw(), func_id, stack_raw); }
1125 }
1126 pub fn each(&self, func: Box<dyn FnMut(&Entity) -> bool>) -> bool {
1127 match self.find(func) {
1128 Some(_) => true,
1129 None => false
1130 }
1131 }
1132}
1133
1134extern "C" {
1137 fn observer_watch(observer: i64, func: i32, stack: i64);
1138}
1139
1140#[repr(i32)]
1141pub enum EntityEvent {
1142 Add = 1,
1143 Change = 2,
1144 AddOrChange = 3,
1145 Remove = 4
1146}
1147
1148impl Observer {
1149 pub fn watch(&mut self, mut func: Box<dyn FnMut(&mut CallStack)>) {
1150 let mut stack = CallStack::new();
1151 let stack_raw = stack.raw();
1152 let func_id = push_function(Box::new(move || { func(&mut stack); }));
1153 unsafe { observer_watch(self.raw(), func_id, stack_raw); }
1154 }
1155}
1156
1157extern "C" {
1160 fn node_emit(node: i64, name: i64, stack: i64);
1161}
1162
1163impl Node {
1164 pub fn emit(&mut self, name: &str, stack: CallStack) {
1165 unsafe { node_emit(self.raw(), from_string(name), stack.raw()); }
1166 }
1167}
1168
1169#[repr(i32)]
1171pub enum TextureWrap {
1172 None = 0,
1173 Mirror = 1,
1174 Clamp = 2,
1175 Border = 3,
1176}
1177
1178#[repr(i32)]
1179pub enum TextureFilter {
1180 None = 0,
1181 Point = 1,
1182 Anisotropic = 2,
1183}
1184
1185#[repr(i32)]
1188pub enum EaseType {
1189 Linear = 0,
1190 InQuad = 1,
1191 OutQuad = 2,
1192 InOutQuad = 3,
1193 InCubic = 4,
1194 OutCubic = 5,
1195 InOutCubic = 6,
1196 InQuart = 7,
1197 OutQuart = 8,
1198 InOutQuart = 9,
1199 InQuint = 10,
1200 OutQuint = 11,
1201 InOutQuint = 12,
1202 InSine = 13,
1203 OutSine = 14,
1204 InOutSine = 15,
1205 InExpo = 16,
1206 OutExpo = 17,
1207 InOutExpo = 18,
1208 InCirc = 19,
1209 OutCirc = 20,
1210 InOutCirc = 21,
1211 InElastic = 22,
1212 OutElastic = 23,
1213 InOutElastic = 24,
1214 InBack = 25,
1215 OutBack = 26,
1216 InOutBack = 27,
1217 InBounce = 28,
1218 OutBounce = 29,
1219 InOutBounce = 30,
1220 OutInQuad = 31,
1221 OutInCubic = 32,
1222 OutInQuart = 33,
1223 OutInQuint = 34,
1224 OutInSine = 35,
1225 OutInExpo = 36,
1226 OutInCirc = 37,
1227 OutInElastic = 38,
1228 OutInBack = 39,
1229 OutInBounce = 40,
1230}
1231
1232#[repr(i32)]
1233pub enum Property {
1234 X = 0,
1235 Y = 1,
1236 Z = 2,
1237 Angle = 3,
1238 AngleX = 4,
1239 AngleY = 5,
1240 ScaleX = 6,
1241 ScaleY = 7,
1242 SkewX = 8,
1243 SkewY = 9,
1244 Width = 10,
1245 Height = 11,
1246 AnchorX = 12,
1247 AnchorY = 13,
1248 Opacity = 14,
1249}
1250
1251#[repr(i32)]
1254pub enum TextAlign {
1255 Left = 0,
1256 Center = 1,
1257 Right = 2,
1258}
1259
1260extern "C" {
1263 fn blackboard_set(b: i64, k: i64, v: i64);
1264 fn blackboard_get(b: i64, k: i64) -> i64;
1265}
1266
1267impl platformer::behavior::Blackboard {
1268 pub fn set<'a, T>(&mut self, key: &str, value: T) where T: IntoValue<'a> {
1269 unsafe { blackboard_set(self.raw(), from_string(key), value.val().raw()); }
1270 }
1271 pub fn get(&self, key: &str) -> Option<Value> {
1272 Value::from(unsafe { blackboard_get(self.raw(), from_string(key)) })
1273 }
1274}
1275
1276static mut IMGUI_STACK: Lazy<CallStack> = Lazy::new(|| { CallStack::new() });
1277
1278impl ImGui {
1279 fn push_bool(v: bool) -> &'static mut CallStack {
1280 let stack = unsafe { &mut IMGUI_STACK };
1281 stack.push_bool(v);
1282 stack
1283 }
1284 fn push_i32(v: i32) -> &'static mut CallStack {
1285 let stack = unsafe { &mut IMGUI_STACK };
1286 stack.push_i32(v);
1287 stack
1288 }
1289 fn push_i32x2(v1: i32, v2: i32) -> &'static mut CallStack {
1290 let stack = unsafe { &mut IMGUI_STACK };
1291 stack.push_i32(v1);
1292 stack.push_i32(v2);
1293 stack
1294 }
1295 fn push_f32(v: f32) -> &'static mut CallStack {
1296 let stack = unsafe { &mut IMGUI_STACK };
1297 stack.push_f32(v);
1298 stack
1299 }
1300 fn push_f32x2(v1: f32, v2: f32) -> &'static mut CallStack {
1301 let stack = unsafe { &mut IMGUI_STACK };
1302 stack.push_f32(v1);
1303 stack.push_f32(v2);
1304 stack
1305 }
1306 pub fn begin_ret(name: &str, opened: bool) -> (bool, bool) {
1307 let stack = ImGui::push_bool(opened);
1308 let changed = ImGui::_begin(name, stack);
1309 (changed, stack.pop_bool().unwrap())
1310 }
1311 pub fn begin_ret_opts(name: &str, opened: bool, windows_flags: &Vec<&str>) -> (bool, bool) {
1312 let stack = ImGui::push_bool(opened);
1313 let changed = ImGui::_begin_opts(name, stack, windows_flags);
1314 (changed, stack.pop_bool().unwrap())
1315 }
1316 pub fn collapsing_header_ret(label: &str, opened: bool) -> (bool, bool) {
1317 let stack = ImGui::push_bool(opened);
1318 let changed = ImGui::_collapsing_header(label, stack);
1319 (changed, stack.pop_bool().unwrap())
1320 }
1321 pub fn collapsing_header_ret_opts(label: &str, opened: bool, tree_node_flags: &Vec<&str>) -> (bool, bool) {
1322 let stack = ImGui::push_bool(opened);
1323 let changed = ImGui::_collapsing_header_opts(label, stack, tree_node_flags);
1324 (changed, stack.pop_bool().unwrap())
1325 }
1326 pub fn selectable_ret(label: &str, selected: bool) -> (bool, bool) {
1327 let stack = ImGui::push_bool(selected);
1328 let changed = ImGui::_selectable(label, stack);
1329 (changed, stack.pop_bool().unwrap())
1330 }
1331 pub fn selectable_ret_opts(label: &str, selected: bool, size: &crate::dora::Vec2, selectable_flags: &Vec<&str>) -> (bool, bool) {
1332 let stack = ImGui::push_bool(selected);
1333 let changed = ImGui::_selectable_opts(label, stack, size, selectable_flags);
1334 (changed, stack.pop_bool().unwrap())
1335 }
1336 pub fn begin_popup_modal_ret(name: &str, opened: bool) -> (bool, bool) {
1337 let stack = ImGui::push_bool(opened);
1338 let changed = ImGui::_begin_popup_modal(name, stack);
1339 (changed, stack.pop_bool().unwrap())
1340 }
1341 pub fn begin_popup_modal_ret_opts(name: &str, opened: bool, windows_flags: &Vec<&str>) -> (bool, bool) {
1342 let stack = ImGui::push_bool(opened);
1343 let changed = ImGui::_begin_popup_modal_opts(name, stack, windows_flags);
1344 (changed, stack.pop_bool().unwrap())
1345 }
1346 pub fn combo_ret(label: &str, current_item: i32, items: &Vec<&str>) -> (bool, i32) {
1347 let stack = ImGui::push_i32(current_item);
1348 let changed = ImGui::_combo(label, stack, items);
1349 (changed, stack.pop_i32().unwrap())
1350 }
1351 pub fn combo_ret_opts(label: &str, current_item: i32, items: &Vec<&str>, height_in_items: i32) -> (bool, i32) {
1352 let stack = ImGui::push_i32(current_item);
1353 let changed = ImGui::_combo_opts(label, stack, items, height_in_items);
1354 (changed, stack.pop_i32().unwrap())
1355 }
1356 pub fn drag_float_ret(label: &str, v: f32, v_speed: f32, v_min: f32, v_max: f32) -> (bool, f32) {
1357 let stack = ImGui::push_f32(v);
1358 let changed = ImGui::_drag_float(label, stack, v_speed, v_min, v_max);
1359 (changed, stack.pop_f32().unwrap())
1360 }
1361 pub fn drag_float_ret_opts(label: &str, v: f32, v_speed: f32, v_min: f32, v_max: f32, display_format: &str, slider_flags: &Vec<&str>) -> (bool, f32) {
1362 let stack = ImGui::push_f32(v);
1363 let changed = ImGui::_drag_float_opts(label, stack, v_speed, v_min, v_max, display_format, slider_flags);
1364 (changed, stack.pop_f32().unwrap())
1365 }
1366 pub fn drag_float2_ret(label: &str, v1: f32, v2: f32, v_speed: f32, v_min: f32, v_max: f32) -> (bool, f32, f32) {
1367 let stack = ImGui::push_f32x2(v1, v2);
1368 let changed = ImGui::_drag_float2(label, stack, v_speed, v_min, v_max);
1369 (changed, stack.pop_f32().unwrap(), stack.pop_f32().unwrap())
1370 }
1371 pub fn drag_float2_ret_opts(label: &str, v1: f32, v2: f32, v_speed: f32, v_min: f32, v_max: f32, display_format: &str, slider_flags: &Vec<&str>) -> (bool, f32, f32) {
1372 let stack = ImGui::push_f32x2(v1, v2);
1373 let changed = ImGui::_drag_float2_opts(label, stack, v_speed, v_min, v_max, display_format, slider_flags);
1374 (changed, stack.pop_f32().unwrap(), stack.pop_f32().unwrap())
1375 }
1376 pub fn drag_int2_ret(label: &str, v1: i32, v2: i32, v_speed: f32, v_min: i32, v_max: i32) -> (bool, i32, i32) {
1377 let stack = ImGui::push_i32x2(v1, v2);
1378 let changed = ImGui::_drag_int2(label, stack, v_speed, v_min, v_max);
1379 (changed, stack.pop_i32().unwrap(), stack.pop_i32().unwrap())
1380 }
1381 pub fn drag_int2_opts(label: &str, v1: i32, v2: i32, v_speed: f32, v_min: i32, v_max: i32, display_format: &str, slider_flags: &Vec<&str>) -> (bool, i32, i32) {
1382 let stack = ImGui::push_i32x2(v1, v2);
1383 let changed = ImGui::_drag_int2_opts(label, stack, v_speed, v_min, v_max, display_format, slider_flags);
1384 (changed, stack.pop_i32().unwrap(), stack.pop_i32().unwrap())
1385 }
1386 pub fn input_float_ret(label: &str, v: f32) -> (bool, f32) {
1387 let stack = ImGui::push_f32(v);
1388 let changed = ImGui::_input_float(label, stack);
1389 (changed, stack.pop_f32().unwrap())
1390 }
1391 pub fn input_float_ret_opts(label: &str, v: f32, step: f32, step_fast: f32, display_format: &str, input_text_flags: &Vec<&str>) -> (bool, f32) {
1392 let stack = ImGui::push_f32(v);
1393 let changed = ImGui::_input_float_opts(label, stack, step, step_fast, display_format, input_text_flags);
1394 (changed, stack.pop_f32().unwrap())
1395 }
1396 pub fn input_float2_ret(label: &str, v1: f32, v2: f32) -> (bool, f32, f32) {
1397 let stack = ImGui::push_f32x2(v1, v2);
1398 let changed = ImGui::_input_float2(label, stack);
1399 (changed, stack.pop_f32().unwrap(), stack.pop_f32().unwrap())
1400 }
1401 pub fn input_float2_ret_opts(label: &str, v1: f32, v2: f32, display_format: &str, input_text_flags: &Vec<&str>) -> (bool, f32, f32) {
1402 let stack = ImGui::push_f32x2(v1, v2);
1403 let changed = ImGui::_input_float2_opts(label, stack, display_format, input_text_flags);
1404 (changed, stack.pop_f32().unwrap(), stack.pop_f32().unwrap())
1405 }
1406 pub fn input_int_ret(label: &str, v: i32) -> (bool, i32) {
1407 let stack = ImGui::push_i32(v);
1408 let changed = ImGui::_input_int(label, stack);
1409 (changed, stack.pop_i32().unwrap())
1410 }
1411 pub fn input_int_ret_opts(label: &str, v: i32, step: i32, step_fast: i32, input_text_flags: &Vec<&str>) -> (bool, i32) {
1412 let stack = ImGui::push_i32(v);
1413 let changed = ImGui::_input_int_opts(label, stack, step, step_fast, input_text_flags);
1414 (changed, stack.pop_i32().unwrap())
1415 }
1416 pub fn input_int2_ret(label: &str, v1: i32, v2: i32) -> (bool, i32, i32) {
1417 let stack = ImGui::push_i32x2(v1, v2);
1418 let changed = ImGui::_input_int2(label, stack);
1419 (changed, stack.pop_i32().unwrap(), stack.pop_i32().unwrap())
1420 }
1421 pub fn input_int2_ret_opts(label: &str, v1: i32, v2: i32, input_text_flags: &Vec<&str>) -> (bool, i32, i32) {
1422 let stack = ImGui::push_i32x2(v1, v2);
1423 let changed = ImGui::_input_int2_opts(label, stack, input_text_flags);
1424 (changed, stack.pop_i32().unwrap(), stack.pop_i32().unwrap())
1425 }
1426 pub fn slider_float_ret(label: &str, v: f32, v_min: f32, v_max: f32) -> (bool, f32) {
1427 let stack = ImGui::push_f32(v);
1428 let changed = ImGui::_slider_float(label, stack, v_min, v_max);
1429 (changed, stack.pop_f32().unwrap())
1430 }
1431 pub fn slider_float_ret_opts(label: &str, v: f32, v_min: f32, v_max: f32, display_format: &str, slider_flags: &Vec<&str>) -> (bool, f32) {
1432 let stack = ImGui::push_f32(v);
1433 let changed = ImGui::_slider_float_opts(label, stack, v_min, v_max, display_format, slider_flags);
1434 (changed, stack.pop_f32().unwrap())
1435 }
1436 pub fn slider_float2_ret(label: &str, v1: f32, v2: f32, v_min: f32, v_max: f32) -> (bool, f32, f32) {
1437 let stack = ImGui::push_f32x2(v1, v2);
1438 let changed = ImGui::_slider_float2(label, stack, v_min, v_max);
1439 (changed, stack.pop_f32().unwrap(), stack.pop_f32().unwrap())
1440 }
1441 pub fn slider_float2_ret_opts(label: &str, v1: f32, v2: f32, v_min: f32, v_max: f32, display_format: &str, slider_flags: &Vec<&str>) -> (bool, f32, f32) {
1442 let stack = ImGui::push_f32x2(v1, v2);
1443 let changed = ImGui::_slider_float2_opts(label, stack, v_min, v_max, display_format, slider_flags);
1444 (changed, stack.pop_f32().unwrap(), stack.pop_f32().unwrap())
1445 }
1446 pub fn drag_float_range2_ret(label: &str, v_current_min: f32, v_current_max: f32, v_speed: f32, v_min: f32, v_max: f32) -> (bool, f32, f32) {
1447 let stack = ImGui::push_f32x2(v_current_min, v_current_max);
1448 let changed = ImGui::_drag_float_range2(label, stack, v_speed, v_min, v_max);
1449 (changed, stack.pop_f32().unwrap(), stack.pop_f32().unwrap())
1450 }
1451 pub fn drag_float_range2_ret_opts(label: &str, v_current_min: f32, v_current_max: f32, v_speed: f32, v_min: f32, v_max: f32, format: &str, format_max: &str, slider_flags: &Vec<&str>) -> (bool, f32, f32) {
1452 let stack = ImGui::push_f32x2(v_current_min, v_current_max);
1453 let changed = ImGui::_drag_float_range2_opts(label, stack, v_speed, v_min, v_max, format, format_max, slider_flags);
1454 (changed, stack.pop_f32().unwrap(), stack.pop_f32().unwrap())
1455 }
1456 pub fn drag_int_range2_ret(label: &str, v_current_min: i32, v_current_max: i32, v_speed: f32, v_min: i32, v_max: i32) -> (bool, i32, i32) {
1457 let stack = ImGui::push_i32x2(v_current_min, v_current_max);
1458 let changed = ImGui::_drag_int_range2(label, stack, v_speed, v_min, v_max);
1459 (changed, stack.pop_i32().unwrap(), stack.pop_i32().unwrap())
1460 }
1461 pub fn drag_int_range2_ret_opts(label: &str, v_current_min: i32, v_current_max: i32, v_speed: f32, v_min: i32, v_max: i32, format: &str, format_max: &str, slider_flags: &Vec<&str>) -> (bool, i32, i32) {
1462 let stack = ImGui::push_i32x2(v_current_min, v_current_max);
1463 let changed = ImGui::_drag_int_range2_opts(label, stack, v_speed, v_min, v_max, format, format_max, slider_flags);
1464 (changed, stack.pop_i32().unwrap(), stack.pop_i32().unwrap())
1465 }
1466 pub fn v_slider_float_ret(label: &str, size: &crate::dora::Vec2, v: f32, v_min: f32, v_max: f32) -> (bool, f32) {
1467 let stack = ImGui::push_f32(v);
1468 let changed = ImGui::_v_slider_float(label, size, stack, v_min, v_max);
1469 (changed, stack.pop_f32().unwrap())
1470 }
1471 pub fn v_slider_float_ret_opts(label: &str, size: &crate::dora::Vec2, v: f32, v_min: f32, v_max: f32, format: &str, slider_flags: &Vec<&str>) -> (bool, f32) {
1472 let stack = ImGui::push_f32(v);
1473 let changed = ImGui::_v_slider_float_opts(label, size, stack, v_min, v_max, format, slider_flags);
1474 (changed, stack.pop_f32().unwrap())
1475 }
1476 pub fn v_slider_int_ret(label: &str, size: &crate::dora::Vec2, v: i32, v_min: i32, v_max: i32) -> (bool, i32) {
1477 let stack = ImGui::push_i32(v);
1478 let changed = ImGui::_v_slider_int(label, size, stack, v_min, v_max);
1479 (changed, stack.pop_i32().unwrap())
1480 }
1481 pub fn v_slider_int_ret_opts(label: &str, size: &crate::dora::Vec2, v: i32, v_min: i32, v_max: i32, format: &str, slider_flags: &Vec<&str>) -> (bool, i32) {
1482 let stack = ImGui::push_i32(v);
1483 let changed = ImGui::_v_slider_int_opts(label, size, stack, v_min, v_max, format, slider_flags);
1484 (changed, stack.pop_i32().unwrap())
1485 }
1486 pub fn color_edit3(label: &str, color3: &Color3) -> (bool, Color3) {
1487 let stack = ImGui::push_i32(color3.to_rgb() as i32);
1488 let changed = ImGui::_color_edit3(label, stack);
1489 (changed, Color3::new(stack.pop_i32().unwrap() as u32))
1490 }
1491 pub fn color_edit4(label: &str, color: &Color, show_alpha: bool) -> (bool, Color) {
1492 let stack = ImGui::push_i32(color.to_argb() as i32);
1493 let changed = ImGui::_color_edit4(label, stack, show_alpha);
1494 (changed, Color::new(stack.pop_i32().unwrap() as u32))
1495 }
1496}