mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
152 lines
4.4 KiB
Perl
Executable File
152 lines
4.4 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
#
|
|
# Copyright 2025 Henri Verbeet
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 2.1 of the License, or (at your option) any later version.
|
|
#
|
|
# This library is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this library; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
use strict;
|
|
use warnings;
|
|
use JSON;
|
|
use open ':utf8';
|
|
binmode STDOUT, ':utf8';
|
|
|
|
sub method_name($)
|
|
{
|
|
shift->{selector} =~ s/(:.*)//r;
|
|
}
|
|
|
|
sub method_parameters($$)
|
|
{
|
|
my ($method, $method_type) = @_;
|
|
|
|
my $parameters = join ", ", $method_type eq "class" ? () : "id self",
|
|
map {"$_->{type} $_->{name}"} @{$method->{parameters}};
|
|
|
|
length $parameters ? $parameters : "void";
|
|
}
|
|
|
|
sub send_function($)
|
|
{
|
|
shift->{'return-float'} ? "vkd3d_objc_msgSend_fpret" : "objc_msgSend";
|
|
}
|
|
|
|
sub invocation_type($$)
|
|
{
|
|
my ($method, $method_type) = @_;
|
|
|
|
"$method->{'return-type'} (*)(" . join(", ", $method_type eq "class" ? "Class" : "id", "SEL",
|
|
map {$_->{type}} @{$method->{parameters}}) . ")";
|
|
}
|
|
|
|
sub invocation_parameters($$$)
|
|
{
|
|
my ($method, $interface_name, $method_type) = @_;
|
|
|
|
join ", ", $method_type eq "class" ? "objc_getClass(\"$interface_name\")" : "self",
|
|
"sel_registerName(\"$method->{selector}\")", map {$_->{name}} @{$method->{parameters}};
|
|
}
|
|
|
|
sub invocation($$$)
|
|
{
|
|
my ($method, $interface_name, $method_type) = @_;
|
|
|
|
($method->{'return-type'} eq "void" ? "" : "return ")
|
|
. "((${\invocation_type $method, $method_type})f)"
|
|
. "(${\invocation_parameters $method, $interface_name, $method_type});";
|
|
}
|
|
|
|
sub print_method($$$)
|
|
{
|
|
my ($method, $interface_name, $method_type) = @_;
|
|
|
|
print "static inline $method->{'return-type'} "
|
|
. "${interface_name}_${\method_name $method}(${\method_parameters $method, $method_type})\n";
|
|
print "{\n";
|
|
print " void *f = ${\send_function $method};\n";
|
|
print " ${\invocation $method, $interface_name, $method_type}\n";
|
|
print "}\n\n";
|
|
}
|
|
|
|
sub print_property($$)
|
|
{
|
|
my ($property, $interface_name) = @_;
|
|
|
|
my $method =
|
|
{
|
|
'return-type' => $property->{type},
|
|
'return-float' => $property->{float},
|
|
selector => $property->{getter} // $property->{name},
|
|
};
|
|
my $method_type = $property->{class} ? "class" : "instance";
|
|
|
|
print_method $method, $interface_name, $method_type;
|
|
if (!$property->{readonly})
|
|
{
|
|
$method->{'return-type'} = "void";
|
|
$method->{'return-float'} = 0;
|
|
$method->{selector} = "set${\ucfirst $property->{name}}:";
|
|
$method->{parameters} = [$property];
|
|
print_method $method, $interface_name, $method_type;
|
|
}
|
|
}
|
|
|
|
sub print_interface(_)
|
|
{
|
|
my ($interface) = @_;
|
|
|
|
print_method $_, $interface->{name}, "class" foreach (@{$interface->{'class-methods'}});
|
|
print_method $_, $interface->{name}, "instance" foreach (@{$interface->{'instance-methods'}});
|
|
print_property $_, $interface->{name} foreach (@{$interface->{properties}});
|
|
}
|
|
|
|
sub print_header($)
|
|
{
|
|
my ($grammar) = @_;
|
|
|
|
my $guard = "__VKD3D_${\uc $grammar->{name}}_H__";
|
|
|
|
print "/*\n";
|
|
print " * This file is automatically generated.\n";
|
|
print " * The original source is covered by the following license:\n";
|
|
print " *\n";
|
|
print map {" * $_" =~ s/ +$//r . "\n"} @{$grammar->{copyright}};
|
|
print " */\n\n";
|
|
|
|
print "#ifndef $guard\n";
|
|
print "#define $guard\n\n";
|
|
|
|
print "#include <objc/objc-runtime.h>\n\n";
|
|
|
|
print "#ifdef __arm64__\n";
|
|
print "# define vkd3d_objc_msgSend_fpret objc_msgSend\n";
|
|
print "#else\n";
|
|
print "# define vkd3d_objc_msgSend_fpret objc_msgSend_fpret\n";
|
|
print "#endif /* __arm64__ */\n\n";
|
|
|
|
print_interface foreach (@{$grammar->{interfaces}});
|
|
|
|
print "#undef vkd3d_objc_msgSend_fpret\n\n";
|
|
|
|
print "#endif /* $guard */\n";
|
|
}
|
|
|
|
die "No input file specified.\n" unless @ARGV;
|
|
print_header do
|
|
{
|
|
local $/;
|
|
open my $fh, '<', $ARGV[0] or die $!;
|
|
decode_json <$fh>;
|
|
};
|