1#![allow(clippy::not_unsafe_ptr_arg_deref)] pub use rrplug_proc::{GetFromSQObject, GetFromSquirrelVm, PushToSquirrelVm, SQVMName};
6use std::{mem::MaybeUninit, ptr::NonNull};
7
8use crate::{
9 bindings::{
10 server::{cbaseentity::CBaseEntity, cplayer::CPlayer},
11 squirrelclasstypes::SQRESULT,
12 squirreldatatypes::{
13 SQArray, SQBool, SQClosure, SQFloat, SQFunctionProto, SQInteger, SQNativeClosure,
14 SQObject, SQObjectType, SQObjectValue, SQString, SQStructInstance, SQTable,
15 },
16 },
17 high::squirrel::SQHandle,
18 mid::{
19 squirrel::{
20 get_sq_array, get_sq_bool, get_sq_float, get_sq_int, get_sq_object, get_sq_string,
21 get_sq_vector, push_sq_array, push_sq_bool, push_sq_float, push_sq_int, push_sq_object,
22 push_sq_string, push_sq_vector, sqvm_to_context,
23 },
24 utils::to_cstring,
25 },
26 prelude::*,
27};
28
29use super::UnsafeHandle;
30
31macro_rules! push_to_sqvm {
34 ( $( $function:ident::<$t:ty> );*; ) => { $(
35
36 impl PushToSquirrelVm for $t {
37 #[inline]
38 fn push_to_sqvm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) {
39 $function(sqvm, sqfunctions, self)
40 }
41 }
42 )* }
43}
44
45pub trait PushToSquirrelVm {
51 #[doc(hidden)]
53 const DEFAULT_RESULT: SQRESULT = SQRESULT::SQRESULT_NOTNULL;
54
55 fn push_to_sqvm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions);
57}
58
59push_to_sqvm! {
60 push_sq_string::<String>;
61 push_sq_string::<&str>;
62 push_sq_int::<i32>;
63 push_sq_float::<f32>;
64 push_sq_bool::<bool>;
65 push_sq_vector::<Vector3>;
66 push_sq_object::<SQObject>;
67}
68
69impl<T> PushToSquirrelVm for Vec<T>
70where
71 T: PushToSquirrelVm,
72{
73 fn push_to_sqvm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) {
74 push_sq_array(sqvm, sqfunctions, self);
75 }
76}
77
78impl PushToSquirrelVm for () {
79 const DEFAULT_RESULT: SQRESULT = SQRESULT::SQRESULT_NULL;
80
81 #[inline]
82 fn push_to_sqvm(self, _: NonNull<HSquirrelVM>, _: &SquirrelFunctions) {}
83}
84
85impl PushToSquirrelVm for &CPlayer {
86 fn push_to_sqvm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) {
88 unsafe {
89 let obj =
90 (sqfunctions.sq_create_script_instance)((self as *const CPlayer).cast_mut().cast());
91 (sqfunctions.sq_pushobject)(sqvm.as_ptr(), obj);
92 }
93 }
94}
95
96impl PushToSquirrelVm for &CBaseEntity {
97 fn push_to_sqvm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) {
99 unsafe {
100 let obj = (sqfunctions.sq_create_script_instance)(
101 (self as *const CBaseEntity).cast_mut().cast(),
102 );
103 (sqfunctions.sq_pushobject)(sqvm.as_ptr(), obj);
104 }
105 }
106}
107
108impl<T: PushToSquirrelVm, const N: usize> PushToSquirrelVm for [T; N] {
109 fn push_to_sqvm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) {
110 push_sq_array(sqvm, sqfunctions, self);
111 }
112}
113
114impl<T: PushToSquirrelVm + Clone + Copy> PushToSquirrelVm for &[T] {
116 fn push_to_sqvm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) {
117 push_sq_array(sqvm, sqfunctions, self.iter().copied());
118 }
119}
120
121impl<T: PushToSquirrelVm> PushToSquirrelVm for UnsafeHandle<T>
122where
123 T: PushToSquirrelVm,
124{
125 fn push_to_sqvm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) {
126 self.take().push_to_sqvm(sqvm, sqfunctions)
127 }
128}
129
130pub trait ReturnToVm {
140 fn return_to_vm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) -> SQRESULT;
142}
143
144impl<T: PushToSquirrelVm> ReturnToVm for Option<T> {
145 fn return_to_vm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) -> SQRESULT {
147 match self {
148 Some(rtrn) => {
149 rtrn.push_to_sqvm(sqvm, sqfunctions);
150 T::DEFAULT_RESULT
151 }
152 None => {
153 unsafe { (sqfunctions.sq_pushnull)(sqvm.as_ptr()) };
154 SQRESULT::SQRESULT_NULL
155 }
156 }
157 }
158}
159
160impl<T: PushToSquirrelVm, E: ToString> ReturnToVm for Result<T, E> {
161 fn return_to_vm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) -> SQRESULT {
165 match self {
166 Ok(rtrn) => {
167 rtrn.push_to_sqvm(sqvm, sqfunctions);
168 T::DEFAULT_RESULT
169 }
170 Err(err) => {
171 let err = to_cstring(err.to_string().as_str());
172 unsafe { (sqfunctions.sq_raiseerror)(sqvm.as_ptr(), err.as_ptr()) };
173 SQRESULT::SQRESULT_ERROR
174 }
175 }
176 }
177}
178
179impl<T: PushToSquirrelVm> ReturnToVm for T {
180 fn return_to_vm(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &SquirrelFunctions) -> SQRESULT {
182 self.push_to_sqvm(sqvm, sqfunctions);
183 T::DEFAULT_RESULT
184 }
185}
186
187pub trait IntoSquirrelArgs {
191 fn into_function(
193 self,
194 ) -> Box<
195 dyn FnOnce(NonNull<HSquirrelVM>, &'static SquirrelFunctions) -> i32 + 'static + Send + Sync,
196 >
197 where
198 Self: Sized + Send + Sync + 'static,
199 {
200 Box::new(
201 move |sqvm: NonNull<HSquirrelVM>, sqfunctions: &'static SquirrelFunctions| {
202 self.into_push(sqvm, sqfunctions)
203 },
204 )
205 }
206
207 fn into_push(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &'static SquirrelFunctions) -> i32;
209}
210
211impl<T: PushToSquirrelVm> IntoSquirrelArgs for T {
212 fn into_push(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &'static SquirrelFunctions) -> i32 {
213 if T::DEFAULT_RESULT != SQRESULT::SQRESULT_NULL {
216 self.push_to_sqvm(sqvm, sqfunctions);
217 1
218 } else {
219 0
220 }
221 }
222}
223
224macro_rules! into_squirrel_args_impl{
226 ( $( ($($ty_name: ident : $tuple_index:tt),*) );*; ) => { $(
227 impl<$($ty_name: PushToSquirrelVm,)*> IntoSquirrelArgs for ($($ty_name,)*) {
228 fn into_push(self, sqvm: NonNull<HSquirrelVM>, sqfunctions: &'static SquirrelFunctions) -> i32 {
229 $(
230 self.$tuple_index.push_to_sqvm(sqvm, sqfunctions);
231 )*
232 $crate::macros::sq_utils::__arg_count_helper([$($crate::__replace_expr!($ty_name)),*]) as i32
233 }
234 }
235 )* }
236}
237
238into_squirrel_args_impl! {
239 (T1: 0);
240 (T1: 0, T2: 1);
241 (T1: 0, T2: 1, T3: 2);
242 (T1: 0, T2: 1, T3: 2, T4: 3);
243 (T1: 0, T2: 1, T3: 2, T4: 3, T5: 4);
244 (T1: 0, T2: 1, T3: 2, T4: 3, T5: 4, T6: 5);
245 (T1: 0, T2: 1, T3: 2, T4: 3, T5: 4, T6: 5, T7: 6);
246 (T1: 0, T2: 1, T3: 2, T4: 3, T5: 4, T6: 5, T7: 6, T8: 7);
247 (T1: 0, T2: 1, T3: 2, T4: 3, T5: 4, T6: 5, T7: 6, T8: 7, T9: 8);
248 (T1: 0, T2: 1, T3: 2, T4: 3, T5: 4, T6: 5, T7: 6, T8: 7, T9: 8, T10: 9);
249}
250
251macro_rules! get_from_sqvm {
254 ( $( $function:ident::<$t:ty> );*; ) => { $(
255
256 impl GetFromSquirrelVm for $t {
257 #[inline]
258 fn get_from_sqvm(
259 sqvm: NonNull<HSquirrelVM>,
260 sqfunctions: &SquirrelFunctions,
261 stack_pos: i32,
262 ) -> Self {
263 $function(sqvm, sqfunctions, stack_pos)
264 }
265 }
266 )* };
267
268 ( $( ($($ty_name: ident : $var_name:ident),*) );*; ) => { $(
269 impl<$($ty_name: PushToSquirrelVm,)*> GetFromSquirrelVm for Box<dyn Fn($($ty_name,)*)> {
270 fn get_from_sqvm(
271 sqvm: NonNull<HSquirrelVM>,
272 sqfunctions: &'static SquirrelFunctions,
273 stack_pos: i32,
274 ) -> Self {
275 Box::new(move |$($var_name: $ty_name,)*| { _ =
276 call_sq_object_function!(
277 sqvm,
278 sqfunctions,
279 SQHandle::<SQClosure>::get_from_sqvm(sqvm, sqfunctions, stack_pos),
280 $($var_name),*
281 );
282 })
283 }
284 }
285 )* }
286}
287
288pub trait GetFromSquirrelVm: Sized {
293 fn get_from_sqvm(
298 sqvm: NonNull<HSquirrelVM>,
299 sqfunctions: &'static SquirrelFunctions,
300 stack_pos: i32,
301 ) -> Self;
302
303 #[doc(hidden)]
307 #[inline]
308 fn get_from_sqvm_internal(
309 sqvm: NonNull<HSquirrelVM>,
310 sqfunctions: &'static SquirrelFunctions,
311 stack_pos: &mut i32,
312 ) -> Self {
313 let s = Self::get_from_sqvm(sqvm, sqfunctions, *stack_pos);
314
315 *stack_pos += 1;
318
319 s
320 }
321}
322
323get_from_sqvm! {
324 get_sq_string::<String>;
325 get_sq_int::<i32>;
326 get_sq_float::<f32>;
327 get_sq_bool::<bool>;
328 get_sq_vector::<Vector3>;
329 get_sq_object::<SQObject>;
330}
331
332impl<T> GetFromSquirrelVm for Vec<T>
333where
334 T: GetFromSQObject,
335{
336 fn get_from_sqvm(
337 sqvm: NonNull<HSquirrelVM>,
338 _: &'static SquirrelFunctions,
339 stack_pos: i32,
340 ) -> Self {
341 get_sq_array(sqvm, stack_pos)
342 }
343}
344
345impl GetFromSquirrelVm for Option<&mut CPlayer> {
346 fn get_from_sqvm(
347 mut sqvm: NonNull<HSquirrelVM>,
348 sqfunctions: &SquirrelFunctions,
349 stack_pos: i32,
350 ) -> Self {
351 unsafe {
352 debug_assert_eq!(
353 sqvm_to_context(sqvm),
354 ScriptContext::SERVER,
355 "CPlayer only exists on server vm use C_Player for CLIENT and UI"
356 );
357
358 let sqvm = sqvm.as_mut();
359 let cs_sqvm = sqvm
360 .sharedState
361 .as_ref()
362 .expect("shared state was invalid")
363 .cSquirrelVM;
364
365 let mut obj = MaybeUninit::<SQObject>::uninit();
366 (sqfunctions.sq_getobject)(sqvm, stack_pos, obj.as_mut_ptr());
367
368 (sqfunctions.sq_getentityfrominstance)(
369 cs_sqvm,
370 obj.as_mut_ptr(),
371 (sqfunctions.sq_get_entity_constant_cbase_entity)(),
372 )
373 .cast::<CBaseEntity>()
374 .as_mut()?
375 .dynamic_cast_mut()
376 }
377 }
378}
379
380impl GetFromSquirrelVm for Option<&mut CBaseEntity> {
381 fn get_from_sqvm(
382 mut sqvm: NonNull<HSquirrelVM>,
383 sqfunctions: &SquirrelFunctions,
384 stack_pos: i32,
385 ) -> Self {
386 unsafe {
387 debug_assert_eq!(
388 sqvm_to_context(sqvm),
389 ScriptContext::SERVER,
390 "CBaseEnity only exists on server vm"
391 );
392
393 let sqvm = sqvm.as_mut();
394 let cs_sqvm = sqvm
395 .sharedState
396 .as_ref()
397 .expect("shared state was invalid")
398 .cSquirrelVM;
399
400 let mut obj = MaybeUninit::<SQObject>::uninit();
401 (sqfunctions.sq_getobject)(sqvm, stack_pos, obj.as_mut_ptr());
402
403 let ent = (sqfunctions.sq_getentityfrominstance)(
404 cs_sqvm,
405 obj.as_mut_ptr(),
406 (sqfunctions.sq_get_entity_constant_cbase_entity)(),
407 )
408 .cast::<CBaseEntity>()
409 .as_mut()?;
410
411 Some(ent)
412 }
413 }
414}
415
416impl<'a, T: IsSQObject<'a>> GetFromSquirrelVm for SQHandle<'a, T> {
417 fn get_from_sqvm(
418 sqvm: NonNull<HSquirrelVM>,
419 sqfunctions: &SquirrelFunctions,
420 stack_pos: i32,
421 ) -> Self {
422 unsafe {
423 let mut obj = std::mem::MaybeUninit::<SQObject>::uninit();
424 (sqfunctions.sq_getobject)(sqvm.as_ptr(), stack_pos, obj.as_mut_ptr());
425
426 match Self::try_new(obj.assume_init()) {
427 Ok(handle) => handle,
428 Err(_) => {
429 panic!(
430 "the object wasn't the correct type got {:X} expected {}",
431 obj.assume_init()._Type as i32,
432 std::any::type_name::<T>()
433 );
434 }
435 }
436 }
437 }
438}
439
440impl<T: IntoSquirrelArgs> GetFromSquirrelVm for SquirrelFn<'_, T> {
441 #[inline]
442 fn get_from_sqvm(
443 sqvm: NonNull<HSquirrelVM>,
444 sqfunctions: &'static SquirrelFunctions,
445 stack_pos: i32,
446 ) -> Self {
447 SquirrelFn {
448 func: GetFromSquirrelVm::get_from_sqvm(sqvm, sqfunctions, stack_pos),
449 phantom: std::marker::PhantomData,
450 }
451 }
452}
453
454impl GetFromSquirrelVm for () {
455 fn get_from_sqvm(_: NonNull<HSquirrelVM>, _: &SquirrelFunctions, _: i32) -> Self {}
457}
458
459pub trait GetFromSQObject {
470 fn get_from_sqobject(obj: &SQObject) -> Self;
474}
475
476impl GetFromSQObject for () {
477 #[inline]
478 fn get_from_sqobject(_: &SQObject) -> Self {}
479}
480
481impl GetFromSQObject for String {
482 #[inline]
483 fn get_from_sqobject(obj: &SQObject) -> Self {
484 unsafe {
485 std::ffi::CStr::from_ptr(
486 (&obj._VAL.asString.as_ref().unwrap_unchecked()._val) as *const i8,
487 )
488 .to_string_lossy()
489 .into()
490 }
491 }
492}
493
494impl GetFromSQObject for i32 {
495 #[inline]
496 fn get_from_sqobject(obj: &SQObject) -> Self {
497 unsafe { obj._VAL.asInteger }
498 }
499}
500
501impl GetFromSQObject for f32 {
502 #[inline]
503 fn get_from_sqobject(obj: &SQObject) -> Self {
504 unsafe { obj._VAL.asFloat }
505 }
506}
507
508impl GetFromSQObject for bool {
509 #[inline]
510 fn get_from_sqobject(obj: &SQObject) -> Self {
511 unsafe { obj._VAL.asInteger != 0 }
512 }
513}
514
515impl GetFromSQObject for Vector3 {
516 #[inline]
517 fn get_from_sqobject(obj: &SQObject) -> Self {
518 (obj as *const SQObject).into()
519 }
520}
521
522impl GetFromSQObject for SQObject {
523 #[inline]
524 fn get_from_sqobject(obj: &SQObject) -> Self {
525 *obj
526 }
527}
528
529impl<'a, T: IsSQObject<'a>> GetFromSQObject for SQHandle<'a, T> {
530 #[inline]
531 fn get_from_sqobject(obj: &SQObject) -> Self {
532 match Self::try_new(*obj) {
533 Ok(handle) => handle,
534 Err(_) => {
535 panic!(
536 "the object wasn't the correct type got {:X} expected {}",
537 obj._Type as i32,
538 std::any::type_name::<T>()
539 );
540 }
541 }
542 }
543}
544
545impl<T: IntoSquirrelArgs> GetFromSQObject for SquirrelFn<'_, T> {
546 #[inline]
547 fn get_from_sqobject(obj: &SQObject) -> Self {
548 SquirrelFn {
549 func: SQHandle::try_new(obj.to_owned())
550 .expect("the squirrel object wasn't a function lol L"),
551 phantom: std::marker::PhantomData,
552 }
553 }
554}
555
556impl<T> GetFromSQObject for Vec<T>
557where
558 T: GetFromSQObject,
559{
560 #[inline]
561 fn get_from_sqobject(obj: &SQObject) -> Self {
562 unsafe {
563 let array = obj
564 ._VAL
565 .asArray
566 .as_ref()
567 .expect("the sq object may be invalid");
568
569 (0..array._usedSlots as usize)
570 .map(|i| array._values.add(i))
571 .filter_map(|obj| obj.as_ref())
572 .map(T::get_from_sqobject)
573 .collect()
574 }
575 }
576}
577
578macro_rules! sqvm_name {
581 ($( ($($ty_name:ident : $var_name:ident),*) );*;) => {
582 $(
583 impl<$($ty_name: SQVMName,)*> SQVMName for ($($ty_name,)*) {
584 fn get_sqvm_name() -> String {
585 let mut name = String::new();
586
587 $(
588 if !name.is_empty() { name.push(',');
590 name.push(' ');
591 }
592 name.push_str(&$ty_name::get_sqvm_name());
593 )*
594
595 name
596 }
597 }
598 )*
599 };
600
601 ( $( $t:ty = $sqty:literal );*; ) => {
602 $(
603 impl SQVMName for $t {
604 #[inline]
605 fn get_sqvm_name() -> String {
606 $sqty.to_string()
607 }
608 }
609 )*
610 };
611
612 ( $( LIFE $t:ty = $sqty:literal );*; ) => {
613 $(
614 impl<'a> SQVMName for $t {
615 #[inline]
616 fn get_sqvm_name() -> String {
617 $sqty.to_string()
618 }
619 }
620 )*
621 };
622}
623
624pub trait SQVMName {
631 fn get_sqvm_name() -> String;
635}
636
637sqvm_name! {
638 String = "string";
639 &str = "string";
640 i32 = "int";
641 f32 = "float";
642 bool = "bool";
643 Vector3 = "vector";
644 Option<&mut CPlayer> = "entity";
645 Option<&mut CBaseEntity> = "entity";
646 Option<&CPlayer> = "entity";
647 Option<&CBaseEntity> = "entity";
648 SQObject = "var";
649 () = "void";
650}
651
652sqvm_name! {
653 LIFE SQHandle<'a, SQClosure> = "var";
654 LIFE SQHandle<'a, SQTable> = "table";
655 LIFE SQHandle<'a, SQString> = "string";
656 LIFE SQHandle<'a, SQArray> = "array";
657 LIFE SQHandle<'a, SQFloat> = "float";
658 LIFE SQHandle<'a, SQInteger> = "int";
659 LIFE SQHandle<'a, SQFunctionProto> = "var";
660 LIFE SQHandle<'a, SQStructInstance> = "var";
661 LIFE SQHandle<'a, SQBool> = "bool";
662 LIFE SQHandle<'a, SQNativeClosure> = "var";
663}
664
665sqvm_name! {
666 (T1: v2);
667 (T1: v1, T2: v2);
668 (T1: v1, T2: v2, T3: v3);
669 (T1: v1, T2: v2, T3: v3, T4: v4);
670 (T1: v1, T2: v2, T3: v3, T4: v4, T5: v5);
671 (T1: v1, T2: v2, T3: v3, T4: v4, T5: v5, T6: v6);
672 (T1: v1, T2: v2, T3: v3, T4: v4, T5: v5, T6: v6, T7: v7);
673 (T1: v1, T2: v2, T3: v3, T4: v4, T5: v5, T6: v6, T7: v7, T8: v8);
674 (T1: v1, T2: v2, T3: v3, T4: v4, T5: v5, T6: v6, T7: v7, T8: v8, T9: v9);
675 (T1: v1, T2: v2, T3: v3, T4: v4, T5: v5, T6: v6, T7: v7, T8: v8, T9: v9, T10: v10);
676}
677
678impl<T: SQVMName + IntoSquirrelArgs> SQVMName for SquirrelFn<'_, T> {
679 fn get_sqvm_name() -> String {
680 format!("void functionref({})", T::get_sqvm_name())
681 }
682}
683
684impl<T: SQVMName> SQVMName for Vec<T> {
685 fn get_sqvm_name() -> String {
686 format!("array<{}>", T::get_sqvm_name())
687 }
688}
689
690impl<T: SQVMName, const N: usize> SQVMName for [T; N] {
691 fn get_sqvm_name() -> String {
692 Vec::<T>::get_sqvm_name()
693 }
694}
695
696impl<T: SQVMName> SQVMName for &[T] {
697 fn get_sqvm_name() -> String {
698 Vec::<T>::get_sqvm_name()
699 }
700}
701
702impl<T: SQVMName> SQVMName for Option<T> {
704 fn get_sqvm_name() -> String {
705 format!("{} ornull", T::get_sqvm_name())
706 }
707}
708
709impl<T: SQVMName, E> SQVMName for Result<T, E> {
710 fn get_sqvm_name() -> String {
711 T::get_sqvm_name() }
713}
714
715macro_rules! is_sq_object {
725 ( $( $object:ty,RT: $rt:expr,OT: $ot:expr, EXTRACT: * $extract:ident );*; ) => {
726 $(
727 impl<'a> IsSQObject<'a> for $object {
728 const OT_TYPE: SQObjectType = $ot;
729 const RT_TYPE: SQObjectType = $rt;
730
731 fn extract_mut(val: &'a mut SQObjectValue) -> &'a mut Self {
732 unsafe { &mut *val.$extract } }
734
735 fn extract(val: &'a SQObjectValue) -> &'a Self {
736 unsafe { &*val.$extract } }
738 }
739 )*
740 };
741
742 ( $( $object:ty,RT: $rt:expr,OT: $ot:expr, EXTRACT: $extract:ident );*; ) => {
743 $(
744 impl<'a> IsSQObject<'a> for $object {
745 const OT_TYPE: SQObjectType = $ot;
746 const RT_TYPE: SQObjectType = $rt;
747
748 fn extract_mut(val: &'a mut SQObjectValue) -> &'a mut Self {
749 unsafe { std::mem::transmute(&mut val.$extract) } }
751
752 fn extract(val: &'a SQObjectValue) -> &'a Self {
753 unsafe { std::mem::transmute(&val.$extract) } }
755 }
756 )*
757 }
758}
759
760pub trait IsSQObject<'a> {
762 const OT_TYPE: SQObjectType;
764 const RT_TYPE: SQObjectType;
766
767 fn extract(val: &'a SQObjectValue) -> &'a Self;
771
772 fn extract_mut(val: &'a mut SQObjectValue) -> &'a mut Self;
776}
777
778is_sq_object! {
779 SQTable, RT: SQObjectType::RT_TABLE, OT: SQObjectType::OT_TABLE, EXTRACT: * asTable;
780 SQString, RT: SQObjectType::RT_STRING, OT: SQObjectType::OT_STRING, EXTRACT: * asString;
781 SQFunctionProto, RT: SQObjectType::RT_FUNCPROTO, OT: SQObjectType::OT_FUNCPROTO, EXTRACT: * asFuncProto;
782 SQClosure, RT: SQObjectType::RT_CLOSURE, OT: SQObjectType::OT_CLOSURE, EXTRACT: * asClosure;
783 SQStructInstance, RT: SQObjectType::RT_INSTANCE, OT: SQObjectType::OT_STRUCT, EXTRACT: * asStructInstance;
784 SQNativeClosure, RT: SQObjectType::RT_NATIVECLOSURE, OT: SQObjectType::OT_NATIVECLOSURE, EXTRACT: * asNativeClosure;
785 SQArray, RT: SQObjectType::RT_ARRAY, OT: SQObjectType::OT_ARRAY, EXTRACT: * asArray;
786}
787is_sq_object! {
788 SQFloat, RT: SQObjectType::RT_FLOAT, OT: SQObjectType::OT_FLOAT, EXTRACT: asFloat;
789 SQInteger, RT: SQObjectType::RT_INTEGER, OT: SQObjectType::OT_INTEGER, EXTRACT: asInteger;
790 SQBool, RT: SQObjectType::RT_BOOL, OT: SQObjectType::OT_BOOL, EXTRACT: asInteger;
791}