Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 59 additions & 22 deletions generate_imgui_bindings.pl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
#use diagnostics;

# This works for IMGUI 1.60 and does not get all functions
# This works for IMGUI 1.91.9b and does not get all functions; 292 are supported.
#
# to use ./generate_imgui_bindings.pl <../imgui/imgui.h >imgui_iterator.inl
# and define macros properly as in example imgui_lua_bindings.cpp
Expand All @@ -13,9 +13,10 @@
require "./parse_blocks.pl";

sub generateNamespaceImgui {
my ($imguiCodeBlock) = @_;
my $imguiCodeBlock = $_[0];
my @knownEnums = @{$_[1]};

my $lineCaptureRegex = qr" *(IMGUI_API) *((const char\*)|([^ ]+)) *([^\(]+)\(([^\;]*)\);";
my $lineCaptureRegex = qr" *(IMGUI_API) *((const char\*)|([^ ]+)) *([^\(]+)\(([^\;]*)\)\s*;";
my $doEndStackOptions = 1;
my $terminator = "} \/\/ namespace ImGui";
my $callPrefix = "";
Expand Down Expand Up @@ -64,11 +65,13 @@ sub generateNamespaceImgui {
\%changeN,
\%endN,
\%endOverride,
\@knownEnums,
$imguiCodeBlock)
}

sub generateDrawListFunctions {
my ($imguiCodeBlock) = @_;
my $imguiCodeBlock = $_[0];
my @knownEnums = @{$_[1]};

my $lineCaptureRegex = qr" *(IMGUI_API|inline) *((const char\*)|([^ ]+)) *([^\(]+)\(([^\;]*)\);";
my $doEndStackOptions = 0;
Expand Down Expand Up @@ -108,6 +111,7 @@ sub generateDrawListFunctions {
\%changeN,
\%endN,
\%endOverride,
\@knownEnums,
$imguiCodeBlock)
}

Expand Down Expand Up @@ -137,7 +141,8 @@ sub generateImguiGeneric {
my %endN = %{$endNRef};
my $endOverrideRef = shift;
my %endOverride = %{$endOverrideRef};

my $myKnownEnums = shift;
my $knownEnums = join("|", @{$myKnownEnums});
my ($imguiCodeBlock) = @_;


Expand All @@ -154,7 +159,8 @@ sub generateImguiGeneric {
$line =~ s/ImVec4\(([^,]*),([^\)]*),([^\)]*),([^\)]*)\)/ImVec4 $1 $2 $3 $4/g;

#delete this so it's eaiser for regexes
$line =~ s/ IM_PRINTFARGS\(.\);/;/g;
$line =~ s/ IM_[A-Z]+[ARGS|LIST]\(.\);/;/g;

