913e8f9ea64aba57cf886a664fb4987f41050f21
[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 # ###################################################################### #
286
287 code Vulkan {
288   class {{
289         package {package};
290         public class Vulkan {
291
292                 public static int VK_MAKE_API_VERSION(int variant, int major, int minor, int patch) {
293                         return (variant << 29) | (major << 22) | (minor << 12) | patch;
294                 }
295
296                 {defines}
297
298                 {constants}
299         }
300   }}
301   VK_API_VERSION_1_0 {{ public final static int VK_API_VERSION_1_0 = VK_MAKE_API_VERSION(0, 1, 0, 0); }}
302   VK_API_VERSION_1_1 {{ public final static int VK_API_VERSION_1_1 = VK_MAKE_API_VERSION(0, 1, 1, 0); }}
303   VK_API_VERSION_1_2 {{ public final static int VK_API_VERSION_1_2 = VK_MAKE_API_VERSION(0, 1, 2, 0); }}
304   VK_API_VERSION_1_3 {{ public final static int VK_API_VERSION_1_3 = VK_MAKE_API_VERSION(0, 1, 3, 0); }}
305 }
306
307 code dispatch {
308   class {{
309         // template: dispatch:class
310         package {package};
311         import jdk.incubator.foreign.*;
312         import java.lang.invoke.*;
313         import au.notzed.nativez.*;
314         class {Name} {
315
316                 {field-init}
317
318                 {Name}(VkInstance instance$, ResourceScope scope$) {
319                         {init}
320                 }
321         }
322   }}
323   field-init {{ final NativeSymbol {name}$NS; }}
324   init {{ {name}$NS = instance$.vkGetInstanceProcAddr("{name}", scope$); }}
325
326 }
327
328 # non-dispatchable handle
329 code handle {
330   class {{
331         // template: handle:class
332         package {package};
333         import jdk.incubator.foreign.*;
334         import java.lang.invoke.*;
335         import au.notzed.nativez.*;
336
337         public class {name} implements Pointer {
338                 final NativeSymbol self;
339
340                 private {name}(MemoryAddress address, ResourceScope scope) {
341                         this.self = NativeSymbol.ofAddress("{name}", address, scope);
342                         {init}
343                 }
344
345                 public static {name} create(MemoryAddress address, ResourceScope scope) {
346                         return new {name}(address, scope);
347                 }
348
349                 public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc) {
350                         return HandleArray.createArray(length, alloc, {name}::create);
351                 }
352
353                 public MemoryAddress address() {
354                         return self.address();
355                 }
356
357                 public ResourceScope scope() {
358                         return self.scope();
359                 }
360         }
361   }}
362 }
363
364 # VkInstance
365 code handle-instance {
366   class {{
367         // template: handle-instance:class
368         package {package};
369         import jdk.incubator.foreign.*;
370         import java.lang.invoke.*;
371         import au.notzed.nativez.*;
372
373         public class {name} implements Pointer {
374                 final NativeSymbol self;
375                 final DispatchInstance dispatch;
376
377                 private {name}(MemoryAddress address, ResourceScope scope) {
378                         this.self = NativeSymbol.ofAddress("{name}", address, scope);
379                         this.dispatch = new DispatchInstance(this, scope);
380                         {init}
381                 }
382
383                 public static {name} create(MemoryAddress address, ResourceScope scope) {
384                         return new {name}(address, scope);
385                 }
386
387                 public MemoryAddress address() {
388                         return self.address();
389                 }
390
391                 public ResourceScope scope() {
392                         return self.scope();
393                 }
394
395                 {commands}
396         }
397   }}
398 }
399
400 # dispatchable handle
401 code handle-dispatch {
402   class {{
403         // template: handle-dispatch:class
404         package {package};
405         import jdk.incubator.foreign.*;
406         import java.lang.invoke.*;
407         import au.notzed.nativez.*;
408
409         public class {name} implements Pointer {
410                 final NativeSymbol self;
411                 final DispatchInstance dispatch;
412
413                 private {name}(MemoryAddress address, DispatchInstance dispatch, ResourceScope scope) {
414                         this.self = NativeSymbol.ofAddress("{name}", address, scope);
415                         this.dispatch = dispatch;
416                         {init}
417                 }
418
419                 public static {name} create(MemoryAddress address, DispatchInstance dispatch, ResourceScope scope) {
420                         return new {name}(address, dispatch, scope);
421                 }
422
423                 // TODO: evaluate how scope fits here
424                 public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, DispatchInstance dispatch, ResourceScope scope) {
425                         return HandleArray.createArray(length, alloc, (a, s) -> create(a, dispatch, s), scope);
426                 }
427
428                 public static HandleArray<{name}> createArray(long length, SegmentAllocator alloc, VkInstance instance, ResourceScope scope) {
429                         return HandleArray.createArray(length, alloc, (a, s) -> create(a, instance.dispatch, s), scope);
430                 }
431
432                 public MemoryAddress address() {
433                         return self.address();
434                 }
435
436                 public ResourceScope scope() {
437                         return self.scope();
438                 }
439
440                 {commands}
441         }
442   }}
443 }
444
445 # ###################################################################### #
446
447 # shared struct components
448 code struct {
449   header {{
450                 public MemorySegment segment;
451
452                 public static final GroupLayout LAYOUT = {layout};
453
454                 private {Name}(MemorySegment segment) {
455                         this.segment = segment;
456                 }
457
458                 public static {Name} create(MemorySegment segment) {
459                         return new {Name}(segment);
460                 }
461
462                 public static {Name} create(MemoryAddress address, ResourceScope scope) {
463                         return create(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope));
464                 }
465
466                 public static {Name} create(SegmentAllocator alloc) {
467                         var self$ = create(alloc.allocate(LAYOUT));
468                         {init}
469                         return self$;
470                 }
471
472                 // Pointer
473                 @Override
474                 public MemoryAddress address() {
475                         return segment.address();
476                 }
477
478                 // Pointer
479                 @Override
480                 public ResourceScope scope() {
481                         return segment.scope();
482                 }
483
484                 @Override
485                 public String toString() {
486                         return Memory.toString(segment, LAYOUT);
487                 }
488   }}
489   create-all {{
490                 public static {Name} {create}({java-setall-arguments}, SegmentAllocator alloc$) {
491                         {Name} self$ = create(alloc$);
492
493                         {java-setall}
494
495                         return self$;
496                 }
497   }}
498   set-all {{
499                 public void {set}({java-setall-arguments}) {
500                         {Name} self$ = this;
501
502                         {java-setall}
503                 }
504   }}
505   setat-all {{
506                 public void {set}AtIndex(long index$, {java-setall-arguments}) {
507                         {Name} self$ = this;
508
509                         {java-setallat}
510                 }
511   }}
512   array {{
513                 static {Name} createArray(MemoryAddress addr, long length, ResourceScope scope) {
514                         return create(MemorySegment.ofAddress(addr, length * LAYOUT.byteSize(), scope));
515                 }
516
517                 public static {Name} createArray(long length, SegmentAllocator alloc) {
518                         var self$ = create(alloc.allocateArray(LAYOUT, length));
519                         {init-array}
520                         return self$;
521                 }
522
523                 public final static MethodHandle LAYOUT$SH = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement());
524
525                 // Array
526                 @Override
527                 public long length() {
528                         return segment.byteSize() / LAYOUT.byteSize();
529                 }
530
531                 // Array
532                 #Override
533                 public {Name} getAtIndex(long index$) {
534                         try {
535                                 return create((MemorySegment)LAYOUT$SH.invokeExact(this.segment, index$));
536                         } catch (Throwable t) {
537                                 throw new RuntimeException(t);
538                         }
539                 }
540   }}
541 }
542
543 # default - writeonly struct
544 code struct-writeonly insert=struct:header,struct:create-all
545         fields=init,set,getorset,handle,java-setall {
546   class {{
547         // template: struct-writeonly:class
548         package {package};
549         import jdk.incubator.foreign.*;
550         import java.lang.invoke.*;
551         import au.notzed.nativez.*;
552
553         public class {Name} implements Pointer {
554                 {header}
555
556                 {create-all}
557
558                 {set}
559                 {getorset}
560
561                 {handle}
562         }
563   }}
564 }
565
566 code struct-writeonly-array insert=struct:header,struct:create-all,struct:array
567         fields=init,init-array,set,getorset,setat,getorsetat,handle,handleat,java-setall {
568   class {{
569         // template: struct-writeonly-array:class
570         package {package};
571         import jdk.incubator.foreign.*;
572         import java.lang.invoke.*;
573         import au.notzed.nativez.*;
574
575         public class {Name} implements Pointer, Array<{Name}> {
576                 {header}
577                 {array}
578
579                 {create-all}
580
581                 {set}
582                 {getorset}
583
584                 {setat}
585                 {getorsetat}
586
587                 {handle}
588                 {handleat}
589         }
590   }}
591 }
592
593 code struct-readonly insert=struct:header
594         fields=init,get,getorset,handle {
595   class {{
596         // template: struct-readonly:class
597         package {package};
598         import jdk.incubator.foreign.*;
599         import java.lang.invoke.*;
600         import au.notzed.nativez.*;
601
602         public class {Name} implements Pointer {
603                 {header}
604
605                 {get}
606                 {getorset}
607
608                 {handle}
609         }
610   }}
611 }
612
613 code struct-readonly-array insert=struct:header,struct:array
614         fields=init,init-array,get,getorset,getat,getorsetat,handle,handleat {
615   class {{
616         // template: struct-readonly-array:class
617         package {package};
618         import jdk.incubator.foreign.*;
619         import java.lang.invoke.*;
620         import au.notzed.nativez.*;
621
622         public class {Name} implements Pointer, Array<{Name}> {
623                 {header}
624                 {array}
625
626                 {get}
627                 {getorset}
628
629                 {getat}
630                 {getorsetat}
631
632                 {handle}
633                 {handleat}
634         }
635   }}
636 }
637
638 code struct-readwrite insert=struct:header,struct:create-all
639         fields=init,get,set,getorset,handle,java-setall {
640   class {{
641         // template: struct-readwrite:class
642         package {package};
643         import jdk.incubator.foreign.*;
644         import java.lang.invoke.*;
645         import au.notzed.nativez.*;
646
647         public class {Name} implements Pointer {
648                 {header}
649
650                 {create-all}
651
652                 {get}
653                 {set}
654                 {getorset}
655
656                 {handle}
657         }
658   }}
659 }
660
661 code struct-readwrite-array insert=struct:header,struct:create-all,struct:array
662         fields=init,init-array,get,getat,set,setat,getorset,getorsetat,handle,handleat,java-setall {
663   class {{
664         // template: struct-readwrite-array:class
665         package {package};
666         import jdk.incubator.foreign.*;
667         import java.lang.invoke.*;
668         import au.notzed.nativez.*;
669
670         public class {Name} implements Pointer,Array<{Name}> {
671                 {header}
672                 {array}
673
674                 {create-all}
675
676                 {get}
677                 {set}
678                 {getorset}
679
680                 {getat}
681                 {setat}
682                 {getorsetat}
683
684                 {handle}
685                 {handleat}
686         }
687   }}
688 }
689
690 # read-write with a 'set' method for all members
691 code struct-readwrite-all insert=struct:header,struct:create-all,struct:set-all
692         fields=init,get,set,getorset,handle,java-setall {
693   class {{
694         // template: struct-readwrite-all:class
695         package {package};
696         import jdk.incubator.foreign.*;
697         import java.lang.invoke.*;
698         import au.notzed.nativez.*;
699
700         public class {Name} implements Pointer {
701                 {header}
702
703                 {create-all}
704
705                 {get}
706                 {set}
707                 {getorset}
708
709                 {handle}
710         }
711   }}
712 }
713
714 code struct-readwrite-array-all insert=struct:header,struct:create-all,struct:array,struct:set-all,struct:setat-all
715         fields=init,init-array,get,getat,set,setat,setallat,getorset,getorsetat,handle,handleat,java-setall,java-setallat {
716   class {{
717         // template: struct-readwrite-array-all:class
718         package {package};
719         import jdk.incubator.foreign.*;
720         import java.lang.invoke.*;
721         import au.notzed.nativez.*;
722
723         public class {Name} implements Pointer,Array<{Name}> {
724                 {header}
725                 {array}
726
727                 {create-all}
728
729                 {get}
730                 {set}
731                 {getorset}
732
733                 {getat}
734                 {setat}
735                 {getorsetat}
736
737                 {handle}
738                 {handleat}
739         }
740   }}
741 }
742
743 # ###################################################################### #
744
745 # Basic value-based accessor
746 type value accessor=value {
747         native-value    {{ {name} }}
748
749         native-get              {{ ({type}){name}$VH.get(this.segment) }}
750         handle                  {{ final static VarHandle {name}$VH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
751
752         java-get                {{ {native-get} }}
753         java-set                {{ {name}$VH.set(this.segment, {native-value}) }}
754
755         native-getat    {{ ({type}){name}$AH.get(this.segment, i$) }}
756         native-setat    {{ {name}$AH.set(this.segment, i$, {native-value}) }}
757         handleat                {{ final static VarHandle {name}$AH = MemoryLayout.sequenceLayout(LAYOUT).varHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
758
759         java-getat              {{ {native-getat} }}
760         java-setat              {{ {native-setat} }}
761 }
762
763 type value-array accessor=value-array {
764         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
765         java-get        {{ {type}.create({native-get}) }}
766
767         native-geti     {{ {name}$EH.get(this.segment, i$) }}
768
769         java-geti       {{ ({typei}){native-geti} }}
770         java-seti       {{ {name}$EH.set(this.segment, i$, {name}) }}
771         handle          {{
772                 final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
773                 final static VarHandle {name}$EH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("{name}"), MemoryLayout.PathElement.sequenceElement());
774         }}
775 }
776
777 type value-array2d accessor=value-array2d {
778         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
779         java-get        {{ {type}.create({native-get}) }}
780         java-geti       {{ ({typei}){name}$EH.get(this.segment, i$, j$) }}
781         java-seti       {{ {name}$EH.set(this.segment, i$, j$, {name}) }}
782         handle          {{
783                 final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
784                 final static VarHandle {name}$EH = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("{name}"), MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.sequenceElement());
785         }}
786 }
787
788 type inline accessor=inline {
789         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
790         java-get        {{ {type}.create({native-get}) }}
791         handle          {{ final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
792
793         native-getat {{ (MemorySegment){name}$SA.invokeExact(this.segment, i$) }}
794         java-getat      {{ {type}.create({native-getat}) }}
795         handleat        {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
796 }
797
798 type inline-array accessor=inline {
799         native-get      {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
800         java-get        {{ {type}.create({native-get}) }}
801         handle          {{ final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
802
803         native-getat {{ (MemorySegment){name}$SA.invokeExact(this.segment, i$) }}
804         java-getat      {{ {type}.create({native-getat}) }}
805         handleat        {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
806 }
807
808 type uint8_t,char value {
809         type    {{ byte }}
810         layout  {{ Memory.BYTE }}
811 }
812
813 type uint16_t value {
814         type    {{ short }}
815         layout  {{ Memory.SHORT }}
816 }
817
818 type uint32_t,int,int32_t value {
819         type    {{ int }}
820         layout  {{ Memory.INT }}
821 }
822
823 type uint64_t,int64_t,size_t value {
824         type    {{ long }}
825         layout  {{ Memory.LONG }}
826 }
827
828 type float value {
829         type    {{ float }}
830         layout  {{ Memory.FLOAT }}
831 }
832
833 type double value {
834         type    {{ double }}
835         layout  {{ Memory.DOUBLE }}
836 }
837
838 # ###################################################################### #
839
840 type uint8_t[],char[] value-array {
841         type    {{ ByteArray }}
842         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.BYTE) }}
843         typei   {{ byte }}
844 }
845
846 type uint32_t[],int32_t[] value-array {
847         type    {{ IntArray }}
848         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.INT) }}
849         typei   {{ int }}
850 }
851
852 type uint64_t[] value-array {
853         type    {{ LongArray }}
854         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.LONG) }}
855         typei   {{ long }}
856 }
857
858 type float[] value-array {
859         type    {{ FloatArray }}
860         layout  {{ MemoryLayout.sequenceLayout({len1}, Memory.FLOAT) }}
861         typei   {{ float }}
862 }
863
864 type struct[] inline-array {
865         type    {{ {baseType} }}
866         layout  {{ MemoryLayout.sequenceLayout({len1}, {baseType}.LAYOUT) }}
867 }
868
869 type struct-expand[] struct[] accessor=inline-expand;
870
871 type float[][] value-array2d {
872         type    {{ FloatArray }}
873         typei   {{ float }}
874         layout  {{ MemoryLayout.sequenceLayout({len1}, MemoryLayout.sequenceLayout({len2}, Memory.FLOAT)) }}
875 }
876
877 # select=len?  or what?
878
879 type pointer value {
880         layout  {{ Memory.POINTER }}
881         type    {{ MemoryAddress }}
882
883         native-value    {{ Memory.address({name}) }}
884         native-get              {{ (MemoryAddress){name}$VH.get(this.segment) }}
885
886 #       java-get        {{ {native-get} }}
887 #       java-set        {{ {name}$VH.set(this.segment, Memory.address({name})) }}
888 }
889
890 type void* pointer;
891
892 type value-pointer pointer {
893         java-get        {{ {type}.create((MemoryAddress){name}$VH.get(this.segment), segment.scope()) }}
894 }
895
896 type uint8_t* value-pointer {
897         type    ByteArray;
898 }
899
900 type uint32_t*,int32_t*,int* value-pointer {
901         type    IntArray;
902 }
903
904 type uint64_t* value-pointer {
905         type    LongArray;
906 }
907
908 type float* value-pointer {
909         type    FloatArray;
910 }
911
912 type size_t* value-pointer {
913         type    LongArray;
914 }
915
916 type pointer-length pointer {
917         java-get        {{ {type}.createArray({native-get}, {length}, this.segment.scope()) }}
918 }
919
920 type void*-length pointer-length {
921         type            MemorySegment;
922         java-get        {{ MemorySegment.ofAddress({native-get}, {length}, this.segment.scope()) }}
923 }
924
925 type uint8_t*-length pointer-length {
926         type    ByteArray;
927 }
928
929 type uint32_t*-length,int32_t*-length pointer-length {
930         type    IntArray;
931 }
932
933 type uint64_t*-length pointer-length {
934         type    LongArray;
935 }
936
937 type float*-length pointer-length {
938         type    FloatArray;
939 }
940
941 # special handling for strings, will fail if it isn't
942 type char* pointer accessor=value-alloc {
943         type            {{ String }}
944
945         java-get        {{ ({native-get}).getUtf8String(0) }}
946         native-value {{ alloc$.allocateUtf8String({name}).address() }}
947
948         # this just verifies it's a string type
949         length eval     {{
950                 if ($v->{len} =~ m/null-terminated/) {
951                         1;
952                 } else {
953                         die Dumper($v, $s);
954                 }
955         }}
956
957 }
958
959 type char**-length pointer-length accessor=value-alloc {
960         type    {{ String[] }}
961
962         java-set        {{ {name}$VH.set(this.segment, Memory.copyStringArray({name}, alloc$).address()); }}
963         java-get        {{ Memory.copyStringArray((MemoryAddress){name}$VH.get(this.segment), {length}) }}
964 }
965
966 type funcpointer pointer {
967         type            {{ FunctionPointer<{baseType}> }}
968         typei           {{ {baseType} }}
969         java-get        {{ {baseType}.downcall({native-get}, this.segment.scope()) }}
970 }
971
972 type void** pointer {
973 }
974
975 type void**-length pointer-length {
976         type    PointerArray;
977 }
978
979 type handle pointer {
980         type            {{ {baseType} }}
981         java-get        {{ {type}.create({native-get}, this.segment.scope()) }}
982 }
983
984 type handle[] value-array accessor=handle-array {
985         type            {{ HandleArray<{typei}> }}
986         typei           {{ {baseType} }}
987         layout          {{ MemoryLayout.sequenceLayout({len1}, Memory.POINTER) }}
988         java-get        {{ HandleArray.create({native-get}, (a, s) -> {typei}.create(a, instance$.dispatch, s), scope$) }}
989
990         java-geti       {{ {typei}.create((MemoryAddress){native-geti}, instance$.dispatch, scope$) }}
991 }
992
993 type handle* pointer {
994         type            {{ HandleArray<{typei}> }}
995         typei           {{ {baseType} }}
996         java-get        {{ HandleArray.create({native-get}, {typei}::create) }}
997 }
998
999 type handle*-length pointer-length {
1000         type            {{ HandleArray<{baseType}> }}
1001         typei           {{ {baseType} }}
1002         java-get        {{ HandleArray.createArray({native-get}, {length}, {typei}::create, this.segment.scope()) }}
1003         java-set        {{ {name}$VH.set(this.segment, Memory.address({name})); }}
1004 }
1005
1006 type struct inline {
1007         type    {{ {baseType} }}
1008         layout  {{ {baseType}.LAYOUT }}
1009 }
1010
1011 type struct-expand inline accessor=inline-expand {
1012         type    {{ {baseType} }}
1013         layout  {{ {baseType}.LAYOUT }}
1014 }
1015
1016 type struct* pointer {
1017         type            {{ {baseType} }}
1018         java-get        {{ {baseType}.create({native-get}, this.segment.scope()) }}
1019 }
1020
1021 type struct*-length pointer-length {
1022         type    {{ {baseType} }}
1023         typei   {{ {baseType} }}
1024 }
1025
1026 type struct** pointer {
1027 }
1028
1029 # xlib
1030 type XID,Window,VisualID uint64_t;
1031
1032 type Display* handle {
1033         type    xlib.XDisplay;
1034 }
1035
1036 # xcb
1037 type xcb_window_t uint32_t;
1038 type xcb_visualid_t uint32_t;
1039 type xcb_connection_t* handle {
1040         type    xcb.Connection;
1041 }
1042
1043 override structs {
1044         VkInstance                      template=handle-instance;
1045         VkPhysicalDevice        template=handle-dispatch;
1046         VkDevice                        template=handle-dispatch;
1047         VkCommandBuffer         template=handle-dispatch;
1048         VkQueue                         template=handle-dispatch;
1049
1050         VkAllocationCallbacks   ignore;
1051
1052         # We want 'set(all fields) for these types and to include them expanded if inline
1053         VkOffset2D expand template=struct-readwrite-array-all;
1054         VkOffset3D expand template=struct-readwrite-array-all;
1055         VkExtent2D expand template=struct-readwrite-all;
1056         VkExtent3D expand template=struct-readwrite-all;
1057         VkRect2D expand template=struct-readwrite-array-all;
1058
1059         VkStencilOpState template=struct-readwrite-all;
1060         VkComponentMapping template=struct-readwrite-all;
1061         VkImageSubresourceRange template=struct-readwrite-all;
1062
1063         VkClearColorValue expand template=struct-readwrite-all;
1064         VkClearDepthStencilValue expand template=struct-readwrite-all;
1065
1066         # Override default read/write
1067         VkDebugUtilsMessengerCallbackDataEXT template=struct-readonly;
1068         VkDebugUtilsLabelEXT template=struct-readonly-array;
1069         VkDebugUtilsObjectNameInfoEXT template=struct-readonly-array;
1070
1071 # 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
1072         VkCuLaunchInfoNVX       pParams=type:pointer pExtras=type:pointer;
1073 }