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