jai port :D
This commit is contained in:
239
modules/ImGui/generate.jai
Normal file
239
modules/ImGui/generate.jai
Normal file
@@ -0,0 +1,239 @@
|
||||
AT_COMPILE_TIME :: true;
|
||||
|
||||
IMGUI_PATH :: "src";
|
||||
|
||||
DECLARATIONS_TO_OMIT :: string.[
|
||||
"ImVec2",
|
||||
"ImVec4",
|
||||
"ImColor",
|
||||
"ImVector",
|
||||
"ImDrawCallback",
|
||||
"ImGuiTextBuffer",
|
||||
"ImDrawCallback_ResetRenderState",
|
||||
];
|
||||
|
||||
#if AT_COMPILE_TIME {
|
||||
#run,stallable {
|
||||
set_build_options_dc(.{do_output=false});
|
||||
root_options := get_build_options();
|
||||
args := root_options.compile_time_command_line;
|
||||
if !generate_bindings(args) {
|
||||
compiler_set_workspace_status(.FAILED);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#import "System";
|
||||
|
||||
main :: () {
|
||||
set_working_directory(path_strip_filename(get_path_of_running_executable()));
|
||||
args := get_command_line_arguments();
|
||||
if !generate_bindings(args) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generate_bindings :: (args: [] string) -> bool {
|
||||
compile := array_find(args, "-compile");
|
||||
compile_debug := array_find(args, "-debug");
|
||||
|
||||
if compile {
|
||||
imgui_src_files: [..] string;
|
||||
array_add(*imgui_src_files, tprint("%/imgui.cpp", IMGUI_PATH));
|
||||
array_add(*imgui_src_files, tprint("%/imgui_widgets.cpp", IMGUI_PATH));
|
||||
array_add(*imgui_src_files, tprint("%/imgui_draw.cpp", IMGUI_PATH));
|
||||
array_add(*imgui_src_files, tprint("%/imgui_tables.cpp", IMGUI_PATH));
|
||||
array_add(*imgui_src_files, tprint("%/imgui_demo.cpp", IMGUI_PATH));
|
||||
array_add(*imgui_src_files, tprint("%/backends/imgui_impl_win32.cpp", IMGUI_PATH));
|
||||
array_add(*imgui_src_files, tprint("%/backends/imgui_impl_dx12.cpp", IMGUI_PATH));
|
||||
array_add(*imgui_src_files, tprint("%/imgui_backend_c.cpp", IMGUI_PATH));
|
||||
|
||||
success := true;
|
||||
#if OS == .WINDOWS {
|
||||
make_directory_if_it_does_not_exist("windows");
|
||||
success &&= build_cpp_static_lib("windows/ImGui", ..imgui_src_files,
|
||||
extra = .[
|
||||
"/DIMGUI_API=__declspec(dllexport)",
|
||||
"/DIMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS",
|
||||
tprint("/I%", IMGUI_PATH),
|
||||
tprint("/I%/backends", IMGUI_PATH),
|
||||
],
|
||||
debug=compile_debug);
|
||||
} else {
|
||||
assert(false, "Only Windows is supported for this project.");
|
||||
}
|
||||
|
||||
if !success return false;
|
||||
}
|
||||
|
||||
defer array_reset(*begin_end_string_args);
|
||||
|
||||
output_filename: string;
|
||||
opts: Generate_Bindings_Options;
|
||||
{
|
||||
using opts;
|
||||
|
||||
#if OS == .WINDOWS {
|
||||
array_add(*library_search_paths, "windows");
|
||||
output_filename = "windows.jai";
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
array_add(*libraries, .{filename="ImGui"});
|
||||
array_add(*include_paths, IMGUI_PATH);
|
||||
array_add(*source_files, tprint("%/imgui.h", IMGUI_PATH));
|
||||
array_add(*extra_clang_arguments, "-x", "c++", "-DWIN32_LEAN_AND_MEAN");
|
||||
array_add(*flatten_namespaces, "ImGui");
|
||||
array_add(*strip_prefixes, "ImGui");
|
||||
auto_detect_enum_prefixes = false;
|
||||
log_stripped_declarations = false;
|
||||
generate_compile_time_struct_checks = false;
|
||||
strip_flags |= .INLINED_FUNCTIONS;
|
||||
|
||||
visitor = imgui_visitor;
|
||||
get_func_args_for_printing = imgui_get_function_arg_for_printing;
|
||||
}
|
||||
|
||||
return generate_bindings(opts, output_filename);
|
||||
}
|
||||
|
||||
begin_end_string_args: [..]*Declaration;
|
||||
|
||||
enums_for_typedefs: Table(string, *Enum);
|
||||
|
||||
imgui_visitor :: (decl: *Declaration, parent_decl: *Declaration) -> Declaration_Visit_Result {
|
||||
get_associated_enum_name :: (name: string) -> string {
|
||||
if name.count > 1 && name[name.count - 1] != #char "_" {
|
||||
return tprint("%_", name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
if !parent_decl {
|
||||
if array_find(DECLARATIONS_TO_OMIT, decl.name) {
|
||||
decl.decl_flags |= .OMIT_FROM_OUTPUT;
|
||||
return .STOP;
|
||||
}
|
||||
if decl.name == "ImGuiContext" {
|
||||
decl.output_name = decl.name;
|
||||
}
|
||||
|
||||
if decl.kind == .TYPEDEF {
|
||||
old_name := decl.name;
|
||||
if old_name {
|
||||
new_name := get_associated_enum_name(old_name);
|
||||
for context.generator.global_scope.members {
|
||||
if it.kind != .ENUM || it.name != new_name continue;
|
||||
|
||||
en := cast(*Enum)it;
|
||||
decl.decl_flags |= .OMIT_FROM_OUTPUT;
|
||||
|
||||
if en.output_name.count > 2 && en.output_name[en.output_name.count - 1] == #char "_" {
|
||||
en.output_name.count -= 1;
|
||||
}
|
||||
|
||||
if decl.comment.text && !en.comment.text {
|
||||
en.comment = decl.comment;
|
||||
}
|
||||
|
||||
table_add(*enums_for_typedefs, old_name, en);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if parent_decl &&
|
||||
(parent_decl.kind == .FUNCTION || parent_decl.kind == .STRUCT) &&
|
||||
decl.kind == .DECLARATION && decl.type.type_of_typedef != null
|
||||
{
|
||||
old_name := decl.type.type_of_typedef.name;
|
||||
if old_name {
|
||||
found, en := table_find(*enums_for_typedefs, old_name);
|
||||
if found {
|
||||
change_type_to_enum(decl, en);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if decl.kind == .ENUM {
|
||||
if ends_with(decl.name, "Flags_") {
|
||||
en := cast(*Enum)decl;
|
||||
en.flags |= .IS_ENUM_FLAGS;
|
||||
en.flags |= .VALUES_IN_HEX;
|
||||
}
|
||||
}
|
||||
|
||||
if decl.kind == .FUNCTION {
|
||||
func := cast(*Function)decl;
|
||||
type := func.type.type_of_function;
|
||||
for type.arguments {
|
||||
if it_index == 0 || !ends_with(it.name, "_end") continue;
|
||||
arg_type := find_underlying_type(it.type);
|
||||
if !arg_type.pointer_to || !(arg_type.pointer_to.number_flags & ._8BIT) continue;
|
||||
|
||||
name_part := slice(it.name, 0, it.name.count - "_end".count);
|
||||
if !name_part continue;
|
||||
|
||||
name_part_with_begin := tprint("%_begin", name_part);
|
||||
prev_arg := type.arguments[it_index - 1];
|
||||
if prev_arg.name == name_part || prev_arg.name == name_part_with_begin {
|
||||
array_add(*begin_end_string_args, prev_arg);
|
||||
func.decl_flags |= .NEEDS_ARGUMENT_WRAPPER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return .RECURSE;
|
||||
}
|
||||
|
||||
imgui_get_function_arg_for_printing :: (func: *Function, type: *Function_Type, mode: Arg_Print_Mode) -> []*Declaration {
|
||||
args: [..]*Declaration;
|
||||
for type.arguments {
|
||||
if array_find(begin_end_string_args, it) {
|
||||
if mode == {
|
||||
case .OUTER_WRAPPER;
|
||||
arg_copy := New(Declaration);
|
||||
(arg_copy.*) = it.*;
|
||||
arg_copy.type = context.generator.type_def_jai_string;
|
||||
if ends_with(it.name, "_begin") {
|
||||
arg_copy.output_name = slice(it.name, 0, it.name.count - "_begin".count);
|
||||
}
|
||||
array_add(*args, arg_copy);
|
||||
it_index += 1;
|
||||
continue;
|
||||
case .INNER_WRAPPER_CALL;
|
||||
base_arg_name := it.name;
|
||||
if ends_with(it.name, "_begin") {
|
||||
base_arg_name = slice(it.name, 0, it.name.count - "_begin".count);
|
||||
}
|
||||
|
||||
arg_copy := New(Declaration);
|
||||
(arg_copy.*) = it.*;
|
||||
arg_copy.output_name = tprint("%.data", base_arg_name);
|
||||
array_add(*args, arg_copy);
|
||||
|
||||
arg_copy_2 := New(Declaration);
|
||||
(arg_copy_2.*) = it.*;
|
||||
arg_copy_2.output_name = tprint("%.data + %.count", base_arg_name, base_arg_name);
|
||||
array_add(*args, arg_copy_2);
|
||||
|
||||
it_index += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
array_add(*args, it);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
#import "Basic";
|
||||
#import "Bindings_Generator";
|
||||
#import "BuildCpp";
|
||||
#import "Compiler";
|
||||
#import "File";
|
||||
#import "Hash_Table";
|
||||
#import "String";
|
||||
Reference in New Issue
Block a user