Generate set-field(all-fields) setters for selected inline structures.
[panamaz] / src / notzed.vulkan / gen / struct-types.api
1 # -*- Mode:text; tab-width:4; electric-indent-mode: nil; indent-line-function:insert-tab; -*-
2
3 # types for structs and unions
4
5 # ###################################################################### #
6
7 #accessor=code template
8 # {type} - java type
9 # {java-get}
10 # {java-set}
11 # {init}*
12 # {init-array}*
13 # {setall-arg}
14 # {setall}
15
16 # ###################################################################### #
17
18 code value {
19   get {{
20         /* {deref} */
21         public {type} get{Name}() {
22                 return {java-get};
23         }
24   }}
25   set {{
26         /* {deref} */
27         public void set{Name}({type} {name}) {
28                 {java-set};
29         }
30   }}
31   getat {{
32         public {type} get{Name}AtIndex(long i$) {
33                 return {java-getat};
34         }
35   }}
36   setat {{
37         public void set{Name}AtIndex(long i$, {type} {name}) {
38                 {java-setat};
39         }
40   }}
41
42   # Initialise the sType field if it has one, also include sub-
43   init eval     {{
44         if ($tempname =~ m/write/) {
45                 my $init = "{name}\$VH.set(self\$.segment, Vulkan.{values});\n";
46                 foreach my $x (@{$s->{items}}) {
47                         if ($x->{deref} eq 'struct') {
48                                 my $y = $api->{types}->{$x->{baseType}};
49                                 if ($#{$y->{items}} >= 0 && $y->{items}->[0]->{values}) {
50                                         my $z = $y->{items}->[0];
51                                         $init .= "self\$.get$x->{Name}().set$z->{Name}(Vulkan.$z->{values});\n";
52                                 }
53                         }
54                 }
55                 return $init;
56         } else {
57                 ''
58         }
59   }}
60
61   init-array eval       {{
62         if ($tempname =~ m/write.*array/n) {
63                 my $init = "{name}\$AH.set(self\$.segment, i, Vulkan.{values});\n";
64                 foreach my $x (@{$s->{items}}) {
65                         if ($x->{deref} eq 'struct') {
66                                 my $y = $api->{types}->{$x->{baseType}};
67                                 if ($#{$y->{items}} >= 0 && $y->{items}->[0]->{values}) {
68                                         my $z = $y->{items}->[0];
69                                         $init .= "self\$.get$x->{Name}AtIndex(i).set$z->{Name}(Vulkan.$z->{values});\n";
70                                 }
71                         }
72                 }
73
74                 "for (long i=0; i<length; i++) {\n\t$init\n\t}\n";
75         } else {
76                 ''
77         }
78   }}
79
80   # for complex constructors
81   #setall-arg   {{ {type} {name} }}
82   setall-arg    {{ {type} {name} }}
83   setall                {{ self$.set{Name}({name}); }}
84   setallat              {{ self$.set{Name}AtIndex(index$, {name}); }}
85 }
86
87 # ###################################################################### #
88
89 code value-array {
90   getorset {{
91         /* value-array {deref} */
92         public {type} get{Name}() {
93                 try {
94                         return {java-get};
95                 } catch (Throwable t) {
96                         throw new RuntimeException(t);
97                 }
98         }
99         public {typei} get{Name}Element(int i$) {
100                 return {java-geti};
101         }
102         public void set{Name}Element(int i$, {typei} {name}) {
103                 {java-seti};
104         }
105   }}
106
107   setall-arg eval {{
108         if ($m->{len1} <= 4) {
109                 join ", ", map { '{typei} {name}$'.$_ } (0 .. $m->{len1}-1);
110         } else {
111                 "{typei}[] {name} /* $m->{deref} $m->{len1} */";
112         }
113   }}
114   setall eval {{
115         if ($m->{len1} <= 4) {
116                 join "\n\t", map { "self\$.set{Name}Element($_, {name}\$$_);" } (0 .. $m->{len1}-1);
117     } else {
118                 <<END;
119                 if ({name} != null) {
120                         try {
121                                 ((MemorySegment){name}\$SH.invokeExact(self\$.segment)).copyFrom(MemorySegment.ofArray({name}));
122                         } catch (Throwable t) {
123                                 System.err.println("Copy error: " + t.getLocalizedMessage());
124                         }
125                 }
126 END
127     }
128   }}
129 }
130
131 # ###################################################################### #
132 # don't like having to pass scope here, not sure what else to do though
133 code handle-array {
134   getorset {{
135         /* value-array {deref} */
136         public {type} get{Name}(VkInstance instance$, ResourceScope scope$) {
137                 try {
138                         return {java-get};
139                 } catch (Throwable t) {
140                         throw new RuntimeException(t);
141                 }
142         }
143         public {typei} get{Name}Element(int i$, VkInstance instance$, ResourceScope scope$) {
144                 return {java-geti};
145         }
146         public void set{Name}Element(int i$, {typei} {name}) {
147                 {java-seti};
148         }
149   }}
150 }
151
152 # ###################################################################### #
153
154 code value-array2d {
155   getorset {{
156         /* value-array2d {deref} */
157         public {type} get{Name}() {
158                 try {
159                         return {java-get};
160                 } catch (Throwable t) {
161                         throw new RuntimeException(t);
162                 }
163         }
164         public {typei} get{Name}Element(int i$, int j$) {
165                 return {java-geti};
166         }
167         public void set{Name}Element(int i$, int j$, {typei} {name}) {
168                 {java-seti};
169         }
170   }}
171 }
172
173 # ###################################################################### #
174
175 code inline {
176   getorset {{
177         /* inline {deref} */
178         public {type} get{Name}() {
179                 try {
180                         return {java-get};
181                 } catch (Throwable t) {
182                         throw new RuntimeException(t);
183                 }
184         }
185   }}
186   getorsetat {{
187         /* inline {deref} */
188         public {type} get{Name}AtIndex(long i$) {
189                 try {
190                         return {java-getat};
191                 } catch (Throwable t) {
192                         throw new RuntimeException(t);
193                 }
194         }
195   }}
196 }
197
198 # ###################################################################### #
199 # inline type that we also want to include expanded in initialiser
200 # We also create expanded setters and a getter for each simple embedded field.
201
202 code inline-expand {
203
204   # These are basic object based accessors
205
206   getorset {{
207         /* inline {deref} */
208         public {type} get{Name}() {
209                 try {
210                         return {java-get};
211                 } catch (Throwable t) {
212                         throw new RuntimeException(t);
213                 }
214         }
215   }}
216
217   getorsetat {{
218         /* inline {deref} */
219         public {type} get{Name}AtIndex(long i$) {
220                 try {
221                         return {java-getat};
222                 } catch (Throwable t) {
223                         throw new RuntimeException(t);
224                 }
225         }
226   }}
227
228   # subroutine to the all-args info, only eval if len1 == 0
229   # this will also include it's own inline struct's fields
230   analyse-args eval {{
231         use integer;
232         my $list = [];
233
234         foreach my $a (@{$api->{data}->{$m->{baseType}}->{items}}) {
235                 my $name = "$m->{name}\$$a->{name}";
236                 my $offset = ($m->{bitOffset} + $a->{bitOffset}) / 8;
237                 my $atype = $primitiveMap{$a->{baseType}};
238
239                 if ($atype) {
240                         push @$list, {
241                                 name=> $name,
242                                 type => $atype,
243                                 offset => $offset,
244                         };
245                 } else {
246                         my $as = $api->{data}->{$a->{baseType}};
247                         foreach my $b (@{$as->{items}}) {
248                                 my $btype = $primitiveMap{$b->{baseType}};
249                                 if ($btype) {
250                                         push @$list, {
251                                                 name => "$name\$$b->{name}",
252                                                 type => $btype,
253                                                 offset =>  $offset + $b->{bitOffset} / 8
254                                         };
255                                 }
256                         }
257                 }
258         }
259         $list;
260   }}
261
262   # setBlah(all-simple-blah-fields)
263   set eval {{
264         return 0 if $m->{len1};
265     my $setall_arg = eval($type->{accessor}->{'setall-arg'});
266         my $setall = eval($type->{accessor}->{setall});
267         <<END;
268         public void set{Name}($setall_arg) {
269                 var self\$ = this;
270                 $setall
271         }
272 END
273   }}
274
275   # getBlah$field0(), getBlah$field1() etc.
276   get eval {{
277         die if ($m->{len1});
278
279         return 0 if $m->{len1};
280
281         my $list = eval($type->{accessor}->{'analyse-args'});   die "$@" if !defined $list;
282
283         join("\n", map {
284                 my $tname = uc($_->{type});
285                 my $fname = ucfirst($_->{name});
286                 <<END;
287         public $_->{type} get$fname() {
288                 return this.segment.get(Memory.$tname, $_->{offset});
289         }
290 END
291         } @$list);
292   }}
293
294   # setBlahAtIndex(index, all-simple-blah-fields)
295   setat eval {{
296         return 0 if $m->{len1};
297     my $setall_arg = eval($type->{accessor}->{'setall-arg'});
298         my $setallat = eval($type->{accessor}->{setallat});
299         <<END;
300         public void set{Name}AtIndex(long index\$, $setall_arg) {
301                 var self\$ = this;
302                 $setallat
303         }
304 END
305   }}
306
307   # create arg-list for setall template
308   setall-arg eval {{
309         return 0 if $m->{len1};
310
311         my $list = eval($type->{accessor}->{'analyse-args'});   die "$@" if !defined $list;
312
313         join(', ', map { "$_->{type} $_->{name}" } @$list);
314   }}
315
316   setall eval   {{
317         return 0 if $m->{len1};
318
319         my $list = eval($type->{accessor}->{'analyse-args'});   die "$@" if !defined $list;
320
321         join("\n\t", map { 'self$.segment.set(Memory.'.uc($_->{type}).", $_->{offset}, $_->{name});" } @$list);
322   }}
323
324   setallat eval {{
325         use integer;
326
327         return 0 if $m->{len1};
328
329         my $list = eval($type->{accessor}->{'analyse-args'});   die "$@" if !defined $list;
330         my $stride = $s->{bitSize} / 8;
331
332         join("\n\t", map { 'self$.segment.set(Memory.'.uc($_->{type}).", index\$ * $stride + $_->{offset}, $_->{name});" } @$list);
333   }}
334 }
335
336 # ###################################################################### #
337
338 # value with a SegmentAllocator passed to set()
339 code value-alloc value {
340   set {{
341         /* {deref} */
342         public void set{Name}({type} {name}, SegmentAllocator alloc$) {
343                 {java-set};
344         }
345   }}
346   setat {{
347         /* {deref} */
348         public void set{Name}AtIndex(long i$, {type} {name}, SegmentAllocator alloc$) {
349                 {java-setat};
350         }
351   }}
352
353   setall                {{ self$.set{Name}({name}, alloc$); }}
354 }
355
356 # ###################################################################### #
357
358 code Vulkan {
359   class {{
360         package {package};
361         public class Vulkan {
362
363                 public static int VK_MAKE_API_VERSION(int variant, int major, int minor, int patch) {
364                         return (variant << 29) | (major << 22) | (minor << 12) | patch;
365                 }
366
367                 {defines}
368
369                 {constants}
370         }
371   }}
372   VK_API_VERSION_1_0 {{ public final static int VK_API_VERSION_1_0 = VK_MAKE_API_VERSION(0, 1, 0, 0); }}
373   VK_API_VERSION_1_1 {{ public final static int VK_API_VERSION_1_1 = VK_MAKE_API_VERSION(0, 1, 1, 0); }}
374   VK_API_VERSION_1_2 {{ public final static int VK_API_VERSION_1_2 = VK_MAKE_API_VERSION(0, 1, 2, 0); }}
375   VK_API_VERSION_1_3 {{ public final static int VK_API_VERSION_1_3 = VK_MAKE_API_VERSION(0, 1, 3, 0); }}
376 }
377
378 code dispatch {
379   class {{
380         // template: dispatch:class
381         package {package};
382         import jdk.incubator.foreign.*;
383         import java.lang.invoke.*;
384         import au.notzed.nativez.*;
385         class {Name} {
386
387                 {field-init}
388
389                 {Name}(VkInstance instance$, ResourceScope scope$) {
390                         {init}
391                 }
392         }
393   }}
394   field-init {{ final NativeSymbol {name}$NS; }}
395   init {{ {name}$NS = instance$.vkGetInstanceProcAddr("{name}", scope$); }}
396
397 }
398
399 # non-dispatchable handle
400 code handle {
401   class {{
402         // template: handle:class
403         package {package};
404         import jdk.incubator.foreign.*;
405         import java.lang.invoke.*;
406         import au.notzed.nativez.*;
407
408         public class {name} implements Pointer {
409                 final NativeSymbol self;
410
411                 private {name}(MemoryAddress address, ResourceScope scope) {
412                         this.self = NativeSymbol.ofAddress("{name}", address, scope);
413                         {init}
414                 }
415
416                 public static {name} create(MemoryAddress address, ResourceScope scope) {
417                         return new {name}(address, scope);
418                 }
419
420                 public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc) {
421                         return HandleArray.createArray(length, alloc, {name}::create);
422                 }
423
424                 public MemoryAddress address() {
425                         return self.address();
426                 }
427
428                 public ResourceScope scope() {
429                         return self.scope();
430                 }
431         }
432   }}
433 }
434
435 # VkInstance
436 code handle-instance {
437   class {{
438         // template: handle-instance:class
439         package {package};
440         import jdk.incubator.foreign.*;
441         import java.lang.invoke.*;
442         import au.notzed.nativez.*;
443
444         public class {name} implements Pointer {
445                 final NativeSymbol self;
446                 final DispatchInstance dispatch;
447
448                 private {name}(MemoryAddress address, ResourceScope scope) {
449                         this.self = NativeSymbol.ofAddress("{name}", address, scope);
450                         this.dispatch = new DispatchInstance(this, scope);
451                         {init}
452                 }
453
454                 public static {name} create(MemoryAddress address, ResourceScope scope) {
455                         return new {name}(address, scope);
456                 }
457
458                 public MemoryAddress address() {
459                         return self.address();
460                 }
461
462                 public ResourceScope scope() {
463                         return self.scope();
464                 }
465
466                 {commands}
467         }
468   }}
469 }
470
471 # dispatchable handle
472 code handle-dispatch {
473   class {{
474         // template: handle-dispatch:class
475         package {package};
476         import jdk.incubator.foreign.*;
477         import java.lang.invoke.*;
478         import au.notzed.nativez.*;
479
480         public class {name} implements Pointer {
481                 final NativeSymbol self;
482                 final DispatchInstance dispatch;
483
484                 private {name}(MemoryAddress address, DispatchInstance dispatch, ResourceScope scope) {
485                         this.self = NativeSymbol.ofAddress("{name}", address, scope);
486                         this.dispatch = dispatch;
487                         {init}
488                 }
489
490                 public static {name} create(MemoryAddress address, DispatchInstance dispatch, ResourceScope scope) {
491                         return new {name}(address, dispatch, scope);
492                 }
493
494                 // TODO: evaluate how scope fits here
495                 public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, DispatchInstance dispatch, ResourceScope scope) {
496                         return HandleArray.createArray(length, alloc, (a, s) -> create(a, dispatch, s), scope);
497                 }
498
499                 public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, VkInstance instance, ResourceScope scope) {
500                         return HandleArray.createArray(length, alloc, (a, s) -> create(a, instance.dispatch, s), scope);
501                 }
502
503                 public MemoryAddress address() {
504                         return self.address();
505                 }
506
507                 public ResourceScope scope() {
508                         return self.scope();
509                 }
510
511                 {commands}
512         }
513   }}
514 }
515
516 # ###################################################################### #
517
518 # shared struct components
519 code struct {
520   header {{
521                 public MemorySegment segment;
522
523                 public static final GroupLayout LAYOUT = {layout};
524
525                 private {Name}(MemorySegment segment) {
526                         this.segment = segment;
527                 }
528
529                 public static {Name} create(MemorySegment segment) {
530                         return new {Name}(segment);
531                 }
532
533                 public static {Name} create(MemoryAddress address, ResourceScope scope) {
534                         return create(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope));
535                 }
536
537                 public static {Name} create(SegmentAllocator alloc) {
538                         var self$ = create(alloc.allocate(LAYOUT));
539                         {init}
540                         return self$;
541                 }
542
543                 // Pointer
544                 @Override
545                 public MemoryAddress address() {
546                         return segment.address();
547                 }
548
549                 // Pointer
550                 @Override
551                 public ResourceScope scope() {
552                         return segment.scope();
553                 }
554
555                 @Override
556                 public String toString() {
557                         return Memory.toString(segment, LAYOUT);
558                 }
559   }}
560   create-all {{
561                 public static {Name} {create}({java-setall-arguments}, SegmentAllocator alloc$) {
562                         {Name} self$ = create(alloc$);
563
564                         {java-setall}
565
566                         return self$;
567                 }
568   }}
569   set-all {{
570                 public void {set}({java-setall-arguments}) {
571                         {Name} self$ = this;
572
573                         {java-setall}
574                 }
575   }}
576   setat-all {{
577                 public void {set}AtIndex(long index$, {java-setall-arguments}) {
578                         {Name} self$ = this;
579
580                         {java-setallat}
581                 }
582   }}
583   array {{
584                 static {Name} createArray(MemoryAddress addr, long length, ResourceScope scope) {
585                         return create(MemorySegment.ofAddress(addr, length * LAYOUT.byteSize(), scope));
586                 }
587
588                 public static {Name} createArray(long length, SegmentAllocator alloc) {
589                         var self$ = create(alloc.allocateArray(LAYOUT, length));
590                         {init-array}
591                         return self$;
592                 }
593
594                 public final static MethodHandle LAYOUT$SH = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement());
595
596                 // Array
597                 @Override
598                 public long length() {
599                         return segment.byteSize() / LAYOUT.byteSize();
600                 }
601
602                 // Array
603                 #Override
604                 public {Name} getAtIndex(long index$) {
605                         try {
606                                 return create((MemorySegment)LAYOUT$SH.invokeExact(this.segment, index$));
607                         } catch (Throwable t) {
608                                 throw new RuntimeException(t);
609                         }
610                 }
611   }}
612 }
613
614 # default - writeonly struct
615 code struct-writeonly insert=struct:header,struct:create-all
616         fields=init,set,getorset,handle,java-setall {
617   class {{
618         // template: struct-writeonly:class
619         package {package};
620         import jdk.incubator.foreign.*;
621         import java.lang.invoke.*;
622         import au.notzed.nativez.*;
623
624         public class {Name} implements Pointer {
625                 {header}
626
627                 {create-all}
628
629                 {set}
630                 {getorset}
631
632                 {handle}
633         }
634   }}
635 }
636
637 code struct-writeonly-array insert=struct:header,struct:create-all,struct:array
638         fields=init,init-array,set,getorset,setat,getorsetat,handle,handleat,java-setall {
639   class {{
640         // template: struct-writeonly-array:class
641         package {package};
642         import jdk.incubator.foreign.*;
643         import java.lang.invoke.*;
644         import au.notzed.nativez.*;
645
646         public class {Name} implements Pointer, Array<{Name}> {
647                 {header}
648                 {array}
649
650                 {create-all}
651
652                 {set}
653                 {getorset}
654
655                 {setat}
656                 {getorsetat}
657
658                 {handle}
659                 {handleat}
660         }
661   }}
662 }
663
664 code struct-readonly insert=struct:header
665         fields=init,get,getorset,handle {
666   class {{
667         // template: struct-readonly:class
668         package {package};
669         import jdk.incubator.foreign.*;
670         import java.lang.invoke.*;
671         import au.notzed.nativez.*;
672
673         public class {Name} implements Pointer {
674                 {header}
675
676                 {get}
677                 {getorset}
678
679                 {handle}
680         }
681   }}
682 }
683
684 code struct-readonly-array insert=struct:header,struct:array
685         fields=init,init-array,get,getorset,getat,getorsetat,handle,handleat {
686   class {{
687         // template: struct-readonly-array:class
688         package {package};
689         import jdk.incubator.foreign.*;
690         import java.lang.invoke.*;
691         import au.notzed.nativez.*;
692
693         public class {Name} implements Pointer, Array<{Name}> {
694                 {header}
695                 {array}
696
697                 {get}
698                 {getorset}
699
700                 {getat}
701                 {getorsetat}
702
703                 {handle}
704                 {handleat}
705         }
706   }}
707 }
708
709 code struct-readwrite insert=struct:header,struct:create-all
710         fields=init,get,set,getorset,handle,java-setall {
711   class {{
712         // template: struct-readwrite:class
713         package {package};
714         import jdk.incubator.foreign.*;
715         import java.lang.invoke.*;
716         import au.notzed.nativez.*;
717
718         public class {Name} implements Pointer {
719                 {header}
720
721                 {create-all}
722
723                 {get}
724                 {set}
725                 {getorset}
726
727                 {handle}
728         }
729   }}
730 }
731
732 code struct-readwrite-array insert=struct:header,struct:create-all,struct:array
733         fields=init,init-array,get,getat,set,setat,getorset,getorsetat,handle,handleat,java-setall {
734   class {{
735         // template: struct-readwrite-array:class
736         package {package};
737         import jdk.incubator.foreign.*;
738         import java.lang.invoke.*;
739         import au.notzed.nativez.*;
740
741         public class {Name} implements Pointer,Array<{Name}> {
742                 {header}
743                 {array}
744
745                 {create-all}
746
747                 {get}
748                 {set}
749                 {getorset}
750
751                 {getat}
752                 {setat}
753                 {getorsetat}
754
755                 {handle}
756                 {handleat}
757         }
758   }}
759 }
760
761 # read-write with a 'set' method for all members
762 code struct-readwrite-all insert=struct:header,struct:create-all,struct:set-all
763         fields=init,get,set,getorset,handle,java-setall {
764   class {{
765         // template: struct-readwrite-all:class
766         package {package};
767         import jdk.incubator.foreign.*;
768         import java.lang.invoke.*;
769         import au.notzed.nativez.*;
770
771         public class {Name} implements Pointer {
772                 {header}
773
774                 {create-all}
775
776                 {get}
777                 {set}
778                 {getorset}
779
780                 {handle}
781         }
782   }}
783 }
784
785 code struct-readwrite-array-all insert=struct:header,struct:create-all,struct:array,struct:set-all,struct:setat-all
786         fields=init,init-array,get,getat,set,setat,setallat,getorset,getorsetat,handle,handleat,java-setall,java-setallat {
787   class {{
788         // template: struct-readwrite-array-all:class
789         package {package};
790         import jdk.incubator.foreign.*;
791         import java.lang.invoke.*;
792         import au.notzed.nativez.*;
793
794         public class {Name} implements Pointer,Array<{Name}> {
795                 {header}
796                 {array}
797
798                 {create-all}
799
800                 {get}
801                 {set}
802                 {getorset}
803
804                 {getat}
805                 {setat}
806                 {getorsetat}
807
808                 {handle}
809                 {handleat}
810         }
811   }}
812 }
813
814 # ###################################################################### #
815
816 # Basic value-based accessor
817 type value accessor=value {
818         native-value    {{ {name} }}
819
820         native-get              {{ ({type}){name}$VH.get(this.segment) }}
821         handle                  {{ final static VarHandle {name}$VH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
822
823         java-get                {{ {native-get} }}
824         java-set                {{ {name}$VH.set(this.segment, {native-value}) }}
825
826         native-getat    {{ ({type}){name}$AH.get(this.segment, i$) }}
827         native-setat    {{ {name}$AH.set(this.segment, i$, {native-value}) }}
828         handleat                {{ final static VarHandle {name}$AH = MemoryLayout.sequenceLayout(LAYOUT).varHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
829
830         java-getat              {{ {native-getat} }}
831         java-setat              {{ {native-setat} }}
832 }
833
834 type value-array accessor=value-array {
835         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
836         java-get        {{ {type}.create({native-get}) }}
837
838         native-geti     {{ {name}$EH.get(this.segment, i$) }}
839
840         java-geti       {{ ({typei}){native-geti} }}
841         java-seti       {{ {name}$EH.set(this.segment, i$, {name}) }}
842         handle          {{
843                 final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
844                 final static VarHandle {name}$EH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("{name}"), MemoryLayout.PathElement.sequenceElement());
845         }}
846 }
847
848 type value-array2d accessor=value-array2d {
849         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
850         java-get        {{ {type}.create({native-get}) }}
851         java-geti       {{ ({typei}){name}$EH.get(this.segment, i$, j$) }}
852         java-seti       {{ {name}$EH.set(this.segment, i$, j$, {name}) }}
853         handle          {{
854                 final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
855                 final static VarHandle {name}$EH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("{name}"), MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.sequenceElement());
856         }}
857 }
858
859 type inline accessor=inline {
860         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
861         java-get        {{ {type}.create({native-get}) }}
862         handle          {{ final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
863
864         native-getat {{ (MemorySegment){name}$SA.invokeExact(this.segment, i$) }}
865         java-getat      {{ {type}.create({native-getat}) }}
866         handleat        {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
867 }
868
869 type inline-array accessor=inline {
870         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
871         java-get        {{ {type}.create({native-get}) }}
872         handle          {{ final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
873
874         native-getat {{ (MemorySegment){name}$SA.invokeExact(this.segment, i$) }}
875         java-getat      {{ {type}.create({native-getat}) }}
876         handleat        {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
877 }
878
879 type uint8_t,char value {
880         type    {{ byte }}
881         layout  {{ Memory.BYTE }}
882 }
883
884 type uint16_t value {
885         type    {{ short }}
886         layout  {{ Memory.SHORT }}
887 }
888
889 type uint32_t,int,int32_t value {
890         type    {{ int }}
891         layout  {{ Memory.INT }}
892 }
893
894 type uint64_t,int64_t,size_t value {
895         type    {{ long }}
896         layout  {{ Memory.LONG }}
897 }
898
899 type float value {
900         type    {{ float }}
901         layout  {{ Memory.FLOAT }}
902 }
903
904 type double value {
905         type    {{ double }}
906         layout  {{ Memory.DOUBLE }}
907 }
908
909 # ###################################################################### #
910
911 type uint8_t[],char[] value-array {
912         type    {{ ByteArray }}
913         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.BYTE) }}
914         typei   {{ byte }}
915 }
916
917 type uint32_t[],int32_t[] value-array {
918         type    {{ IntArray }}
919         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.INT) }}
920         typei   {{ int }}
921 }
922
923 type uint64_t[] value-array {
924         type    {{ LongArray }}
925         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.LONG) }}
926         typei   {{ long }}
927 }
928
929 type float[] value-array {
930         type    {{ FloatArray }}
931         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.FLOAT) }}
932         typei   {{ float }}
933 }
934
935 type struct[] inline-array {
936         type    {{ {baseType} }}
937         layout  {{ MemoryLayout.sequenceLayout({len1}, {baseType}.LAYOUT) }}
938 }
939
940 type struct-expand[] struct[] accessor=inline-expand;
941
942 type float[][] value-array2d {
943         type    {{ FloatArray }}
944         typei   {{ float }}
945         layout  {{ MemoryLayout.sequenceLayout({len1}, MemoryLayout.sequenceLayout({len2}, Memory.FLOAT)) }}
946 }
947
948 # select=len?  or what?
949
950 type pointer value {
951         layout  {{ Memory.POINTER }}
952         type    {{ MemoryAddress }}
953
954         native-value    {{ Memory.address({name}) }}
955         native-get              {{ (MemoryAddress){name}$VH.get(this.segment) }}
956
957 #       java-get        {{ {native-get} }}
958 #       java-set        {{ {name}$VH.set(this.segment, Memory.address({name})) }}
959 }
960
961 type void* pointer;
962
963 type value-pointer pointer {
964         java-get        {{ {type}.create((MemoryAddress){name}$VH.get(this.segment), segment.scope()) }}
965 }
966
967 type uint8_t* value-pointer {
968         type    ByteArray;
969 }
970
971 type uint32_t*,int32_t*,int* value-pointer {
972         type    IntArray;
973 }
974
975 type uint64_t* value-pointer {
976         type    LongArray;
977 }
978
979 type float* value-pointer {
980         type    FloatArray;
981 }
982
983 type size_t* value-pointer {
984         type    LongArray;
985 }
986
987 type pointer-length pointer {
988         java-get        {{ {type}.createArray({native-get}, {length}, this.segment.scope()) }}
989 }
990
991 type void*-length pointer-length {
992         type            MemorySegment;
993         java-get        {{ MemorySegment.ofAddress({native-get}, {length}, this.segment.scope()) }}
994 }
995
996 type uint8_t*-length pointer-length {
997         type    ByteArray;
998 }
999
1000 type uint32_t*-length,int32_t*-length pointer-length {
1001         type    IntArray;
1002 }
1003
1004 type uint64_t*-length pointer-length {
1005         type    LongArray;
1006 }
1007
1008 type float*-length pointer-length {
1009         type    FloatArray;
1010 }
1011
1012 # special handling for strings, will fail if it isn't
1013 type char* pointer accessor=value-alloc {
1014         type            {{ String }}
1015
1016         java-get        {{ ({native-get}).getUtf8String(0) }}
1017         native-value {{ alloc$.allocateUtf8String({name}).address() }}
1018
1019         # this just verifies it's a string type
1020         length eval     {{
1021                 if ($v->{len} =~ m/null-terminated/) {
1022                         1;
1023                 } else {
1024                         die Dumper($v, $s);
1025                 }
1026         }}
1027
1028 }
1029
1030 type char**-length pointer-length accessor=value-alloc {
1031         type    {{ String[] }}
1032
1033         java-set        {{ {name}$VH.set(this.segment, Memory.copyStringArray({name}, alloc$).address()); }}
1034         java-get        {{ Memory.copyStringArray((MemoryAddress){name}$VH.get(this.segment), {length}) }}
1035 }
1036
1037 type funcpointer pointer {
1038         type            {{ FunctionPointer<{baseType}> }}
1039         typei           {{ {baseType} }}
1040         java-get        {{ {baseType}.downcall({native-get}, this.segment.scope()) }}
1041 }
1042
1043 type void** pointer {
1044 }
1045
1046 type void**-length pointer-length {
1047         type    PointerArray;
1048 }
1049
1050 type handle pointer {
1051         type            {{ {baseType} }}
1052         java-get        {{ {type}.create({native-get}, this.segment.scope()) }}
1053 }
1054
1055 type handle[] value-array accessor=handle-array {
1056         type            {{ HandleArray<{typei}> }}
1057         typei           {{ {baseType} }}
1058         layout          {{ MemoryLayout.sequenceLayout({len1}, Memory.POINTER) }}
1059         java-get        {{ HandleArray.create({native-get}, (a, s) -> {typei}.create(a, instance$.dispatch, s), scope$) }}
1060
1061         java-geti       {{ {typei}.create((MemoryAddress){native-geti}, instance$.dispatch, scope$) }}
1062 }
1063
1064 type handle* pointer {
1065         type            {{ HandleArray<{typei}> }}
1066         typei           {{ {baseType} }}
1067         java-get        {{ HandleArray.create({native-get}, {typei}::create) }}
1068 }
1069
1070 type handle*-length pointer-length {
1071         type            {{ HandleArray<{baseType}> }}
1072         typei           {{ {baseType} }}
1073         java-get        {{ HandleArray.createArray({native-get}, {length}, {typei}::create, this.segment.scope()) }}
1074         java-set        {{ {name}$VH.set(this.segment, Memory.address({name})); }}
1075 }
1076
1077 type struct inline {
1078         type    {{ {baseType} }}
1079         layout  {{ {baseType}.LAYOUT }}
1080 }
1081
1082 type struct-expand inline accessor=inline-expand {
1083         type    {{ {baseType} }}
1084         layout  {{ {baseType}.LAYOUT }}
1085 }
1086
1087 type struct* pointer {
1088         type            {{ {baseType} }}
1089         java-get        {{ {baseType}.create({native-get}, this.segment.scope()) }}
1090 }
1091
1092 type struct*-length pointer-length {
1093         type    {{ {baseType} }}
1094         typei   {{ {baseType} }}
1095 }
1096
1097 type struct** pointer {
1098 }
1099
1100 # xlib
1101 type XID,Window,VisualID uint64_t;
1102
1103 type Display* handle {
1104         type    xlib.XDisplay;
1105 }
1106
1107 # xcb
1108 type xcb_window_t uint32_t;
1109 type xcb_visualid_t uint32_t;
1110 type xcb_connection_t* handle {
1111         type    xcb.Connection;
1112 }
1113
1114 override structs {
1115         VkInstance                      template=handle-instance;
1116         VkPhysicalDevice        template=handle-dispatch;
1117         VkDevice                        template=handle-dispatch;
1118         VkCommandBuffer         template=handle-dispatch;
1119         VkQueue                         template=handle-dispatch;
1120
1121         VkAllocationCallbacks   ignore;
1122
1123         # We want 'set(all fields) for these types and to include them expanded if inline
1124         VkOffset2D expand template=struct-readwrite-array-all;
1125         VkOffset3D expand template=struct-readwrite-array-all;
1126         VkExtent2D expand template=struct-readwrite-all;
1127         VkExtent3D expand template=struct-readwrite-all;
1128         VkRect2D expand template=struct-readwrite-array-all;
1129
1130         VkStencilOpState template=struct-readwrite-all;
1131         VkComponentMapping template=struct-readwrite-all;
1132         VkImageSubresourceRange template=struct-readwrite-all;
1133
1134         VkClearColorValue expand template=struct-readwrite-all;
1135         VkClearDepthStencilValue expand template=struct-readwrite-all;
1136
1137         # Override default read/write
1138         VkDebugUtilsMessengerCallbackDataEXT template=struct-readonly;
1139         VkDebugUtilsLabelEXT template=struct-readonly-array;
1140         VkDebugUtilsObjectNameInfoEXT template=struct-readonly-array;
1141
1142 # can't really work out what this is it's a void ** but it stays it's a pointer to uint8_t * in the spec
1143         VkCuLaunchInfoNVX       pParams=type:pointer pExtras=type:pointer;
1144 }