mirror of
https://github.com/godotengine/godot.git
synced 2025-10-31 21:51:22 +00:00
C# bindings generator cleanup
- Normal log messages are no longer warnings. - BindingsGenerator is no longer a singleton. - Added a log function.
This commit is contained in:
parent
bf1fe11143
commit
c20a3823a2
7 changed files with 139 additions and 108 deletions
|
|
@ -131,14 +131,6 @@ void CSharpLanguage::finish() {
|
||||||
|
|
||||||
finalizing = true;
|
finalizing = true;
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
|
||||||
// Must be here, to avoid StringName leaks
|
|
||||||
if (BindingsGenerator::singleton) {
|
|
||||||
memdelete(BindingsGenerator::singleton);
|
|
||||||
BindingsGenerator::singleton = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Make sure all script binding gchandles are released before finalizing GDMono
|
// Make sure all script binding gchandles are released before finalizing GDMono
|
||||||
for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) {
|
for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) {
|
||||||
CSharpScriptBinding &script_binding = E->value();
|
CSharpScriptBinding &script_binding = E->value();
|
||||||
|
|
|
||||||
|
|
@ -101,10 +101,6 @@
|
||||||
|
|
||||||
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN("\t%0 %1_in = %1;\n");
|
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN("\t%0 %1_in = %1;\n");
|
||||||
|
|
||||||
bool BindingsGenerator::verbose_output = false;
|
|
||||||
|
|
||||||
BindingsGenerator *BindingsGenerator::singleton = NULL;
|
|
||||||
|
|
||||||
static String fix_doc_description(const String &p_bbcode) {
|
static String fix_doc_description(const String &p_bbcode) {
|
||||||
|
|
||||||
// This seems to be the correct way to do this. It's the same EditorHelp does.
|
// This seems to be the correct way to do this. It's the same EditorHelp does.
|
||||||
|
|
@ -816,9 +812,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
|
||||||
|
|
||||||
CRASH_COND(enum_class_name != "Variant"); // Hard-coded...
|
CRASH_COND(enum_class_name != "Variant"); // Hard-coded...
|
||||||
|
|
||||||
if (verbose_output) {
|
_log("Declaring global enum `%s` inside static class `%s`\n", enum_proxy_name.utf8().get_data(), enum_class_name.utf8().get_data());
|
||||||
WARN_PRINTS("Declaring global enum `" + enum_proxy_name + "` inside static class `" + enum_class_name + "`");
|
|
||||||
}
|
|
||||||
|
|
||||||
p_output.append("\n" INDENT1 "public static partial class ");
|
p_output.append("\n" INDENT1 "public static partial class ");
|
||||||
p_output.append(enum_class_name);
|
p_output.append(enum_class_name);
|
||||||
|
|
@ -867,9 +861,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
|
||||||
p_output.append("\n#pragma warning restore CS1591\n");
|
p_output.append("\n#pragma warning restore CS1591\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Error BindingsGenerator::generate_cs_core_project(const String &p_solution_dir, DotNetSolution &r_solution, bool p_verbose_output) {
|
Error BindingsGenerator::generate_cs_core_project(const String &p_solution_dir, DotNetSolution &r_solution) {
|
||||||
|
|
||||||
verbose_output = p_verbose_output;
|
|
||||||
|
|
||||||
String proj_dir = p_solution_dir.plus_file(CORE_API_ASSEMBLY_NAME);
|
String proj_dir = p_solution_dir.plus_file(CORE_API_ASSEMBLY_NAME);
|
||||||
|
|
||||||
|
|
@ -1001,15 +993,12 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_solution_dir,
|
||||||
|
|
||||||
r_solution.add_new_project(CORE_API_ASSEMBLY_NAME, proj_info);
|
r_solution.add_new_project(CORE_API_ASSEMBLY_NAME, proj_info);
|
||||||
|
|
||||||
if (verbose_output)
|
_log("The solution and C# project for the Core API was generated successfully\n");
|
||||||
OS::get_singleton()->print("The solution and C# project for the Core API was generated successfully\n");
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error BindingsGenerator::generate_cs_editor_project(const String &p_solution_dir, DotNetSolution &r_solution, bool p_verbose_output) {
|
Error BindingsGenerator::generate_cs_editor_project(const String &p_solution_dir, DotNetSolution &r_solution) {
|
||||||
|
|
||||||
verbose_output = p_verbose_output;
|
|
||||||
|
|
||||||
String proj_dir = p_solution_dir.plus_file(EDITOR_API_ASSEMBLY_NAME);
|
String proj_dir = p_solution_dir.plus_file(EDITOR_API_ASSEMBLY_NAME);
|
||||||
|
|
||||||
|
|
@ -1100,13 +1089,12 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_solution_dir
|
||||||
|
|
||||||
r_solution.add_new_project(EDITOR_API_ASSEMBLY_NAME, proj_info);
|
r_solution.add_new_project(EDITOR_API_ASSEMBLY_NAME, proj_info);
|
||||||
|
|
||||||
if (verbose_output)
|
_log("The solution and C# project for the Editor API was generated successfully\n");
|
||||||
OS::get_singleton()->print("The solution and C# project for the Editor API was generated successfully\n");
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error BindingsGenerator::generate_cs_api(const String &p_output_dir, bool p_verbose_output) {
|
Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
|
||||||
|
|
||||||
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||||
ERR_FAIL_COND_V(!da, ERR_CANT_CREATE);
|
ERR_FAIL_COND_V(!da, ERR_CANT_CREATE);
|
||||||
|
|
@ -1123,13 +1111,13 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir, bool p_verb
|
||||||
|
|
||||||
Error proj_err;
|
Error proj_err;
|
||||||
|
|
||||||
proj_err = generate_cs_core_project(p_output_dir, solution, p_verbose_output);
|
proj_err = generate_cs_core_project(p_output_dir, solution);
|
||||||
if (proj_err != OK) {
|
if (proj_err != OK) {
|
||||||
ERR_PRINT("Generation of the Core API C# project failed");
|
ERR_PRINT("Generation of the Core API C# project failed");
|
||||||
return proj_err;
|
return proj_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
proj_err = generate_cs_editor_project(p_output_dir, solution, p_verbose_output);
|
proj_err = generate_cs_editor_project(p_output_dir, solution);
|
||||||
if (proj_err != OK) {
|
if (proj_err != OK) {
|
||||||
ERR_PRINT("Generation of the Editor API C# project failed");
|
ERR_PRINT("Generation of the Editor API C# project failed");
|
||||||
return proj_err;
|
return proj_err;
|
||||||
|
|
@ -1168,8 +1156,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
|
||||||
|
|
||||||
List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls;
|
List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls;
|
||||||
|
|
||||||
if (verbose_output)
|
_log("Generating %s.cs...\n", itype.proxy_name.utf8().get_data());
|
||||||
OS::get_singleton()->print("Generating %s.cs...\n", itype.proxy_name.utf8().get_data());
|
|
||||||
|
|
||||||
String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor"); // Used only for derived types
|
String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor"); // Used only for derived types
|
||||||
|
|
||||||
|
|
@ -1710,8 +1697,6 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
|
||||||
|
|
||||||
Error BindingsGenerator::generate_glue(const String &p_output_dir) {
|
Error BindingsGenerator::generate_glue(const String &p_output_dir) {
|
||||||
|
|
||||||
verbose_output = true;
|
|
||||||
|
|
||||||
bool dir_exists = DirAccess::exists(p_output_dir);
|
bool dir_exists = DirAccess::exists(p_output_dir);
|
||||||
ERR_EXPLAIN("The output directory does not exist.");
|
ERR_EXPLAIN("The output directory does not exist.");
|
||||||
ERR_FAIL_COND_V(!dir_exists, ERR_FILE_BAD_PATH);
|
ERR_FAIL_COND_V(!dir_exists, ERR_FILE_BAD_PATH);
|
||||||
|
|
@ -2128,15 +2113,13 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ClassDB::is_class_exposed(type_cname)) {
|
if (!ClassDB::is_class_exposed(type_cname)) {
|
||||||
if (verbose_output)
|
_log("Ignoring type `%s` because it's not exposed\n", String(type_cname).utf8().get_data());
|
||||||
WARN_PRINTS("Ignoring type " + type_cname.operator String() + " because it's not exposed");
|
|
||||||
class_list.pop_front();
|
class_list.pop_front();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ClassDB::is_class_enabled(type_cname)) {
|
if (!ClassDB::is_class_enabled(type_cname)) {
|
||||||
if (verbose_output)
|
_log("Ignoring type `%s` because it's not enabled\n", String(type_cname).utf8().get_data());
|
||||||
WARN_PRINTS("Ignoring type " + type_cname.operator String() + " because it's not enabled");
|
|
||||||
class_list.pop_front();
|
class_list.pop_front();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -2186,12 +2169,10 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
|
|
||||||
iprop.proxy_name = escape_csharp_keyword(snake_to_pascal_case(iprop.cname));
|
iprop.proxy_name = escape_csharp_keyword(snake_to_pascal_case(iprop.cname));
|
||||||
|
|
||||||
// Prevent property and enclosing type from sharing the same name
|
// Prevent the property and its enclosing type from sharing the same name
|
||||||
if (iprop.proxy_name == itype.proxy_name) {
|
if (iprop.proxy_name == itype.proxy_name) {
|
||||||
if (verbose_output) {
|
_log("Name of property `%s` is ambiguous with the name of its enclosing class `%s`. Renaming property to `%s_`\n",
|
||||||
WARN_PRINTS("Name of property `" + iprop.proxy_name + "` is ambiguous with the name of its class `" +
|
iprop.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), iprop.proxy_name.utf8().get_data());
|
||||||
itype.proxy_name + "`. Renaming property to `" + iprop.proxy_name + "_`");
|
|
||||||
}
|
|
||||||
|
|
||||||
iprop.proxy_name += "_";
|
iprop.proxy_name += "_";
|
||||||
}
|
}
|
||||||
|
|
@ -2258,14 +2239,13 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
// which could actually will return something different.
|
// which could actually will return something different.
|
||||||
// Let's put this to notify us if that ever happens.
|
// Let's put this to notify us if that ever happens.
|
||||||
if (itype.cname != name_cache.type_Object || imethod.name != "free") {
|
if (itype.cname != name_cache.type_Object || imethod.name != "free") {
|
||||||
if (verbose_output) {
|
ERR_PRINTS("Notification: New unexpected virtual non-overridable method found.\n"
|
||||||
WARN_PRINTS("Notification: New unexpected virtual non-overridable method found.\n"
|
|
||||||
"We only expected Object.free, but found " +
|
"We only expected Object.free, but found " +
|
||||||
itype.name + "." + imethod.name);
|
itype.name + "." + imethod.name);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ERR_PRINTS("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name);
|
ERR_EXPLAIN("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name);
|
||||||
|
ERR_FAIL();
|
||||||
}
|
}
|
||||||
} else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
} else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||||
imethod.return_type.cname = return_info.class_name;
|
imethod.return_type.cname = return_info.class_name;
|
||||||
|
|
@ -2319,12 +2299,10 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
|
|
||||||
imethod.proxy_name = escape_csharp_keyword(snake_to_pascal_case(imethod.name));
|
imethod.proxy_name = escape_csharp_keyword(snake_to_pascal_case(imethod.name));
|
||||||
|
|
||||||
// Prevent naming the property and its enclosing type from sharing the same name
|
// Prevent the method and its enclosing type from sharing the same name
|
||||||
if (imethod.proxy_name == itype.proxy_name) {
|
if (imethod.proxy_name == itype.proxy_name) {
|
||||||
if (verbose_output) {
|
_log("Name of method `%s` is ambiguous with the name of its enclosing class `%s`. Renaming method to `%s_`\n",
|
||||||
WARN_PRINTS("Name of method `" + imethod.proxy_name + "` is ambiguous with the name of its class `" +
|
imethod.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), imethod.proxy_name.utf8().get_data());
|
||||||
itype.proxy_name + "`. Renaming method to `" + imethod.proxy_name + "_`");
|
|
||||||
}
|
|
||||||
|
|
||||||
imethod.proxy_name += "_";
|
imethod.proxy_name += "_";
|
||||||
}
|
}
|
||||||
|
|
@ -2858,7 +2836,18 @@ void BindingsGenerator::_populate_global_constants() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindingsGenerator::initialize() {
|
void BindingsGenerator::_log(const char *p_format, ...) {
|
||||||
|
|
||||||
|
if (log_print_enabled) {
|
||||||
|
va_list list;
|
||||||
|
|
||||||
|
va_start(list, p_format);
|
||||||
|
OS::get_singleton()->print("%s", str_format(p_format, list).utf8().get_data());
|
||||||
|
va_end(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingsGenerator::_initialize() {
|
||||||
|
|
||||||
EditorHelp::generate_doc();
|
EditorHelp::generate_doc();
|
||||||
|
|
||||||
|
|
@ -2881,12 +2870,13 @@ void BindingsGenerator::initialize() {
|
||||||
void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) {
|
void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) {
|
||||||
|
|
||||||
const int NUM_OPTIONS = 2;
|
const int NUM_OPTIONS = 2;
|
||||||
int options_left = NUM_OPTIONS;
|
|
||||||
|
|
||||||
String mono_glue_option = "--generate-mono-glue";
|
String mono_glue_option = "--generate-mono-glue";
|
||||||
String cs_api_option = "--generate-cs-api";
|
String cs_api_option = "--generate-cs-api";
|
||||||
|
|
||||||
verbose_output = true;
|
String mono_glue_path;
|
||||||
|
String cs_api_path;
|
||||||
|
|
||||||
|
int options_left = NUM_OPTIONS;
|
||||||
|
|
||||||
const List<String>::Element *elem = p_cmdline_args.front();
|
const List<String>::Element *elem = p_cmdline_args.front();
|
||||||
|
|
||||||
|
|
@ -2895,8 +2885,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
|
||||||
const List<String>::Element *path_elem = elem->next();
|
const List<String>::Element *path_elem = elem->next();
|
||||||
|
|
||||||
if (path_elem) {
|
if (path_elem) {
|
||||||
if (get_singleton()->generate_glue(path_elem->get()) != OK)
|
mono_glue_path = path_elem->get();
|
||||||
ERR_PRINTS(mono_glue_option + ": Failed to generate mono glue");
|
|
||||||
elem = elem->next();
|
elem = elem->next();
|
||||||
} else {
|
} else {
|
||||||
ERR_PRINTS(mono_glue_option + ": No output directory specified");
|
ERR_PRINTS(mono_glue_option + ": No output directory specified");
|
||||||
|
|
@ -2907,8 +2896,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
|
||||||
const List<String>::Element *path_elem = elem->next();
|
const List<String>::Element *path_elem = elem->next();
|
||||||
|
|
||||||
if (path_elem) {
|
if (path_elem) {
|
||||||
if (get_singleton()->generate_cs_api(path_elem->get()) != OK)
|
cs_api_path = path_elem->get();
|
||||||
ERR_PRINTS(cs_api_option + ": Failed to generate the C# API");
|
|
||||||
elem = elem->next();
|
elem = elem->next();
|
||||||
} else {
|
} else {
|
||||||
ERR_PRINTS(cs_api_option + ": No output directory specified");
|
ERR_PRINTS(cs_api_option + ": No output directory specified");
|
||||||
|
|
@ -2920,10 +2908,23 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
|
||||||
elem = elem->next();
|
elem = elem->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
verbose_output = false;
|
if (mono_glue_path.length() || cs_api_path.length()) {
|
||||||
|
BindingsGenerator bindings_generator;
|
||||||
|
bindings_generator.set_log_print_enabled(true);
|
||||||
|
|
||||||
if (options_left != NUM_OPTIONS)
|
if (mono_glue_path.length()) {
|
||||||
|
if (bindings_generator.generate_glue(mono_glue_path) != OK)
|
||||||
|
ERR_PRINTS(mono_glue_option + ": Failed to generate mono glue");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs_api_path.length()) {
|
||||||
|
if (bindings_generator.generate_cs_api(cs_api_path) != OK)
|
||||||
|
ERR_PRINTS(cs_api_option + ": Failed to generate the C# API");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit once done
|
||||||
::exit(0);
|
::exit(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,6 @@ class BindingsGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodInterface() {
|
MethodInterface() {
|
||||||
return_type.cname = BindingsGenerator::get_singleton()->name_cache.type_void;
|
|
||||||
is_vararg = false;
|
is_vararg = false;
|
||||||
is_virtual = false;
|
is_virtual = false;
|
||||||
requires_object_call = false;
|
requires_object_call = false;
|
||||||
|
|
@ -469,7 +468,7 @@ class BindingsGenerator {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool verbose_output;
|
bool log_print_enabled;
|
||||||
|
|
||||||
OrderedHashMap<StringName, TypeInterface> obj_types;
|
OrderedHashMap<StringName, TypeInterface> obj_types;
|
||||||
|
|
||||||
|
|
@ -515,6 +514,7 @@ class BindingsGenerator {
|
||||||
enum_Error = StaticCString::create("Error");
|
enum_Error = StaticCString::create("Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
NameCache(const NameCache &);
|
NameCache(const NameCache &);
|
||||||
NameCache &operator=(const NameCache &);
|
NameCache &operator=(const NameCache &);
|
||||||
};
|
};
|
||||||
|
|
@ -578,33 +578,26 @@ class BindingsGenerator {
|
||||||
|
|
||||||
Error _save_file(const String &p_path, const StringBuilder &p_content);
|
Error _save_file(const String &p_path, const StringBuilder &p_content);
|
||||||
|
|
||||||
BindingsGenerator() {}
|
void _log(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
|
||||||
|
|
||||||
BindingsGenerator(const BindingsGenerator &);
|
void _initialize();
|
||||||
BindingsGenerator &operator=(const BindingsGenerator &);
|
|
||||||
|
|
||||||
friend class CSharpLanguage;
|
|
||||||
static BindingsGenerator *singleton;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Error generate_cs_core_project(const String &p_solution_dir, DotNetSolution &r_solution, bool p_verbose_output = true);
|
Error generate_cs_core_project(const String &p_solution_dir, DotNetSolution &r_solution);
|
||||||
Error generate_cs_editor_project(const String &p_solution_dir, DotNetSolution &r_solution, bool p_verbose_output = true);
|
Error generate_cs_editor_project(const String &p_solution_dir, DotNetSolution &r_solution);
|
||||||
Error generate_cs_api(const String &p_output_dir, bool p_verbose_output = true);
|
Error generate_cs_api(const String &p_output_dir);
|
||||||
Error generate_glue(const String &p_output_dir);
|
Error generate_glue(const String &p_output_dir);
|
||||||
|
|
||||||
|
void set_log_print_enabled(bool p_enabled) { log_print_enabled = p_enabled; }
|
||||||
|
|
||||||
static uint32_t get_version();
|
static uint32_t get_version();
|
||||||
|
|
||||||
void initialize();
|
|
||||||
|
|
||||||
_FORCE_INLINE_ static BindingsGenerator *get_singleton() {
|
|
||||||
if (!singleton) {
|
|
||||||
singleton = memnew(BindingsGenerator);
|
|
||||||
singleton->initialize();
|
|
||||||
}
|
|
||||||
return singleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_cmdline_args(const List<String> &p_cmdline_args);
|
static void handle_cmdline_args(const List<String> &p_cmdline_args);
|
||||||
|
|
||||||
|
BindingsGenerator() :
|
||||||
|
log_print_enabled(true) {
|
||||||
|
_initialize();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -323,10 +323,13 @@ bool GodotSharpBuilds::make_api_assembly(APIAssembly::Type p_api_type) {
|
||||||
String api_sln_file = api_sln_dir.plus_file(API_SOLUTION_NAME ".sln");
|
String api_sln_file = api_sln_dir.plus_file(API_SOLUTION_NAME ".sln");
|
||||||
|
|
||||||
if (!DirAccess::exists(api_sln_dir) || !FileAccess::exists(api_sln_file)) {
|
if (!DirAccess::exists(api_sln_dir) || !FileAccess::exists(api_sln_file)) {
|
||||||
BindingsGenerator *gen = BindingsGenerator::get_singleton();
|
BindingsGenerator bindings_generator;
|
||||||
bool gen_verbose = OS::get_singleton()->is_stdout_verbose();
|
|
||||||
|
|
||||||
Error err = gen->generate_cs_api(api_sln_dir, gen_verbose);
|
if (!OS::get_singleton()->is_stdout_verbose()) {
|
||||||
|
bindings_generator.set_log_print_enabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error err = bindings_generator.generate_cs_api(api_sln_dir);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
show_build_error_dialog("Failed to generate " API_SOLUTION_NAME " solution. Error: " + itos(err));
|
show_build_error_dialog("Failed to generate " API_SOLUTION_NAME " solution. Error: " + itos(err));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
|
|
||||||
#include "../godotsharp_dirs.h"
|
#include "../godotsharp_dirs.h"
|
||||||
|
#include "../utils/string_utils.h"
|
||||||
|
|
||||||
static int log_level_get_id(const char *p_log_level) {
|
static int log_level_get_id(const char *p_log_level) {
|
||||||
|
|
||||||
|
|
@ -125,27 +126,6 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) {
|
||||||
da->list_dir_end();
|
da->list_dir_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static String format(const char *p_fmt, ...) {
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
va_start(args, p_fmt);
|
|
||||||
int len = vsnprintf(NULL, 0, p_fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
len += 1; // for the trailing '/0'
|
|
||||||
|
|
||||||
char *buffer(memnew_arr(char, len));
|
|
||||||
|
|
||||||
va_start(args, p_fmt);
|
|
||||||
vsnprintf(buffer, len, p_fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
String res(buffer);
|
|
||||||
memdelete_arr(buffer);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GDMonoLog::initialize() {
|
void GDMonoLog::initialize() {
|
||||||
|
|
||||||
CharString log_level = OS::get_singleton()->get_environment("GODOT_MONO_LOG_LEVEL").utf8();
|
CharString log_level = OS::get_singleton()->get_environment("GODOT_MONO_LOG_LEVEL").utf8();
|
||||||
|
|
@ -172,7 +152,7 @@ void GDMonoLog::initialize() {
|
||||||
OS::Time time_now = OS::get_singleton()->get_time();
|
OS::Time time_now = OS::get_singleton()->get_time();
|
||||||
int pid = OS::get_singleton()->get_process_id();
|
int pid = OS::get_singleton()->get_process_id();
|
||||||
|
|
||||||
String log_file_name = format("%d_%02d_%02d %02d.%02d.%02d (%d).txt",
|
String log_file_name = str_format("%d_%02d_%02d %02d.%02d.%02d (%d).txt",
|
||||||
date_now.year, date_now.month, date_now.day,
|
date_now.year, date_now.month, date_now.day,
|
||||||
time_now.hour, time_now.min, time_now.sec, pid);
|
time_now.hour, time_now.min, time_now.sec, pid);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@
|
||||||
|
|
||||||
#include "core/os/file_access.h"
|
#include "core/os/file_access.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
int sfind(const String &p_text, int p_from) {
|
int sfind(const String &p_text, int p_from) {
|
||||||
|
|
@ -184,3 +186,50 @@ Error read_all_file_utf8(const String &p_path, String &r_content) {
|
||||||
r_content = source;
|
r_content = source;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move to variadic templates once we upgrade to C++11
|
||||||
|
|
||||||
|
String str_format(const char *p_format, ...) {
|
||||||
|
va_list list;
|
||||||
|
|
||||||
|
va_start(list, p_format);
|
||||||
|
String res = str_format(p_format, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// va_copy was defined in the C99, but not in C++ standards before C++11.
|
||||||
|
// When you compile C++ without --std=c++<XX> option, compilers still define
|
||||||
|
// va_copy, otherwise you have to use the internal version (__va_copy).
|
||||||
|
#if !defined(va_copy)
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define va_copy(d, s) __va_copy((d), (s))
|
||||||
|
#else
|
||||||
|
#define va_copy(d, s) ((d) = (s))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MINGW_ENABLED) || defined(_MSC_VER)
|
||||||
|
#define vsnprintf vsnprintf_s
|
||||||
|
#endif
|
||||||
|
|
||||||
|
String str_format(const char *p_format, va_list p_list) {
|
||||||
|
va_list list;
|
||||||
|
|
||||||
|
va_copy(list, p_list);
|
||||||
|
int len = vsnprintf(NULL, 0, p_format, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
len += 1; // for the trailing '/0'
|
||||||
|
|
||||||
|
char *buffer(memnew_arr(char, len));
|
||||||
|
|
||||||
|
va_copy(list, p_list);
|
||||||
|
vsnprintf(buffer, len, p_format, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
String res(buffer);
|
||||||
|
memdelete_arr(buffer);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@
|
||||||
#include "core/ustring.h"
|
#include "core/ustring.h"
|
||||||
#include "core/variant.h"
|
#include "core/variant.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
String sformat(const String &p_text, const Variant &p1 = Variant(), const Variant &p2 = Variant(), const Variant &p3 = Variant(), const Variant &p4 = Variant(), const Variant &p5 = Variant());
|
String sformat(const String &p_text, const Variant &p1 = Variant(), const Variant &p2 = Variant(), const Variant &p3 = Variant(), const Variant &p4 = Variant(), const Variant &p5 = Variant());
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
|
@ -44,4 +46,15 @@ String escape_csharp_keyword(const String &p_name);
|
||||||
|
|
||||||
Error read_all_file_utf8(const String &p_path, String &r_content);
|
Error read_all_file_utf8(const String &p_path, String &r_content);
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define _PRINTF_FORMAT_ATTRIBUTE_1_0 __attribute__((format(printf, 1, 0)))
|
||||||
|
#define _PRINTF_FORMAT_ATTRIBUTE_1_2 __attribute__((format(printf, 1, 2)))
|
||||||
|
#else
|
||||||
|
#define _PRINTF_FORMAT_ATTRIBUTE_1_0
|
||||||
|
#define _PRINTF_FORMAT_ATTRIBUTE_1_2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
String str_format(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_1_2;
|
||||||
|
String str_format(const char *p_format, va_list p_list) _PRINTF_FORMAT_ATTRIBUTE_1_0;
|
||||||
|
|
||||||
#endif // STRING_FORMAT_H
|
#endif // STRING_FORMAT_H
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue