1use enum_dispatch::enum_dispatch;
3use nsi_sys::*;
4use std::{
5 ffi::{CString, c_void},
6 marker::PhantomData,
7 pin::Pin,
8};
9use ustr::{Ustr, ustr};
10
11#[allow(unused_imports)]
13use crate::*;
14
15#[inline(always)]
16pub(crate) fn get_c_param_vec(
17 args: Option<&ArgSlice>,
18) -> (i32, *const NSIParam, Vec<NSIParam>) {
19 let args = match args {
20 Some(args) => args
21 .iter()
22 .map(|arg| NSIParam {
23 name: arg.name.as_char_ptr(),
24 data: arg.data.as_c_ptr(),
25 type_: arg.data.type_() as _,
26 arraylength: arg.array_length as _,
27 count: (arg.data.len() / arg.array_length) as _,
28 flags: arg.flags as _,
29 })
30 .collect::<Vec<_>>(),
31 None => Vec::new(),
32 };
33
34 (args.len() as _, args.as_ptr(), args)
35}
36
37pub type ArgSlice<'a, 'b> = [Arg<'a, 'b>];
40
41pub type ArgVec<'a, 'b> = Vec<Arg<'a, 'b>>;
44
45#[derive(Debug, Clone)]
48pub struct Arg<'a, 'b> {
49 pub(crate) name: Ustr,
50 pub(crate) data: ArgData<'a, 'b>,
51 pub(crate) array_length: usize,
53 pub(crate) flags: i32,
55}
56
57impl<'a, 'b> Arg<'a, 'b> {
58 #[inline]
59 pub fn new(name: &str, data: ArgData<'a, 'b>) -> Self {
60 Arg {
61 name: ustr(name),
62 data,
63 array_length: 1,
64 flags: 0,
65 }
66 }
67
68 #[inline]
70 pub fn array_len(mut self, length: usize) -> Self {
71 self.array_length = length;
72 self.flags |= NSIParamFlags::IsArray.bits();
73 self
74 }
75
76 #[inline]
78 pub fn per_face(mut self) -> Self {
79 self.flags |= NSIParamFlags::PerFace.bits();
80 self
81 }
82
83 #[inline]
85 pub fn per_vertex(mut self) -> Self {
86 self.flags |= NSIParamFlags::PerVertex.bits();
87 self
88 }
89
90 #[inline]
92 pub fn linear_interpolation(mut self) -> Self {
93 self.flags |= NSIParamFlags::InterpolateLinear.bits();
94 self
95 }
96}
97
98#[enum_dispatch(ArgData)]
99pub(crate) trait ArgDataMethods {
100 fn type_(&self) -> DataType;
102 fn len(&self) -> usize;
103 fn as_c_ptr(&self) -> *const c_void;
104}
105
106#[enum_dispatch]
117#[derive(Debug, Clone)]
118pub enum ArgData<'a, 'b> {
119 F32,
121 F32Slice(F32Slice<'a>),
123 F64,
125 F64Slice(F64Slice<'a>),
127 I32,
129 I32Slice(I32Slice<'a>),
131 I64,
133 I64Slice(I64Slice<'a>),
135 String(String),
137 StringSlice(StringSlice),
139 Color(Color<'a>),
142 ColorSlice(ColorSlice<'a>),
144 Point(Point<'a>),
146 PointSlice(PointSlice<'a>),
148 Vector(Vector<'a>),
150 VectorSlice(VectorSlice<'a>),
152 Normal(Normal<'a>),
154 NormalSlice(NormalSlice<'a>),
156 MatrixF32(MatrixF32<'a>),
158 MatrixF32Slice(MatrixF32Slice<'a>),
160 MatrixF64(MatrixF64<'a>),
162 MatrixF64Slice(MatrixF64Slice<'a>),
164 Point4F32Slice(Point4F32Slice<'a>),
171 Reference(Reference<'b>),
208 ReferenceSlice(ReferenceSlice<'b>),
210 Callback(Callback<'b>),
212}
213
214macro_rules! nsi_data_def {
215 ($type: ty, $name: ident, $nsi_type: expr) => {
216 #[derive(Debug, Clone, PartialEq)]
218 pub struct $name {
219 data: $type,
220 }
221
222 impl $name {
223 pub fn new(data: $type) -> Self {
224 Self { data }
225 }
226 }
227
228 impl ArgDataMethods for $name {
229 fn type_(&self) -> DataType {
230 $nsi_type
231 }
232
233 fn len(&self) -> usize {
234 1
235 }
236
237 fn as_c_ptr(&self) -> *const c_void {
238 &self.data as *const $type as _
239 }
240 }
241 };
242}
243
244macro_rules! nsi_data_array_def {
245 ($type: ty, $name: ident, $nsi_type: expr) => {
246 #[derive(Debug, Clone, PartialEq)]
248 pub struct $name<'a> {
249 data: &'a [$type],
250 }
251
252 impl<'a> $name<'a> {
253 pub fn new(data: &'a [$type]) -> Self {
254 Self { data }
256 }
257 }
258
259 impl<'a> ArgDataMethods for $name<'a> {
260 fn type_(&self) -> DataType {
261 $nsi_type
262 }
263
264 fn len(&self) -> usize {
265 self.data.len() }
267
268 fn as_c_ptr(&self) -> *const c_void {
269 self.data.as_ptr() as _
270 }
271 }
272 };
273}
274
275macro_rules! nsi_tuple_data_array_def {
276 ($type: ty, $name: ident, $nsi_type: expr, $len: expr ) => {
277 #[derive(Debug, Clone, PartialEq)]
279 pub struct $name<'a> {
280 data: &'a [[$type; $len]],
281 }
282
283 impl<'a> $name<'a> {
284 pub fn new(data: &'a [[$type; $len]]) -> Self {
285 Self { data }
287 }
288 }
289
290 impl<'a> ArgDataMethods for $name<'a> {
291 fn type_(&self) -> DataType {
292 $nsi_type
293 }
294
295 fn len(&self) -> usize {
296 self.data.len() }
298
299 fn as_c_ptr(&self) -> *const c_void {
300 self.data.as_ptr() as _
301 }
302 }
303 };
304}
305
306macro_rules! nsi_tuple_data_def {
307 ($type: tt, $len: expr, $name: ident, $nsi_type: expr) => {
308 #[derive(Debug, Clone, PartialEq)]
310 pub struct $name<'a> {
311 data: &'a [$type; $len],
312 }
313
314 impl<'a> $name<'a> {
315 pub fn new(data: &'a [$type; $len]) -> Self {
316 Self { data }
317 }
318 }
319
320 impl<'a> ArgDataMethods for $name<'a> {
321 fn type_(&self) -> DataType {
322 $nsi_type
323 }
324
325 fn len(&self) -> usize {
326 1
327 }
328
329 fn as_c_ptr(&self) -> *const c_void {
330 self.data.as_ptr() as _
331 }
332 }
333 };
334}
335
336nsi_data_def!(f32, F32, DataType::F32);
337nsi_data_def!(f64, F64, DataType::F64);
338nsi_data_def!(i32, I32, DataType::I32);
339nsi_data_def!(i64, I64, DataType::I64);
340
341#[derive(Debug, Clone)]
351pub struct Reference<'a> {
352 data: *const c_void,
353 _marker: PhantomData<&'a ()>,
354}
355
356unsafe impl Send for Reference<'static> {}
359unsafe impl Sync for Reference<'static> {}
360
361pub trait StableDeref<'a> {
364 fn stable_deref(&self) -> *const c_void;
366}
367
368impl<'a, T: ?Sized> StableDeref<'a> for &'a Box<T> {
369 fn stable_deref(&self) -> *const c_void {
370 self.as_ref() as *const T as *const c_void
371 }
372}
373
374impl<'a, T: ?Sized> StableDeref<'a> for &'a Arc<T> {
375 fn stable_deref(&self) -> *const c_void {
376 self.as_ref() as *const T as *const c_void
377 }
378}
379
380impl<'a, T: ?Sized> StableDeref<'a> for &'a Pin<Box<T>> {
381 fn stable_deref(&self) -> *const c_void {
382 self.as_ref().get_ref() as *const T as *const c_void
383 }
384}
385
386use std::sync::Arc;
387
388impl<'a> Reference<'a> {
389 pub fn new<S: StableDeref<'a>>(data: S) -> Self {
392 let ptr = data.stable_deref();
393 debug_assert!(!ptr.is_null(), "Reference created with null pointer");
394
395 Self {
396 data: ptr,
397 _marker: PhantomData,
398 }
399 }
400
401 #[allow(clippy::borrowed_box)]
405 pub fn from_box<T: ?Sized>(data: &'a Box<T>) -> Self {
406 let ptr = data.as_ref() as *const T as *const c_void;
407 debug_assert!(!ptr.is_null(), "Reference created with null pointer");
408
409 Self {
410 data: ptr,
411 _marker: PhantomData,
412 }
413 }
414
415 pub fn from_arc<T: ?Sized>(data: &'a Arc<T>) -> Self {
419 let ptr = data.as_ref() as *const T as *const c_void;
420 debug_assert!(!ptr.is_null(), "Reference created with null pointer");
421
422 Self {
423 data: ptr,
424 _marker: PhantomData,
425 }
426 }
427
428 pub fn from_pin_box<T: ?Sized>(data: &'a Pin<Box<T>>) -> Self {
432 let ptr = data.as_ref().get_ref() as *const T as *const c_void;
433 debug_assert!(!ptr.is_null(), "Reference created with null pointer");
434
435 Self {
436 data: ptr,
437 _marker: PhantomData,
438 }
439 }
440
441 pub unsafe fn from_stable<T: ?Sized>(data: &'a T) -> Self {
454 let ptr = data as *const T as *const c_void;
455 debug_assert!(!ptr.is_null(), "Reference created with null pointer");
456
457 Self {
458 data: ptr,
459 _marker: PhantomData,
460 }
461 }
462
463 pub unsafe fn from_ptr(ptr: *const c_void) -> Self {
471 debug_assert!(!ptr.is_null(), "Reference created with null pointer");
472 Self {
473 data: ptr,
474 _marker: PhantomData,
475 }
476 }
477}
478
479impl<'a> ArgDataMethods for Reference<'a> {
480 fn type_(&self) -> DataType {
481 DataType::Reference
482 }
483
484 fn len(&self) -> usize {
485 1
486 }
487
488 fn as_c_ptr(&self) -> *const c_void {
489 self.data
490 }
491}
492
493pub trait CallbackPtr {
494 #[doc(hidden)]
495 #[allow(clippy::wrong_self_convention)]
496 fn to_ptr(self) -> *const c_void;
497}
498
499unsafe impl Send for Callback<'static> {}
500unsafe impl Sync for Callback<'static> {}
501
502#[derive(Debug, Clone)]
504pub struct Callback<'a> {
505 data: *const c_void,
506 _marker: PhantomData<&'a mut ()>,
507}
508
509impl<'a> Callback<'a> {
510 pub fn new<T: CallbackPtr>(data: T) -> Self {
511 Self {
512 data: data.to_ptr(),
513 _marker: PhantomData,
514 }
515 }
516}
517
518impl<'a> ArgDataMethods for Callback<'a> {
519 fn type_(&self) -> DataType {
520 DataType::Reference
521 }
522
523 fn len(&self) -> usize {
524 1
525 }
526
527 fn as_c_ptr(&self) -> *const c_void {
528 self.data
529 }
530}
531
532#[derive(Debug, Clone)]
534pub struct String {
535 #[allow(dead_code)]
536 data: CString,
537 pointer: *const c_void,
539}
540
541unsafe impl Send for String {}
542unsafe impl Sync for String {}
543
544impl String {
545 pub fn new<T: Into<Vec<u8>>>(data: T) -> Self {
546 let data = CString::new(data).unwrap();
547 let pointer = data.as_ptr() as _;
548
549 String { data, pointer }
550 }
551}
552
553impl ArgDataMethods for String {
554 fn type_(&self) -> DataType {
555 DataType::String
556 }
557
558 fn len(&self) -> usize {
559 1
560 }
561
562 fn as_c_ptr(&self) -> *const c_void {
563 &self.pointer as *const *const c_void as _
564 }
565}
566
567nsi_data_array_def!(f32, F32Slice, DataType::F32);
568nsi_data_array_def!(f64, F64Slice, DataType::F64);
569nsi_data_array_def!(i32, I32Slice, DataType::I32);
570nsi_data_array_def!(i64, I64Slice, DataType::I64);
571nsi_tuple_data_array_def!(f32, ColorSlice, DataType::Color, 3);
572nsi_tuple_data_array_def!(f32, PointSlice, DataType::Point, 3);
573nsi_tuple_data_array_def!(f32, VectorSlice, DataType::Vector, 3);
574nsi_tuple_data_array_def!(f32, NormalSlice, DataType::Normal, 3);
575nsi_tuple_data_array_def!(f32, MatrixF32Slice, DataType::MatrixF32, 16);
576nsi_tuple_data_array_def!(f64, MatrixF64Slice, DataType::MatrixF64, 16);
577
578#[derive(Debug, Clone, PartialEq)]
587pub struct Point4F32Slice<'a> {
588 data: &'a [[f32; 4]],
589}
590
591impl<'a> Point4F32Slice<'a> {
592 pub fn new(data: &'a [[f32; 4]]) -> Self {
593 Self { data }
594 }
595}
596
597impl<'a> ArgDataMethods for Point4F32Slice<'a> {
598 fn type_(&self) -> DataType {
599 DataType::F32
600 }
601
602 fn len(&self) -> usize {
606 self.data.len() * 4
607 }
608
609 fn as_c_ptr(&self) -> *const c_void {
610 self.data.as_ptr() as _
611 }
612}
613
614#[derive(Debug, Clone)]
616pub struct ReferenceSlice<'a> {
617 data: Vec<*const c_void>,
618 _marker: PhantomData<&'a ()>,
619}
620
621unsafe impl Send for ReferenceSlice<'static> {}
622unsafe impl Sync for ReferenceSlice<'static> {}
623
624impl<'a> ReferenceSlice<'a> {
625 pub fn new<T>(data: &'a [&'a T]) -> Self {
626 debug_assert_eq!(0, data.len() % DataType::Reference.elemensize());
627
628 Self {
629 data: data.iter().map(|r| r as *const _ as _).collect(),
630 _marker: PhantomData,
631 }
632 }
633}
634
635impl<'a> ArgDataMethods for ReferenceSlice<'a> {
636 fn type_(&self) -> DataType {
637 DataType::Reference
638 }
639
640 fn len(&self) -> usize {
641 self.data.len() / DataType::Reference.elemensize()
642 }
643
644 fn as_c_ptr(&self) -> *const c_void {
645 self.data.as_ptr() as _
646 }
647}
648
649#[derive(Debug, Clone)]
651pub struct StringSlice {
652 #[allow(dead_code)]
653 data: Vec<CString>,
654 pointer: Vec<*const c_void>,
655}
656
657unsafe impl Send for StringSlice {}
658unsafe impl Sync for StringSlice {}
659
660impl StringSlice {
661 pub fn new<T: Into<Vec<u8>> + Copy>(data: &[T]) -> Self {
662 let data = data
663 .iter()
664 .map(|s| CString::new(*s).unwrap())
665 .collect::<Vec<_>>();
666 let pointer = data.iter().map(|s| s.as_ptr() as _).collect();
667
668 StringSlice { data, pointer }
669 }
670}
671
672impl ArgDataMethods for StringSlice {
673 fn type_(&self) -> DataType {
674 DataType::String
675 }
676
677 fn len(&self) -> usize {
678 self.pointer.len()
679 }
680
681 fn as_c_ptr(&self) -> *const c_void {
682 self.pointer.as_ptr() as _
683 }
684}
685
686nsi_tuple_data_def!(f32, 3, Color, DataType::Color);
687nsi_tuple_data_def!(f32, 3, Point, DataType::Point);
688nsi_tuple_data_def!(f32, 3, Vector, DataType::Vector);
689nsi_tuple_data_def!(f32, 3, Normal, DataType::Normal);
690nsi_tuple_data_def!(f32, 16, MatrixF32, DataType::MatrixF32);
691nsi_tuple_data_def!(f64, 16, MatrixF64, DataType::MatrixF64);
692
693#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
695#[repr(i32)]
696pub(crate) enum DataType {
697 F32 = NSIType::F32 as _,
699 F64 = NSIType::F64 as _,
701 I32 = NSIType::I32 as _,
703 I64 = NSIType::I64 as _,
705 String = NSIType::String as _,
707 Color = NSIType::Color as _,
711 Point = NSIType::Point as _,
713 Vector = NSIType::Vector as _,
715 Normal = NSIType::Normal as _,
717 MatrixF32 = NSIType::MatrixF32 as _,
719 MatrixF64 = NSIType::MatrixF64 as _,
721 Reference = NSIType::Pointer as _,
723}
724
725impl DataType {
726 #[inline]
728 pub(crate) fn elemensize(&self) -> usize {
729 match self {
730 DataType::F32 => 1,
731 DataType::F64 => 1,
732 DataType::I32 => 1,
733 DataType::I64 => 1,
734 DataType::String => 1,
735 DataType::Color => 3,
736 DataType::Point => 3,
737 DataType::Vector => 3,
738 DataType::Normal => 3,
739 DataType::MatrixF32 => 16,
740 DataType::MatrixF64 => 16,
741 DataType::Reference => 1,
742 }
743 }
744}
745
746#[macro_export]
752macro_rules! f32 {
753 ($name: literal, $value: expr) => {
754 nsi::Arg::new($name, nsi::ArgData::from(nsi::F32::new($value)))
755 };
756 ($name: path, $value: expr) => {{
757 const __ATTR_CHECK: $crate::Attribute<f32> = $name;
758 nsi::Arg::new(
759 __ATTR_CHECK.name(),
760 nsi::ArgData::from(nsi::F32::new($value)),
761 )
762 }};
763}
764
765#[macro_export]
770macro_rules! f32_slice {
771 ($name: literal, $value: expr) => {
772 nsi::Arg::new($name, nsi::ArgData::from(nsi::F32Slice::new($value)))
773 };
774 ($name: path, $value: expr) => {{
775 const __ATTR_CHECK: $crate::Attribute<[f32]> = $name;
776 nsi::Arg::new(
777 __ATTR_CHECK.name(),
778 nsi::ArgData::from(nsi::F32Slice::new($value)),
779 )
780 }};
781}
782
783#[macro_export]
788macro_rules! f64 {
789 ($name: literal, $value: expr) => {
790 nsi::Arg::new($name, nsi::ArgData::from(nsi::F64::new($value)))
791 };
792 ($name: path, $value: expr) => {{
793 const __ATTR_CHECK: $crate::Attribute<f64> = $name;
794 nsi::Arg::new(
795 __ATTR_CHECK.name(),
796 nsi::ArgData::from(nsi::F64::new($value)),
797 )
798 }};
799}
800
801#[macro_export]
806macro_rules! f64_slice {
807 ($name: literal, $value: expr) => {
808 nsi::Arg::new($name, nsi::ArgData::from(nsi::F64Slice::new($value)))
809 };
810 ($name: path, $value: expr) => {{
811 const __ATTR_CHECK: $crate::Attribute<[f64]> = $name;
812 nsi::Arg::new(
813 __ATTR_CHECK.name(),
814 nsi::ArgData::from(nsi::F64Slice::new($value)),
815 )
816 }};
817}
818
819#[macro_export]
824macro_rules! i32 {
825 ($name: literal, $value: expr) => {
826 nsi::Arg::new($name, nsi::ArgData::from(nsi::I32::new($value)))
827 };
828 ($name: path, $value: expr) => {{
829 const __ATTR_CHECK: $crate::Attribute<i32> = $name;
830 nsi::Arg::new(
831 __ATTR_CHECK.name(),
832 nsi::ArgData::from(nsi::I32::new($value)),
833 )
834 }};
835}
836
837#[macro_export]
842macro_rules! i32_slice {
843 ($name: literal, $value: expr) => {
844 nsi::Arg::new($name, nsi::ArgData::from(nsi::I32Slice::new($value)))
845 };
846 ($name: path, $value: expr) => {{
847 const __ATTR_CHECK: $crate::Attribute<[i32]> = $name;
848 nsi::Arg::new(
849 __ATTR_CHECK.name(),
850 nsi::ArgData::from(nsi::I32Slice::new($value)),
851 )
852 }};
853}
854
855#[macro_export]
860macro_rules! i64 {
861 ($name: literal, $value: expr) => {
862 nsi::Arg::new($name, nsi::ArgData::from(nsi::I64::new($value)))
863 };
864 ($name: path, $value: expr) => {{
865 const __ATTR_CHECK: $crate::Attribute<i64> = $name;
866 nsi::Arg::new(
867 __ATTR_CHECK.name(),
868 nsi::ArgData::from(nsi::I64::new($value)),
869 )
870 }};
871}
872
873#[macro_export]
878macro_rules! i64_slice {
879 ($name: literal, $value: expr) => {
880 nsi::Arg::new($name, nsi::ArgData::from(nsi::I64Slice::new($value)))
881 };
882 ($name: path, $value: expr) => {{
883 const __ATTR_CHECK: $crate::Attribute<[i64]> = $name;
884 nsi::Arg::new(
885 __ATTR_CHECK.name(),
886 nsi::ArgData::from(nsi::I64Slice::new($value)),
887 )
888 }};
889}
890
891#[macro_export]
896macro_rules! color {
897 ($name: literal, $value: expr) => {
898 nsi::Arg::new($name, nsi::ArgData::from(nsi::Color::new($value)))
899 };
900 ($name: path, $value: expr) => {{
901 const __ATTR_CHECK: $crate::Attribute<$crate::Color3F32> = $name;
902 nsi::Arg::new(
903 __ATTR_CHECK.name(),
904 nsi::ArgData::from(nsi::Color::new($value)),
905 )
906 }};
907}
908
909#[macro_export]
914macro_rules! color_slice {
915 ($name: literal, $value: expr) => {
916 nsi::Arg::new($name, nsi::ArgData::from(nsi::ColorSlice::new($value)))
917 };
918 ($name: path, $value: expr) => {{
919 const __ATTR_CHECK: $crate::Attribute<[$crate::Color3F32]> = $name;
920 nsi::Arg::new(
921 __ATTR_CHECK.name(),
922 nsi::ArgData::from(nsi::ColorSlice::new($value)),
923 )
924 }};
925}
926
927#[macro_export]
932macro_rules! point {
933 ($name: literal, $value: expr) => {
934 nsi::Arg::new($name, nsi::ArgData::from(nsi::Point::new($value)))
935 };
936 ($name: path, $value: expr) => {{
937 const __ATTR_CHECK: $crate::Attribute<$crate::Point3F32> = $name;
938 nsi::Arg::new(
939 __ATTR_CHECK.name(),
940 nsi::ArgData::from(nsi::Point::new($value)),
941 )
942 }};
943}
944
945#[macro_export]
952macro_rules! point_slice {
953 ($name: literal, $value: expr) => {
955 nsi::Arg::new($name, nsi::ArgData::from(nsi::PointSlice::new($value)))
956 };
957 ($name: path, $value: expr) => {{
959 const __ATTR_CHECK: $crate::Attribute<[$crate::Point3F32]> = $name;
960 nsi::Arg::new(
961 __ATTR_CHECK.name(),
962 nsi::ArgData::from(nsi::PointSlice::new($value)),
963 )
964 }};
965}
966
967#[macro_export]
982macro_rules! point4_f32_slice {
983 ($name: literal, $value: expr) => {
985 nsi::Arg::new(
986 $name,
987 nsi::ArgData::from(nsi::Point4F32Slice::new($value)),
988 )
989 };
990 ($name: path, $value: expr) => {{
992 const __ATTR_CHECK: $crate::Attribute<[$crate::Point4F32]> = $name;
993 nsi::Arg::new(
994 __ATTR_CHECK.name(),
995 nsi::ArgData::from(nsi::Point4F32Slice::new($value)),
996 )
997 }};
998}
999
1000#[macro_export]
1005macro_rules! vector {
1006 ($name: literal, $value: expr) => {
1007 nsi::Arg::new($name, nsi::ArgData::from(nsi::Vector::new($value)))
1008 };
1009 ($name: path, $value: expr) => {{
1010 const __ATTR_CHECK: $crate::Attribute<$crate::Vector3F32> = $name;
1011 nsi::Arg::new(
1012 __ATTR_CHECK.name(),
1013 nsi::ArgData::from(nsi::Vector::new($value)),
1014 )
1015 }};
1016}
1017
1018#[macro_export]
1023macro_rules! vector_slice {
1024 ($name: literal, $value: expr) => {
1025 nsi::Arg::new($name, nsi::ArgData::from(nsi::VectorSlice::new($value)))
1026 };
1027 ($name: path, $value: expr) => {{
1028 const __ATTR_CHECK: $crate::Attribute<[$crate::Vector3F32]> = $name;
1029 nsi::Arg::new(
1030 __ATTR_CHECK.name(),
1031 nsi::ArgData::from(nsi::VectorSlice::new($value)),
1032 )
1033 }};
1034}
1035
1036#[macro_export]
1041macro_rules! normal {
1042 ($name: literal, $value: expr) => {
1043 nsi::Arg::new($name, nsi::ArgData::from(nsi::Normal::new($value)))
1044 };
1045 ($name: path, $value: expr) => {{
1046 const __ATTR_CHECK: $crate::Attribute<$crate::Normal3F32> = $name;
1047 nsi::Arg::new(
1048 __ATTR_CHECK.name(),
1049 nsi::ArgData::from(nsi::Normal::new($value)),
1050 )
1051 }};
1052}
1053
1054#[macro_export]
1059macro_rules! normal_slice {
1060 ($name: literal, $value: expr) => {
1061 nsi::Arg::new($name, nsi::ArgData::from(nsi::NormalSlice::new($value)))
1062 };
1063 ($name: path, $value: expr) => {{
1064 const __ATTR_CHECK: $crate::Attribute<[$crate::Normal3F32]> = $name;
1065 nsi::Arg::new(
1066 __ATTR_CHECK.name(),
1067 nsi::ArgData::from(nsi::NormalSlice::new($value)),
1068 )
1069 }};
1070}
1071
1072#[macro_export]
1078macro_rules! matrix_f32 {
1079 ($name: literal, $value: expr) => {
1080 nsi::Arg::new($name, nsi::ArgData::from(nsi::MatrixF32::new($value)))
1081 };
1082 ($name: path, $value: expr) => {{
1083 const __ATTR_CHECK: $crate::Attribute<$crate::Matrix4F32> = $name;
1084 nsi::Arg::new(
1085 __ATTR_CHECK.name(),
1086 nsi::ArgData::from(nsi::MatrixF32::new($value)),
1087 )
1088 }};
1089}
1090
1091#[macro_export]
1097macro_rules! matrix_f32_slice {
1098 ($name: literal, $value: expr) => {
1099 nsi::Arg::new(
1100 $name,
1101 nsi::ArgData::from(nsi::MatrixF32Slice::new($value)),
1102 )
1103 };
1104 ($name: path, $value: expr) => {{
1105 const __ATTR_CHECK: $crate::Attribute<[$crate::Matrix4F32]> = $name;
1106 nsi::Arg::new(
1107 __ATTR_CHECK.name(),
1108 nsi::ArgData::from(nsi::MatrixF32Slice::new($value)),
1109 )
1110 }};
1111}
1112
1113#[macro_export]
1137macro_rules! matrix_f64 {
1138 ($name: literal, $value: expr) => {
1139 nsi::Arg::new($name, nsi::ArgData::from(nsi::MatrixF64::new($value)))
1140 };
1141 ($name: path, $value: expr) => {{
1142 const __ATTR_CHECK: $crate::Attribute<$crate::Matrix4F64> = $name;
1143 nsi::Arg::new(
1144 __ATTR_CHECK.name(),
1145 nsi::ArgData::from(nsi::MatrixF64::new($value)),
1146 )
1147 }};
1148}
1149
1150#[macro_export]
1156macro_rules! matrix_f64_slice {
1157 ($name: literal, $value: expr) => {
1158 nsi::Arg::new(
1159 $name,
1160 nsi::ArgData::from(nsi::MatrixF64Slice::new($value)),
1161 )
1162 };
1163 ($name: path, $value: expr) => {{
1164 const __ATTR_CHECK: $crate::Attribute<[$crate::Matrix4F64]> = $name;
1165 nsi::Arg::new(
1166 __ATTR_CHECK.name(),
1167 nsi::ArgData::from(nsi::MatrixF64Slice::new($value)),
1168 )
1169 }};
1170}
1171
1172#[macro_export]
1184macro_rules! string {
1185 ($name: literal, $value: expr) => {
1186 nsi::Arg::new($name, nsi::ArgData::from(nsi::String::new($value)))
1187 };
1188 ($name: path, $value: expr) => {{
1189 const __ATTR_CHECK: $crate::Attribute<&'static str> = $name;
1190 nsi::Arg::new(
1191 __ATTR_CHECK.name(),
1192 nsi::ArgData::from(nsi::String::new($value)),
1193 )
1194 }};
1195}
1196
1197#[macro_export]
1214macro_rules! string_slice {
1215 ($name: literal, $value: expr) => {
1216 nsi::Arg::new($name, nsi::ArgData::from(nsi::StringSlice::new($value)))
1217 };
1218 ($name: path, $value: expr) => {{
1219 const __ATTR_CHECK: $crate::Attribute<[&'static str]> = $name;
1220 nsi::Arg::new(
1221 __ATTR_CHECK.name(),
1222 nsi::ArgData::from(nsi::StringSlice::new($value)),
1223 )
1224 }};
1225}
1226
1227#[macro_export]
1236macro_rules! reference {
1237 ($name: tt, $value: expr) => {
1238 nsi::Arg::new($name, nsi::ArgData::from(nsi::Reference::new($value)))
1239 };
1240}
1241
1242#[macro_export]
1248macro_rules! reference_stable {
1249 ($name: tt, $value: expr) => {
1250 nsi::Arg::new(
1251 $name,
1252 nsi::ArgData::from(unsafe { nsi::Reference::from_stable($value) }),
1253 )
1254 };
1255}
1256
1257#[macro_export]
1259macro_rules! reference_slice {
1260 ($name: tt, $value: expr) => {
1261 nsi::Arg::new(
1262 $name,
1263 nsi::ArgData::from(nsi::ReferenceSlice::new($value)),
1264 )
1265 };
1266}
1267
1268#[macro_export]
1270macro_rules! callback {
1271 ($name: tt, $value: expr) => {
1272 nsi::Arg::new($name, nsi::ArgData::from(nsi::Callback::new($value)))
1273 };
1274}