if ($line =~ m/$lineCaptureRegex/) {
print "//" . $line . "\n";
# this will be set to 0 if something is not supported yet
Expand Down Expand Up @@ -196,15 +202,26 @@ sub generateImguiGeneric {
$callMacro = "${callPrefix}CALL_FUNCTION";
push(@funcArgs, "bool");
push(@after, "PUSH_BOOL(ret)");
} elsif ($retType =~ /^float$/) {
} elsif ($retType =~ /^(float|int|unsigned\s+int|double)$/) {
$callMacro = "${callPrefix}CALL_FUNCTION";
push(@funcArgs, "$1");
push(@after, "PUSH_NUMBER(ret)");
} elsif ($knownEnums ne "" && $retType =~ /^($knownEnums)$/) {
$callMacro = "${callPrefix}CALL_FUNCTION";
push(@funcArgs, "float");
push(@funcArgs, "$1");
push(@after, "PUSH_NUMBER(ret)");
} elsif ($retType =~ /^ImVec2$/) {
$callMacro = "${callPrefix}CALL_FUNCTION";
push(@funcArgs, "ImVec2");
push(@after, "PUSH_NUMBER(ret.x)");
push(@after, "PUSH_NUMBER(ret.y)");
} elsif ($retType =~ /^ImVec4$/) {
$callMacro = "${callPrefix}CALL_FUNCTION";
push(@funcArgs, "ImVec4");
push(@after, "PUSH_NUMBER(ret.x)");
push(@after, "PUSH_NUMBER(ret.y)");
push(@after, "PUSH_NUMBER(ret.z)");
push(@after, "PUSH_NUMBER(ret.w)");
} elsif ($retType =~ /^(unsigned int|ImGuiID|ImU32)$/) {
$callMacro = "${callPrefix}CALL_FUNCTION";
push(@funcArgs, "unsigned int");
Expand All @@ -231,7 +248,7 @@ sub generateImguiGeneric {
push(@funcArgs, $name);
push(@after, "END_FLOAT_POINTER($name)");
#float a or float a = number
} elsif ($args[$i] =~ m/^ *float *([^ =\[]*)( *= *[^ ]*|)$/) {
} elsif ($args[$i] =~ m/^ *(?:float|double) *([^ =\[]*)( *= *[^ ]*|)$/) {
my $name = $1;
if ($2 =~ m/^ *= *([^ ]*)$/) {
push(@before, "OPTIONAL_NUMBER_ARG($name, $1)");
Expand All @@ -249,9 +266,9 @@ sub generateImguiGeneric {
}
push(@funcArgs, $name);
#const ImVec2& with default or not
} elsif ($args[$i] =~ m/^ *const ImVec2& ([^ ]*) *(= * ImVec2 [^ ]* [^ ]*|) *$/) {
} elsif ($args[$i] =~ m/^ *(?:const\s+ImVec2&|ImVec2) ([^ ]*) *(= * ImVec2 [^\s]+ +[^\s]+|) *$/) {
my $name = $1;
if ($2 =~ m/^= * ImVec2 ([^ ]*) ([^ ]*)$/) {
if ($2 =~ m/^= * ImVec2 ([^\s]+)\s+([^\s]+)$/) {
push(@before, "OPTIONAL_IM_VEC_2_ARG($name, $1, $2)");
} else {
push(@before, "IM_VEC_2_ARG($name)");
Expand All @@ -263,25 +280,35 @@ sub generateImguiGeneric {
push(@before, "IM_VEC_2_ARG($name)");
push(@funcArgs, $name);
#const ImVec4& with default or not
} elsif ($args[$i] =~ m/^ *const ImVec4& ([^ ]*) *(= * ImVec4 [^ ]* [^ ]* [^ ]* [^ ]*|) *$/) {
} elsif ($args[$i] =~ m/^ *(?:const\s+ImVec4&|ImVec4) ([^ ]*) *(= * ImVec4 [^\s]*\s+[^\s]*\s+[^\s]*\s+[^\s]*|) *$/) {
my $name = $1;
if ($2 =~ m/^= * ImVec4 ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*)$/) {
if ($2 =~ m/^= * ImVec4 ([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)$/) {
push(@before, "OPTIONAL_IM_VEC_4_ARG($name, $1, $2, $3, $4)");
} else {
push(@before, "IM_VEC_4_ARG($name)");
}
push(@funcArgs, $name);
# one of the various enums
} elsif ($args[$i] =~ m/^\s*(ImGuiKey|ImGuiDir|ImGuiMouseSource|ImGuiSortDirection)\s+(\w+)\s*(=\s*\w+|) *$/) {
my $name = $2;
my $ename = $1;
if ($3 =~ m/^=\s*(\w+)$/) {
push(@before, "OPTIONAL_ENUM_ARG($name, $ename, $1)");
} else {
push(@before, "ENUM_ARG($name, $ename)");
}
push(@funcArgs, $name);
# one of the various generic enums
# we are handling these as ints
} elsif ($args[$i] =~ m/^ *(ImGuiWindowFlags|ImGuiCol|ImGuiStyleVar|ImGuiKey|ImGuiAlign|ImGuiColorEditMode|ImGuiMouseCursor|ImGuiSetCond|ImGuiInputTextFlags|ImGuiSelectableFlags) ([^ ]*)( = 0|) *$/) {
} elsif ($args[$i] =~ m/^ *($knownEnums)\s+(\w+)\s*(=\s*\w+|)\s*$/) {
#These are ints
my $name = $2;
if ($3 =~ m/^ = 0$/) {
push(@before, "OPTIONAL_INT_ARG($name, 0)");
if ($3 =~ m/^=\s*(\w+)$/) {
push(@before, "OPTIONAL_INT_ARG($name, $1)");
} else {
push(@before, "INT_ARG($name)");
}
push(@funcArgs, $name);
# one of the various typed enums
#int with default value or not
} elsif ($args[$i] =~ m/^ *int ([^ =\[]*)( = [^ ]*|) *$/) {
my $name = $1;
Expand Down Expand Up @@ -330,7 +357,7 @@ sub generateImguiGeneric {
push(@after, "END_UINT_POINTER($name)");
# we don't support variadic functions yet but we let you use it without extra variables
} elsif ($args[$i] =~ m/^ *\.\.\. *$/) {
print "// Variadic functions aren't suppported but here it is anyway\n";
print "// Variadic functions aren't supported but here it is anyway\n";
} else {
print "// Unsupported arg type " . $args[$i] . "\n";
$shouldPrint = 0;
Expand Down Expand Up @@ -462,17 +489,27 @@ sub generateEnums {
# splits up its header to multiple instances of namespace ImGui, this would break.
my $alreadyParsedMainImguiNamespace = 0;

my @knownEnums = ();
for (my $i=0; $i < scalar @blocks; $i++) {
if ($blocknames[$i] =~ m/enum ImGui([\w_]*)_\n/) {
push @knownEnums, "ImGui" . $1;
}
}

for (my $i=0; $i < scalar @blocks; $i++) {
print "//" . $blocknames[$i] . "\n";

if (($blocknames[$i] eq "namespace ImGui\n") and not $alreadyParsedMainImguiNamespace) {
$alreadyParsedMainImguiNamespace = 1;
generateNamespaceImgui($blocks[$i]);
generateNamespaceImgui($blocks[$i], \@knownEnums);
}
if ($blocknames[$i] =~ m/enum ImGui(.*)_\n/) {

if ($blocknames[$i] =~ m/enum ImGui([\w_]*)_\n/) {
generateEnums($1, $blocks[$i]);
}

if ($blocknames[$i] eq "struct ImDrawList\n") {
generateDrawListFunctions($blocks[$i]);
generateDrawListFunctions($blocks[$i], \@knownEnums);
}
}

Expand Down
Loading