analyseTypes($vk, $api);
-# for structs
+# Use some heuristics to create overrides for improving the api
+
+# - object constructor functions return values rather take pointer* values
+# - array query functions perform the query and return the array
+# - extension functions use a different invocation mechanism
+# - drop any 'ignore' types from argument lists
+
+# - [attempt to] determine which types need to be read/write/arrays
+
+# Scan structs
my %defaultTemplate;
foreach my $s (values %{$api->{types}}) {
foreach my $m (@{$s->{items}}) {
my $nstar = $m->{deref} =~ tr/*/*/;
- # FIXME: this belongs in analyse
- if ($m->{lengthfrom} && $lengths{$m->{lengthfrom}} != 1) {
- $m->{'set-length'} = '';
- }
-
if ($m->{lengthfor} && $nstar == 0 && $lengths{$m->{name}} == 1) {
- $overrides->{$s->{name}}->{$m->{name}}->{type} = $m->{deref}.'-implied';
+ die "No type '$m->{deref}-implied'" if !defined($types->{"$m->{deref}-implied"});
+
+ $overrides->{$s->{name}}->{$m->{name}}->{type} = "$m->{deref}-implied";
+ print "implied: $s->{name} $m->{name} $m->{deref} $s->{index}->{$m->{lengthfor}}->{deref}\n" if $sys->{verbose};
}
+
if ($m->{deref} eq 'struct*-length') {
$defaultTemplate{$m->{baseType}}->{array} = 1;
} elsif ($m->{deref} eq 'struct[]') {
}
}
- if ($s->{returnedonly} eq 'true') {
- $defaultTemplate{$s->{name}}->{name} = 'struct-readonly';
- }
+ $defaultTemplate{$s->{name}}->{name} = 'struct-readonly' if ($s->{returnedonly} eq 'true');
}
# build default overrides for commands
foreach my $s (values %{$api->{commands}}) {
my $overrides = $commandTypes->{overrides};
my $types = $commandTypes->{types};
+ my $first = $s->{items}->[0];
+ my $last = $s->{items}->[$#{$s->{items}}];
+ my $llast = $s->{items}->[$#{$s->{items}}-1];
+ my $result = $s->{proto};
+ my $index = $s->{index};
# check type updates anyway
foreach my $m (@{$s->{items}}) {
if ($m->{deref} eq 'struct*-length') {
- $defaultTemplate{$m->{baseType}}->{name} = 'struct-readwrite' if !($m->{fullType} =~ m/const/n);
+ $defaultTemplate{$m->{baseType}}->{name} = 'struct-readwrite' if !($m->{fullType} =~ m/const/n) && $api->{types}->{$m->{baseType}}->{returnedonly} ne 'true';
$defaultTemplate{$m->{baseType}}->{array} = 1;
} elsif ($m->{deref} eq 'struct*') {
$defaultTemplate{$m->{baseType}}->{name} = 'struct-readwrite' if !($m->{fullType} =~ m/const/n);
next if (defined($overrides->{$s->{name}}));
- my $first = $s->{items}->[0];
- my $last = $s->{items}->[$#{$s->{items}}];
- my $result = $s->{proto};
- my $index = $s->{index};
-
- #map { $index->{$_->{name}} = $_ } @{$s->{items}};
-
my $override = {};
# force handles to be instance types
$override->{$first->{name}}->{type} = 'instance';
}
- # extension functions
+ # extension function default template
if (defined($s->{extensions})) {
- $override->{template} = $commandTypes->{templates}->{'method-extension'};
+ $override->{template} = 'method-extension';
}
+ # Constructor
if ($last->{deref} eq 'handle*') {
if (!$last->{len}) {
my $t = $api->{handles}->{$last->{baseType}};
}
}
+ # turn array-query functions into auto-allocate/return types
# ones we care about with output
# handle*-length
# struct*-length
# uint32_t*-length
# void*-length
- if ($s->{successcodes} =~ m/VK_INCOMPLETE/ && $last->{deref} =~ m/-length$/) {
- my $protoa = "$result->{fullType} $s->{name}("
- .join(', ', map { "$_->{fullType}" } @{$s->{items}})
- .")";
- my $protob = "$result->{deref} $s->{name}("
- .join(', ', map { $_->{len} ? "$_->{deref} \[$_->{len}\]" : $_->{deref} } @{$s->{items}})
- .")";
-
- print "array-constructor: $protoa\n" if $sys->{verbose} > 1;
- print "array-constructor: $protob\n" if $sys->{verbose} > 1;
-
- $override->{template} =
- defined($s->{extensions}) ?
- $commandTypes->{templates}->{'method-extension-query'} :
- $commandTypes->{templates}->{'method-query'};
- foreach my $m (@{$s->{items}}) {
- if ($m->{deref} =~ m/-length$/ && (my $len = $index->{$m->{len}})) {
- my $type;
+ if ($last->{deref} =~ m/-length$/ && (my $len = $index->{$last->{len}})) {
+ if (index($len->{deref}, '*') >= 0) {
+ my $protoa = "$result->{fullType} $s->{name}("
+ .join(', ', map { "$_->{fullType}" } @{$s->{items}})
+ .")";
+ print "array-constructor: $protoa\n" if $sys->{verbose} > 1;
- if ($m->{deref} eq 'handle*-length' && $api->{handles}->{$last->{baseType}}->{type} eq 'VK_DEFINE_HANDLE') {
- $type = 'dispatch*-length-query';
- } else {
- $type = $m->{deref}.'-query';
- }
+ my $otype = ($last->{deref} eq 'handle*-length' && $api->{handles}->{$last->{baseType}}->{type} eq 'VK_DEFINE_HANDLE')
+ ? 'dispatch*-length-query' : $last->{deref}.'-query';
+ my $ltype = $len->{deref}.'-querylen';
- die "no template $m->{deref}-query" if !defined($commandTypes->{types}->{$type});
- $override->{$m->{name}}->{type} = $type;
+ die "no template $otype" if !defined($commandTypes->{types}->{$otype});
+ die "no template $ltype" if !defined($commandTypes->{types}->{$ltype});
- die "no template $len->{deref}-querysize" if !defined($commandTypes->{types}->{$len->{deref}.'-querylen'});
- $override->{$len->{name}}->{type} = $len->{deref}.'-querylen';
- }
+ $override->{template} = defined($s->{extensions}) ? 'method-extension-query' : 'method-query';
+ $override->{$last->{name}}->{type} = $otype;
+ $override->{$len->{name}}->{type} = $ltype;
}
}
my $so = $structTypes->{overrides}->{$m->{baseType}};
if ($so->{ignore}) {
- $m->{deref} .= '-ignore';
- }
-
- # All the vkCmd commands shouldn't imply any array lengths, maybe nothing should really?
- if ($first->{baseType} ne 'VkCommandBuffer' && $m->{lengthfor}) {
- my $nstar = $m->{deref} =~ tr/*/*/;
- if ($nstar == 0) {
- die "No '$m->{deref}-length' type ".Dumper($s) if !defined $types->{$m->{deref}.'-length'};
- $override->{$m->{name}}->{type} = $m->{deref}.'-length';
- } else {
- if (defined($s->{extensions})) {
- #$overrides->{$s->{name}}->{template} = $commandTypes->{templates}->{'method-extension'};
- print "length-extension: $m->{deref} $s->{name} $m->{name} $m->{lengthfor}\n" if $sys->{verbose};
- } else {
- #die "No '$m->{deref}-output' type ".Dumper($s) if !defined $types->{$m->{deref}.'-otuput'};
-
- #$overrides->{$s->{name}}->{template} = $commandTypes->{templates}->{'method-query'};
- #$overrides->{$s->{name}}->{$m->{name}}->{type} = $types->{$m->{deref}.'-output'};
-
- print "length: $m->{deref} $s->{name} $m->{name} $m->{lengthfor}\n" if $sys->{verbose};
- }
-
- }
- # TODO: implied return things
+ die "No type '$m->{deref}-ignore'" if !defined($types->{$m->{deref}.'-ignore'});
+ $override->{$m->{name}}->{type} = $m->{deref}.'-ignore';
}
}
print "$name: $k\n" if $sys->{verbose} > 1;
die "No override $k $name" if !$templates->{$name};
- $overrides->{$k}->{template} = $templates->{$name};
+ $overrides->{$k}->{template} = $name;
}
}
-
-#$overrides->{$s->{name}}->{template} = $structTypes->{templates}->{'struct-readonly'};
-
-#print Dumper({ types=>$types, templates=>$templates });
-#print Dumper($vk);
-
if (0) {
open(my $f, '>', 'types.pm');
print $f Dumper($commandTypes, $structTypes);
die;
}
-if (0) {
- open(my $f, '>', 'data.pm');
- print $f Dumper({
- 'handles' => $api->{handles},
- 'types' => $api->{types},
- 'commands' => $api->{commands},
- 'funcpointers' => $api->{funcpointers},
- });
- close $f;
-}
-
exportEnums($vk, $api, 'VkConstants');
-# dump out the extension function tables
+# dump out the extension function-pointer tables
{
my $f = openOutput($sys, 'DispatchInstance');
my $template = $structTypes->{templates}->{dispatch};
# Load the fields
foreach my $s (@{$t->{items}}) {
- # FIXME: maybe i don't want struct here, as with templates
- my $x = {
- code => defined($s->{literal}) ? $s->{literal} : $s->{options}->[$#{$s->{options}}]
- };
-
- $x->{eval} = 1 if config::optionFlag('eval', $s);
+ if (defined $s->{literal}) {
+ $type->{$s->{match}} = $s->{literal};
+ } elsif ($#{$s->{options}} >= 0) {
+ $type->{$s->{match}} = $s->{options}->[$#{$s->{options}}];
+ } else {
+ $type->{$s->{match}} = 0;
+ }
- $type->{$s->{match}} = $x;
+ $type->{"$s->{match}:eval"} = 1 if config::optionFlag('eval', $s);
}
# Write to all aliases
foreach my $o (@{$t->{options}}) {
if ($o =~ m/insert=(.*)/) {
- foreach my $t (split /,/,$1) {
- if ($t =~ m/(.*):(.*)/) {
- die if !defined $templates->{$1}->{$2};
+ foreach my $x (split /,/,$1) {
+ if ($x =~ m/(.*):(.*)/) {
+ die "$x $t->{name} ".Dumper($templates->{$1}) if !defined $templates->{$1}->{$2};
$code->{insert}->{$2} = $templates->{$1}->{$2};
}
}
} elsif ($o =~ m/^fields=(.*)/) {
$code->{fields} = $1;
+ } elsif (defined($templates->{$o})) {
+ $code = { %$code, %{$templates->{$o}} };
} else {
- die ("Unknown option $o");
+ die ("Unknown option '$o'");
}
}
foreach my $s (@{$t->{items}}) {
- $code->{$s->{match}} = $s->{literal};
- $code->{$s->{match}} =~ s/^\t//gm;
+ if (defined $s->{literal}) {
+ my $t = $s->{literal};
+
+ $t =~ s/^\t//gm;
+ $code->{$s->{match}} = $t;
+ } else {
+ delete $code->{$s->{match}};
+ }
- # hack since the template is a string
- $code->{"$s->{match}:eval"}->{eval} = 1 if config::optionFlag('eval', $s);
+ $code->{"$s->{match}:eval"} = 1 if config::optionFlag('eval', $s);
}
$templates->{$t->{name}} = $code;
$c->{$1}->{accessor} = $templates->{$2};
} elsif ($o =~ m/^template=(.*)/) {
die "No template $o" if !defined($templates->{$1});
- $c->{template} = $templates->{$1};
+ $c->{template} = $1;
} elsif ($o eq 'ignore') {
$c->{ignore} = 1;
}
$m->{length} = "get$len->{Name}()";
$m->{lengthfrom} = $len->{name};
$len->{lengthfor} = $m->{name};
- $m->{'set-length'} = "set$len->{Name}((int)Memory.length($m->{name}))";
}
} elsif ($m->{len} eq 'null-terminated') {
# ignore
$m->{length} = "get$len->{Name}()";
$m->{lengthfrom} = $len->{name};
$len->{lengthfor} = $m->{name};
- $m->{'set-length'} = "set$len->{Name}($cast"."Memory.length($m->{name}))";
} else {
die "what?".Dumper($m);
}
my $type = shift;
my $v = { %{$m} };
- foreach my $k (keys %$type) {
+ foreach my $k (grep { index($_, ':') == -1 } keys %$type) {
my $t = $type->{$k};
- if (ref($t) eq '') {
+ if ($type->{"$k:eval"}) {
$v->{$k} = $t;
- } elsif ($t->{eval}) {
- $v->{$k} = eval $t->{code};
-
die "Eval failed: $! $@: ".Dumper($m, $type) if !defined($v->{$k});
- } elsif (defined($t->{code})) {
- $v->{$k} = $t->{code};
+ } elsif ($t) {
+ $v->{$k} = $t;
}
}
my $overrides = $structTypes->{overrides};
my $override = $overrides->{$s->{name}};
- my $template = $override->{template} ? $override->{template} : $templates->{'struct-writeonly'};
+ my $tempname = $override->{template} ? $override->{template} : 'struct-writeonly';
+ my $template = $templates->{$tempname};
my @fields = split(/,/, $template->{fields});
my $info;
my $setall = defined $info->{'java-setall'};
+ # unions need multiple constructors
if ($setall) {
if ($s->{category} eq 'struct') {
$info->{create}->{create} = {
}
}
- #map { $_->{typeInfo} = buildVars($s, $_, $types->{$_->{deref}}) } @{$s->{items}};
-
- # FIXME: unions need multiple constructors!
-
+ # Collect all fields
foreach my $m (@{$s->{items}}) {
my $nstar = $m->{deref} =~ tr/*/*/;
my $deref = defined($override->{$m->{name}}) && defined($override->{$m->{name}}->{type}) ? $override->{$m->{name}}->{type} : $m->{deref};
my @todump;
if ($m->{values}) {
- @todump = qw(init initat set setat);
+ @todump = qw(init initat init-array set setat);
} else {
@todump = qw(get getat set setat getorset getorsetat);
- # FIXME: something here is adding length parameters which are already handled by the setXX() calls
if ($setall && !$m->{'no-setall'}) {
my $create = $s->{category} eq 'struct' ? $info->{create}->{create} : $info->{create}->{"create$m->{Name}"};
- #push @{$create->{setallArgs}}, code::formatTemplate($type->{accessor}->{'setall-arg'}, $v) if $type->{accessor}->{'setall-arg'};
- #push @{$create->{setall}}, code::formatTemplate($type->{accessor}->{setall}, $v) if $type->{accessor}->{setall};
formatAccessorIf($s, $m, $create, $type, 'setall-arg', $v);
formatAccessorIf($s, $m, $create, $type, 'setall', $v);
}
push @{$info->{handleat}}, code::formatTemplate($v->{handleat}, $v) if $info->{handleat} && $v->{handleat};
foreach my $field (@todump) {
- push @{$info->{$field}}, code::formatTemplate($type->{accessor}->{$field}, $v) if $info->{$field} && $type->{accessor}->{$field};
+ if ($info->{$field} && $type->{accessor}->{$field}) {
+ my $t = $type->{accessor}->{$field};
+
+ $t = eval $t if $type->{accessor}->{"$field:eval"};
+ die "$@" if !defined($t);
+
+ push @{$info->{$field}}, code::formatTemplate($t, $v);
+ }
}
}
}
name => $s->{name},
Name => $s->{Name},
layout => formatStructLayout($types, $s),
- #init => join ("\n", @{$info->{init}}),
- #get => join ("\n", @{$info->{get}}),
- #set => join ("\n", @{$info->{set}}),
- #getorset => join ("\n", @{$info->{getorset}}),
- ##'java-setall-arguments' => join (",", @{$info->{setallArgs}}),
- ##'java-setall' => join ("\n", @{$info->{setall}}),
- #varhandle => join ("\n", @{$info->{varhandle}}),
};
foreach my $field (@fields) {
my $templates = $structTypes->{templates};
my $overrides = $structTypes->{overrides};
my $override = $overrides->{$s->{name}};
- my $template = $override->{template} ? $override->{template} : $templates->{handle};
+ my $tempname = $override->{template} ? $override->{template} : 'handle';
+ my $template = $templates->{$tempname};
my $info = {
init => [],
die "No sig defined ".Dumper($m) if !defined($x) || !defined($x->{sig});
- $d .= $x->{sig}->{code};
+ $d .= $x->{sig};
}
$d .= ')';
my $m = $s->{proto};
my $x = $types->{$m->{deref}};
die "No sig defined ".Dumper($m) if !defined($x) || !defined($x->{sig});
- $d .= $x->{sig}->{code};
+ $d .= $x->{sig};
}
-# TODO: only collect shit we need
+# Forms all the parameter templates
sub collectFunctionInfo {
my $api = shift;
my $ct = shift;
my $s = shift;
- my $templates = $ct->{templates};
my $types = $ct->{types};
my $overrides = $ct->{overrides};
my $void = $s->{proto}->{fullType} eq 'void';
my $needScope = 0;
my $trampScope = 0;
- #return if !defined($override->{template});
- #return if ($s->{name} ne 'vkCmdUpdateBuffer');
-
my @arrayFields = qw(java-arg invoke-arg native-init query-init query-arg native-arg trampoline-arg);
my @fixedFields = qw(java-result java-result-return java-result-assign);
map { $info->{$_} = [] } @arrayFields;
+ # Calculate parameters
foreach my $m (@{$s->{items}}) {
my $deref = defined($override->{$m->{name}}) && defined($override->{$m->{name}}->{type}) ? $override->{$m->{name}}->{type} : $m->{deref};
my $type = $types->{$deref};
$info->{$field} = code::formatTemplate($v->{$field}, $v) if ($v->{$field});
}
- if (0) {
- push @javaArgs, "/* $m->{name} $m->{deref} */ ".code::formatTemplate($v->{'java-arg'}, $v) if ($v->{'java-arg'});
- push @invokeArgs, code::formatTemplate($v->{'invoke-arg'}, $v) if ($v->{'invoke-arg'});
-
- push @nativeInit, code::formatTemplate($v->{'native-init'}, $v) if ($v->{'native-init'});
- push @queryInit, code::formatTemplate($v->{'query-init'}, $v) if ($v->{'query-init'});
-
- if ($v->{'query-arg'}) {
- push @queryArgs, code::formatTemplate($v->{'query-arg'}, $v);
- } elsif ($v->{'invoke-arg'}) {
- push @queryArgs, code::formatTemplate($v->{'invoke-arg'}, $v);
- }
-
- push @nativeArgs, code::formatTemplate($v->{'native-arg'}, $v) if ($v->{'native-arg'});
- push @trampArgs, code::formatTemplate($v->{'trampoline-arg'}, $v) if ($v->{'trampoline-arg'});
-
- $info->{'java-result'} = code::formatTemplate($v->{'java-result'}, $v) if ($v->{'java-result'});
- $info->{'java-result-return'} = code::formatTemplate($v->{'java-result-return'}, $v) if ($v->{'java-result-return'});
- $info->{'java-result-assign'} = code::formatTemplate($v->{'java-result-assign'}, $v) if ($v->{'java-result-assign'});
- }
-
$needScope = 1 if $type->{'need-scope'};
$needFrame = 1 if $type->{'need-frame'};
$needAlloc = 1 if $type->{'need-alloc'};
$info->{'static'} = $hasInstance ? '' : 'static ';
+ # Handle default return types, others are handled by the fixedFields above
if ($s->{successcodes}) {
my @codes = split(/,/,$s->{successcodes});
$info->{'java-result'} = 'int';
$info->{'java-result-return'} = 'return result$;';
}
-
} elsif ($s->{proto}->{fullType} ne 'void') {
my $m = $s->{proto};
my $type = defined($override->{$m->{name}}) ? $override->{$m->{name}}->{type} : $types->{$m->{deref}.'-return'};
$info->{$field} = join $with, @{$info->{$field}};
}
- if (0) {
- $info->{'java-arguments'} = join ",\n\t", @javaArgs;
- $info->{'native-init'} = join "\n\t", @nativeInit;
- $info->{'invoke-arguments'} = join ", ", @invokeArgs;
- $info->{'query-init'} = join "\n\t\t\t", @queryInit;
- $info->{'query-arguments'} = join ", ", @queryArgs;
-
- $info->{'native-arguments'} = join ",\n\t", @nativeArgs;
- $info->{'trampoline-arguments'} = join ",\n\t", @trampArgs;
- }
-
$info->{successcodes} = $s->{successcodes} ? $s->{successcodes} : '';
$info->{errorcodes} = $s->{errorcodes} ? $s->{errorcodes}: '';
sub formatFunctionDescriptor {
my $ct = shift;
my $s = shift;
-
- my $templates = $ct->{templates};
my $types = $ct->{types};
- my $overrides = $ct->{overrides};
-
my @fields = ();
my $void = $s->{proto}->{fullType} eq 'void';
- my $override = $overrides->{$s->{name}};
+ my $override = $ct->{overrides}->{$s->{name}};
foreach my $m ($void ? () : $s->{proto}, @{$s->{items}}) {
my $deref = defined($override->{$m->{name}}) && defined($override->{$m->{name}}->{type}) ? $override->{$m->{name}}->{type} : $m->{deref};
my $api = shift;
my $ct = shift;
my $s = shift;
- my $templates = $ct->{templates};
- my $types = $ct->{types};
- my $overrides = $ct->{overrides};
my $void = $s->{proto}->{fullType} eq 'void';
- my $override = $overrides->{$s->{name}};
- my $template = $override->{template} ? $override->{template} : $templates->{method};
+ my $override = $ct->{overrides}->{$s->{name}};
+ my $tempname = $override->{template} ? $override->{template} : 'method';
+ my $template = $ct->{templates}->{$tempname};
my $info = collectFunctionInfo($api, $ct, $s);
#join("\n", map { '// '.$_ } split(/\n/,Dumper($s)))."\n".
- code::formatTemplate($template->{invoke}, $info);
+ " /* template: $tempname */\n".
+ code::formatTemplate($template->{invoke}, $info);
}
# {java-get}
# {java-set}
# {init}*
+# {init-array}*
+# {setall-arg}
+# {setall}
code value {
get {{
}
}}
- # FIXME: only handles single element arrays
- init {{ {name}$VH.set(this.segment, VkConstants.{values}); }}
+ # Initialise the sType field if it has one, also include sub-
+ init eval {{
+ if ($tempname =~ m/write/) {
+ my $init = "{name}\$VH.set(self\$.segment, VkConstants.{values});\n";
+ foreach my $x (@{$s->{items}}) {
+ if ($x->{deref} eq 'struct') {
+ my $y = $api->{types}->{$x->{baseType}};
+ if ($#{$y->{items}} >= 0 && $y->{items}->[0]->{values}) {
+ my $z = $y->{items}->[0];
+ $init .= "self\$.get$x->{Name}().set$z->{Name}(VkConstants.$z->{values});\n";
+ }
+ }
+ }
+ return $init;
+ } else {
+ ''
+ }
+ }}
- # for complex constructors?
- setall-arg {{ {type} {name} /* value */ }}
- setall {{ self$.set{Name}({name}); }}
+ init-array eval {{
+ if ($tempname =~ m/write.*array/n) {
+ my $init = "{name}\$AH.set(self\$.segment, i, VkConstants.{values});\n";
+ foreach my $x (@{$s->{items}}) {
+ if ($x->{deref} eq 'struct') {
+ my $y = $api->{types}->{$x->{baseType}};
+ if ($#{$y->{items}} >= 0 && $y->{items}->[0]->{values}) {
+ my $z = $y->{items}->[0];
+ $init .= "self\$.get$x->{Name}AtIndex(i).set$z->{Name}(VkConstants.$z->{values});\n";
+ }
+ }
+ }
+
+ "for (long i=0; i<length; i++) {\n\t$init\n\t}\n";
+ } else {
+ ''
+ }
+ }}
+
+ # for complex constructors
+ setall-arg {{ {type} {name} }}
+ setall {{ self$.set{Name}({name}); }}
}
code value-array {
}}
}
+# don't like having to pass scope here, not sure what else to do though
+code handle-array {
+ getorset {{
+ /* value-array {deref} */
+ public {type} get{Name}(VkInstance instance$, ResourceScope scope$) {
+ try {
+ return {java-get};
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ public {typei} get{Name}Element(int i$, VkInstance instance$, ResourceScope scope$) {
+ return {java-geti};
+ }
+ public void set{Name}Element(int i$, {typei} {name}) {
+ {java-seti};
+ }
+ }}
+}
+
code value-array2d {
getorset {{
/* value-array2d {deref} */
}
}
}}
+ getorsetat {{
+ /* inline {deref} */
+ public {type} get{Name}AtIndex(long i$) {
+ try {
+ return {java-getat};
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ }}
}
# value with a SegmentAllocator passed to set()
-code value-alloc {
- get {{
- /* {deref} */
- public {type} get{Name}() {
- return {java-get};
- }
- }}
+code value-alloc value {
set {{
/* {deref} */
public void set{Name}({type} {name}, SegmentAllocator alloc$) {
{java-set};
}
}}
- getat {{
- /* {deref} */
- public {type} get{Name}AtIndex(long i$) {
- return {java-getat};
- }
- }}
setat {{
/* {deref} */
public void set{Name}AtIndex(long i$, {type} {name}, SegmentAllocator alloc$) {
{java-setat};
}
}}
- setall-arg {{ {type} {name} }}
- setall {{ self$.set{Name}({name}, alloc$); }}
+
+ setall {{ self$.set{Name}({name}, alloc$); }}
}
# implied accessors are ignored in constructors
-code value-implied {
- get {{
- /* {deref} */
- public {type} get{Name}() {
- return {java-get};
- }
- }}
- set {{
- /* {deref} */
- public void set{Name}({type} {name}) {
- {java-set};
- }
- }}
-
- # supposed to be handled in set of the target, but ...?
- setall {{ self$.set{Name}(({type})Memory.length({lengthfor})); }}
+code value-implied value {
+ setall-arg;
+ setall {{ self$.set{Name}(({type})Memory.length({lengthfor})); }}
}
# ###################################################################### #
private {Name}(MemorySegment segment) {
this.segment = segment;
- {init}
}
public static {Name} create(MemorySegment segment) {
}
public static {Name} create(MemoryAddress address, ResourceScope scope) {
- return new {Name}(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope));
+ return create(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope));
}
public static {Name} create(SegmentAllocator alloc) {
- return new {Name}(alloc.allocate(LAYOUT));
+ var self$ = create(alloc.allocate(LAYOUT));
+ {init}
+ return self$;
}
// Pointer
}}
create-all {{
public static {Name} {create}({java-setall-arguments}) {
- {Name} self$ = create(alloc$.allocate(LAYOUT));
+ {Name} self$ = create(alloc$);
{java-setall}
}}
array {{
static {Name} createArray(MemoryAddress addr, long length, ResourceScope scope) {
- return new {Name}(MemorySegment.ofAddress(addr, length * LAYOUT.byteSize(), scope));
+ return create(MemorySegment.ofAddress(addr, length * LAYOUT.byteSize(), scope));
}
public static {Name} createArray(long length, SegmentAllocator alloc) {
- return new {Name}(alloc.allocateArray(LAYOUT, length));
+ var self$ = create(alloc.allocateArray(LAYOUT, length));
+ {init-array}
+ return self$;
}
public final static MethodHandle LAYOUT$SH = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement());
}
code struct-writeonly-array insert=struct:header,struct:create-all,struct:array
- fields=init,set,getorset,setat,getorsetat,handle,handleat,java-setall {
+ fields=init,init-array,set,getorset,setat,getorsetat,handle,handleat,java-setall {
class {{
// template: struct-writeonly-array:class
package {package};
}
code struct-readonly-array insert=struct:header,struct:array
- fields=init,get,getorset,getat,getorsetat,handle,handleat {
+ fields=init,init-array,get,getorset,getat,getorsetat,handle,handleat {
class {{
// template: struct-readonly-array:class
package {package};
}
code struct-readwrite-array insert=struct:header,struct:create-all,struct:array
- fields=init,get,getat,set,setat,getorset,getorsetat,handle,handleat,java-setall {
+ fields=init,init-array,get,getat,set,setat,getorset,getorsetat,handle,handleat,java-setall {
class {{
// template: struct-readwrite-array:class
package {package};
type value-array accessor=value-array {
native-get {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
java-get {{ {type}.create({native-get}) }}
- java-geti {{ ({typei}){name}$EH.get(this.segment, i$) }}
+
+ native-geti {{ {name}$EH.get(this.segment, i$) }}
+
+ java-geti {{ ({typei}){native-geti} }}
java-seti {{ {name}$EH.set(this.segment, i$, {name}) }}
handle {{
final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
native-get {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
java-get {{ {type}.create({native-get}) }}
handle {{ final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
+
+ native-getat {{ (MemorySegment){name}$SA.invokeExact(this.segment, i$) }}
+ java-getat {{ {type}.create({native-getat}) }}
+ handleat {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
}
type inline-array accessor=inline {
-# type {{ MemorySegment }}
native-get {{ (MemorySegment){name}$SH.invokeExact(this.segment) }}
-# java-get {{ {native-get} }}
java-get {{ {type}.create({native-get}) }}
- handle {{
- final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}"));
- }}
+ handle {{ final static MethodHandle {name}$SH = LAYOUT.sliceHandle(MemoryLayout.PathElement.groupElement("{name}")); }}
+
+ native-getat {{ (MemorySegment){name}$SA.invokeExact(this.segment, i$) }}
+ java-getat {{ {type}.create({native-getat}) }}
+ handleat {{ final static MethodHandle {name}$SA = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("{name}")); }}
}
type uint8_t,char value {
type char**-length pointer-length accessor=value-alloc {
type {{ String[] }}
- java-set {{ {name}$VH.set(this.segment, Memory.copyStringArray({name}, alloc$).address()); {set-length} }}
+ java-set {{ {name}$VH.set(this.segment, Memory.copyStringArray({name}, alloc$).address()); }}
java-get {{ Memory.copyStringArray((MemoryAddress){name}$VH.get(this.segment), {length}) }}
-
-# set-length eval {{
-# if ($v->{len} =~ m/(.*),null-terminated/) {
-# 'set'.ucfirst($1).'({name}.length)';
-# } else {
-# die Dumper($v, $s);
-# }
-# }}
-}
-
-# FIXME: wrong
-type uint32_t** pointer {
- type {{ HandleArray<IntArray> }}
}
type funcpointer pointer {
java-get {{ {type}.create({native-get}, this.segment.scope()) }}
}
-# FIXME: wrong
-type handle[] {
- type {{ HandleArray<{typei}> }}
- layout {{ MemoryLayout.sequenceLayout({len1}, Memory.POINTER) }}
- #java-get {{ HandleArray.create({get}, {typei}::create) }}
- java-get {{ error }}
- typei {{ {baseType} }}
+type handle[] value-array accessor=handle-array {
+ type {{ HandleArray<{typei}> }}
+ typei {{ {baseType} }}
+ layout {{ MemoryLayout.sequenceLayout({len1}, Memory.POINTER) }}
+ java-get {{ HandleArray.create({native-get}, (a, s) -> {typei}.create(a, instance$.dispatch, s), scope$) }}
+
+ java-geti {{ {typei}.create((MemoryAddress){native-geti}, instance$.dispatch, scope$) }}
}
type handle* pointer {
type {{ HandleArray<{baseType}> }}
typei {{ {baseType} }}
java-get {{ HandleArray.createArray({native-get}, {length}, {typei}::create, this.segment.scope()) }}
- java-set {{ {name}$VH.set(this.segment, Memory.address({name})); {set-length} }}
+ java-set {{ {name}$VH.set(this.segment, Memory.address({name})); }}
}
type struct inline {
layout {{ {baseType}.LAYOUT }}
}
-# how? length?
type struct* pointer {
type {{ {baseType} }}
java-get {{ {baseType}.create({native-get}, this.segment.scope()) }}
VkAllocationCallbacks ignore;
- #VkQueueFamilyProperties template=struct-readwrite;
-
# Override default read/write
VkDebugUtilsMessengerCallbackDataEXT template=struct-readonly;
VkDebugUtilsLabelEXT template=struct-readonly-array;