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