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