From 7933a6cc9fcf2b54e19be6b5b18874069a05331b Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Tue, 5 Jun 2018 22:14:32 +0200 Subject: Mono: Null checks when marshaling from MonoArray* and managed Dictionary --- modules/mono/mono_gd/gd_mono_marshal.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'modules/mono') diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index e6baea3089..c04fcca962 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -606,6 +606,8 @@ MonoArray *Array_to_mono_array(const Array &p_array) { Array mono_array_to_Array(MonoArray *p_array) { Array ret; + if (!p_array) + return ret; int length = mono_array_length(p_array); ret.resize(length); @@ -631,6 +633,8 @@ MonoArray *PoolIntArray_to_mono_array(const PoolIntArray &p_array) { PoolIntArray mono_array_to_PoolIntArray(MonoArray *p_array) { PoolIntArray ret; + if (!p_array) + return ret; int length = mono_array_length(p_array); ret.resize(length); for (int i = 0; i < length; i++) { @@ -653,6 +657,8 @@ MonoArray *PoolByteArray_to_mono_array(const PoolByteArray &p_array) { PoolByteArray mono_array_to_PoolByteArray(MonoArray *p_array) { PoolByteArray ret; + if (!p_array) + return ret; int length = mono_array_length(p_array); ret.resize(length); @@ -676,6 +682,8 @@ MonoArray *PoolRealArray_to_mono_array(const PoolRealArray &p_array) { PoolRealArray mono_array_to_PoolRealArray(MonoArray *p_array) { PoolRealArray ret; + if (!p_array) + return ret; int length = mono_array_length(p_array); ret.resize(length); @@ -700,6 +708,8 @@ MonoArray *PoolStringArray_to_mono_array(const PoolStringArray &p_array) { PoolStringArray mono_array_to_PoolStringArray(MonoArray *p_array) { PoolStringArray ret; + if (!p_array) + return ret; int length = mono_array_length(p_array); ret.resize(length); @@ -732,6 +742,8 @@ MonoArray *PoolColorArray_to_mono_array(const PoolColorArray &p_array) { PoolColorArray mono_array_to_PoolColorArray(MonoArray *p_array) { PoolColorArray ret; + if (!p_array) + return ret; int length = mono_array_length(p_array); ret.resize(length); @@ -763,6 +775,8 @@ MonoArray *PoolVector2Array_to_mono_array(const PoolVector2Array &p_array) { PoolVector2Array mono_array_to_PoolVector2Array(MonoArray *p_array) { PoolVector2Array ret; + if (!p_array) + return ret; int length = mono_array_length(p_array); ret.resize(length); @@ -795,6 +809,8 @@ MonoArray *PoolVector3Array_to_mono_array(const PoolVector3Array &p_array) { PoolVector3Array mono_array_to_PoolVector3Array(MonoArray *p_array) { PoolVector3Array ret; + if (!p_array) + return ret; int length = mono_array_length(p_array); ret.resize(length); @@ -835,6 +851,9 @@ MonoObject *Dictionary_to_mono_object(const Dictionary &p_dict) { Dictionary mono_object_to_Dictionary(MonoObject *p_dict) { Dictionary ret; + if (!p_dict) + return ret; + GDMonoUtils::MarshalUtils_DictToArrays dict_to_arrays = CACHED_METHOD_THUNK(MarshalUtils, DictionaryToArrays); MonoArray *keys = NULL; -- cgit v1.2.3 From 25f10b3c406761b0bb88bf70da1ba2d8f5335fbd Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Tue, 5 Jun 2018 22:18:43 +0200 Subject: Mono: Fix passing wrong logger assembly path to MSBuild - Add option to print MSBuild's stdout and stderr instead of redirecting it. This can be enabled by setting the environment variable: Godot_DEBUG_MSBUILD=1 --- .../editor/GodotSharpTools/Build/BuildSystem.cs | 37 ++++++++++++++++------ modules/mono/editor/godotsharp_builds.cpp | 5 +-- 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'modules/mono') diff --git a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs index f3b4b66663..a5dd37b5dc 100644 --- a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs +++ b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs @@ -78,6 +78,8 @@ namespace GodotSharpTools.Build public bool Build(string loggerAssemblyPath, string loggerOutputDir, string[] customProperties = null) { + bool debugMSBuild = IsDebugMSBuildRequested(); + List customPropertiesList = new List(); if (customProperties != null) @@ -92,9 +94,10 @@ namespace GodotSharpTools.Build ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); - // No console output, thanks - startInfo.RedirectStandardOutput = true; - startInfo.RedirectStandardError = true; + bool redirectOutput = !debugMSBuild; + + startInfo.RedirectStandardOutput = redirectOutput; + startInfo.RedirectStandardError = redirectOutput; startInfo.UseShellExecute = false; if (UsingMonoMSBuildOnWindows) @@ -116,8 +119,11 @@ namespace GodotSharpTools.Build process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); + if (redirectOutput) + { + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + } process.WaitForExit(); @@ -129,6 +135,8 @@ namespace GodotSharpTools.Build public bool BuildAsync(string loggerAssemblyPath, string loggerOutputDir, string[] customProperties = null) { + bool debugMSBuild = IsDebugMSBuildRequested(); + if (process != null) throw new InvalidOperationException("Already in use"); @@ -146,9 +154,10 @@ namespace GodotSharpTools.Build ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); - // No console output, thanks - startInfo.RedirectStandardOutput = true; - startInfo.RedirectStandardError = true; + bool redirectOutput = !debugMSBuild; + + startInfo.RedirectStandardOutput = redirectOutput; + startInfo.RedirectStandardError = redirectOutput; startInfo.UseShellExecute = false; if (UsingMonoMSBuildOnWindows) @@ -171,8 +180,11 @@ namespace GodotSharpTools.Build process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); + if (redirectOutput) + { + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + } return true; } @@ -220,6 +232,11 @@ namespace GodotSharpTools.Build Dispose(); } + private static bool IsDebugMSBuildRequested() + { + return Environment.GetEnvironmentVariable("GODOT_DEBUG_MSBUILD").Trim() == "1"; + } + public void Dispose() { if (process != null) diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index e29384aabf..3adfc62d73 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -527,8 +527,9 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { // Call Build - Variant logger_assembly = OS::get_singleton()->get_executable_path().get_base_dir().plus_file(EDITOR_TOOLS_ASSEMBLY_NAME) + ".dll"; - Variant logger_output_dir = logs_dir; + String logger_assembly_path = GDMono::get_singleton()->get_editor_tools_assembly()->get_path(); + Variant logger_assembly = ProjectSettings::get_singleton()->globalize_path(logger_assembly_path); + Variant logger_output_dir = log_dirpath; Variant custom_props = build_info.custom_props; const Variant *args[3] = { &logger_assembly, &logger_output_dir, &custom_props }; -- cgit v1.2.3 From 4a021fa7a2fdafe4d8aaced8652fa0c72a2a7b08 Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Tue, 5 Jun 2018 22:21:52 +0200 Subject: Mono: Add 'View log' button to open the MSBuild log of a build --- modules/mono/editor/godotsharp_builds.cpp | 8 ++-- modules/mono/editor/mono_bottom_panel.cpp | 60 +++++++++++++++++++++++------- modules/mono/editor/mono_bottom_panel.h | 6 ++- modules/mono/editor/mono_build_info.cpp | 62 +++++++++++++++++++++++++++++++ modules/mono/editor/mono_build_info.h | 24 ++++-------- 5 files changed, 123 insertions(+), 37 deletions(-) create mode 100644 modules/mono/editor/mono_build_info.cpp (limited to 'modules/mono') diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index 3adfc62d73..43d58caad2 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -461,12 +461,12 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { exit_code = -1; - String logs_dir = GodotSharpDirs::get_build_logs_dir().plus_file(build_info.solution.md5_text() + "_" + build_info.configuration); + String log_dirpath = build_info.get_log_dirpath(); if (build_tab) { build_tab->on_build_start(); } else { - build_tab = memnew(MonoBuildTab(build_info, logs_dir)); + build_tab = memnew(MonoBuildTab(build_info, log_dirpath)); MonoBottomPanel::get_singleton()->add_build_tab(build_tab); } @@ -488,12 +488,12 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { // Remove old issues file String issues_file = "msbuild_issues.csv"; - DirAccessRef d = DirAccess::create_for_path(logs_dir); + DirAccessRef d = DirAccess::create_for_path(log_dirpath); if (d->file_exists(issues_file)) { Error err = d->remove(issues_file); if (err != OK) { exited = true; - String file_path = ProjectSettings::get_singleton()->localize_path(logs_dir).plus_file(issues_file); + String file_path = ProjectSettings::get_singleton()->localize_path(log_dirpath).plus_file(issues_file); String message = "Cannot remove issues file: " + file_path; build_tab->on_build_exec_failed(message); ERR_EXPLAIN(message); diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp index 1b5a303835..9317550d28 100644 --- a/modules/mono/editor/mono_bottom_panel.cpp +++ b/modules/mono/editor/mono_bottom_panel.cpp @@ -73,7 +73,7 @@ void MonoBottomPanel::_update_build_tabs_list() { if (no_current_tab || current_tab == i) { build_tabs_list->select(i); - _build_tab_item_selected(i); + _build_tabs_item_selected(i); } } } @@ -105,21 +105,27 @@ void MonoBottomPanel::show_build_tab() { ERR_PRINT("Builds tab not found"); } -void MonoBottomPanel::_build_tab_item_selected(int p_idx) { +void MonoBottomPanel::_build_tabs_item_selected(int p_idx) { ERR_FAIL_INDEX(p_idx, build_tabs->get_tab_count()); + build_tabs->set_current_tab(p_idx); + if (!build_tabs->is_visible()) + build_tabs->set_visible(true); + + warnings_btn->set_visible(true); + errors_btn->set_visible(true); + view_log_btn->set_visible(true); } -void MonoBottomPanel::_build_tab_changed(int p_idx) { +void MonoBottomPanel::_build_tabs_nothing_selected() { - if (p_idx < 0 || p_idx >= build_tabs->get_tab_count()) { - warnings_btn->set_visible(false); - errors_btn->set_visible(false); - } else { - warnings_btn->set_visible(true); - errors_btn->set_visible(true); - } + if (build_tabs->get_tab_count() != 0) // just in case + build_tabs->set_visible(false); + + warnings_btn->set_visible(false); + errors_btn->set_visible(false); + view_log_btn->set_visible(false); } void MonoBottomPanel::_warnings_toggled(bool p_pressed) { @@ -148,6 +154,22 @@ void MonoBottomPanel::_build_project_pressed() { CSharpLanguage::get_singleton()->reload_assemblies_if_needed(true); } +void MonoBottomPanel::_view_log_pressed() { + + if (build_tabs_list->is_anything_selected()) { + Vector selected_items = build_tabs_list->get_selected_items(); + CRASH_COND(selected_items.size() != 1); + int selected_item = selected_items[0]; + + MonoBuildTab *build_tab = Object::cast_to(build_tabs->get_tab_control(selected_item)); + ERR_FAIL_NULL(build_tab); + + String log_dirpath = build_tab->get_build_info().get_log_dirpath(); + + OS::get_singleton()->shell_open(log_dirpath.plus_file("msbuild_log.txt")); + } +} + void MonoBottomPanel::_notification(int p_what) { switch (p_what) { @@ -163,10 +185,11 @@ void MonoBottomPanel::_notification(int p_what) { void MonoBottomPanel::_bind_methods() { ClassDB::bind_method(D_METHOD("_build_project_pressed"), &MonoBottomPanel::_build_project_pressed); + ClassDB::bind_method(D_METHOD("_view_log_pressed"), &MonoBottomPanel::_view_log_pressed); ClassDB::bind_method(D_METHOD("_warnings_toggled", "pressed"), &MonoBottomPanel::_warnings_toggled); ClassDB::bind_method(D_METHOD("_errors_toggled", "pressed"), &MonoBottomPanel::_errors_toggled); - ClassDB::bind_method(D_METHOD("_build_tab_item_selected", "idx"), &MonoBottomPanel::_build_tab_item_selected); - ClassDB::bind_method(D_METHOD("_build_tab_changed", "idx"), &MonoBottomPanel::_build_tab_changed); + ClassDB::bind_method(D_METHOD("_build_tabs_item_selected", "idx"), &MonoBottomPanel::_build_tabs_item_selected); + ClassDB::bind_method(D_METHOD("_build_tabs_nothing_selected"), &MonoBottomPanel::_build_tabs_nothing_selected); } MonoBottomPanel::MonoBottomPanel(EditorNode *p_editor) { @@ -223,6 +246,15 @@ MonoBottomPanel::MonoBottomPanel(EditorNode *p_editor) { errors_btn->connect("toggled", this, "_errors_toggled"); toolbar_hbc->add_child(errors_btn); + toolbar_hbc->add_spacer(); + + view_log_btn = memnew(Button); + view_log_btn->set_text(TTR("View log")); + view_log_btn->set_focus_mode(FOCUS_NONE); + view_log_btn->set_visible(false); + view_log_btn->connect("pressed", this, "_view_log_pressed"); + toolbar_hbc->add_child(view_log_btn); + HSplitContainer *hsc = memnew(HSplitContainer); hsc->set_h_size_flags(SIZE_EXPAND_FILL); hsc->set_v_size_flags(SIZE_EXPAND_FILL); @@ -230,14 +262,14 @@ MonoBottomPanel::MonoBottomPanel(EditorNode *p_editor) { build_tabs_list = memnew(ItemList); build_tabs_list->set_h_size_flags(SIZE_EXPAND_FILL); - build_tabs_list->connect("item_selected", this, "_build_tab_item_selected"); + build_tabs_list->connect("item_selected", this, "_build_tabs_item_selected"); + build_tabs_list->connect("nothing_selected", this, "_build_tabs_nothing_selected"); hsc->add_child(build_tabs_list); build_tabs = memnew(TabContainer); build_tabs->set_tab_align(TabContainer::ALIGN_LEFT); build_tabs->set_h_size_flags(SIZE_EXPAND_FILL); build_tabs->set_tabs_visible(false); - build_tabs->connect("tab_changed", this, "_build_tab_changed"); hsc->add_child(build_tabs); } } diff --git a/modules/mono/editor/mono_bottom_panel.h b/modules/mono/editor/mono_bottom_panel.h index a44d3a9af8..03240e9a13 100644 --- a/modules/mono/editor/mono_bottom_panel.h +++ b/modules/mono/editor/mono_bottom_panel.h @@ -53,16 +53,18 @@ class MonoBottomPanel : public VBoxContainer { Button *warnings_btn; Button *errors_btn; + Button *view_log_btn; void _update_build_tabs_list(); - void _build_tab_item_selected(int p_idx); - void _build_tab_changed(int p_idx); + void _build_tabs_item_selected(int p_idx); + void _build_tabs_nothing_selected(); void _warnings_toggled(bool p_pressed); void _errors_toggled(bool p_pressed); void _build_project_pressed(); + void _view_log_pressed(); static MonoBottomPanel *singleton; diff --git a/modules/mono/editor/mono_build_info.cpp b/modules/mono/editor/mono_build_info.cpp new file mode 100644 index 0000000000..e4af2aac4f --- /dev/null +++ b/modules/mono/editor/mono_build_info.cpp @@ -0,0 +1,62 @@ +/*************************************************************************/ +/* mono_build_info.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "mono_build_info.h" + +#include "../godotsharp_dirs.h" +#include "../mono_gd/gd_mono_utils.h" + +uint32_t MonoBuildInfo::Hasher::hash(const MonoBuildInfo &p_key) { + + uint32_t hash = 0; + + GDMonoUtils::hash_combine(hash, p_key.solution.hash()); + GDMonoUtils::hash_combine(hash, p_key.configuration.hash()); + + return hash; +} + +bool MonoBuildInfo::operator==(const MonoBuildInfo &p_b) const { + + return p_b.solution == solution && p_b.configuration == configuration; +} + +String MonoBuildInfo::get_log_dirpath() { + + return GodotSharpDirs::get_build_logs_dir().plus_file(solution.md5_text() + "_" + configuration); +} + +MonoBuildInfo::MonoBuildInfo() {} + +MonoBuildInfo::MonoBuildInfo(const String &p_solution, const String &p_config) { + + solution = p_solution; + configuration = p_config; +} diff --git a/modules/mono/editor/mono_build_info.h b/modules/mono/editor/mono_build_info.h index 4806764a61..64ba0f4037 100644 --- a/modules/mono/editor/mono_build_info.h +++ b/modules/mono/editor/mono_build_info.h @@ -31,35 +31,25 @@ #ifndef MONO_BUILD_INFO_H #define MONO_BUILD_INFO_H -#include "../mono_gd/gd_mono_utils.h" +#include "core/ustring.h" +#include "core/vector.h" struct MonoBuildInfo { struct Hasher { - static _FORCE_INLINE_ uint32_t hash(const MonoBuildInfo &p_key) { - uint32_t hash = 0; - - GDMonoUtils::hash_combine(hash, p_key.solution.hash()); - GDMonoUtils::hash_combine(hash, p_key.configuration.hash()); - - return hash; - } + static uint32_t hash(const MonoBuildInfo &p_key); }; String solution; String configuration; Vector custom_props; - MonoBuildInfo() {} + bool operator==(const MonoBuildInfo &p_b) const; - MonoBuildInfo(const String &p_solution, const String &p_config) { - solution = p_solution; - configuration = p_config; - } + String get_log_dirpath(); - bool operator==(const MonoBuildInfo &p_b) const { - return p_b.solution == solution && p_b.configuration == configuration; - } + MonoBuildInfo(); + MonoBuildInfo(const String &p_solution, const String &p_config); }; #endif // MONO_BUILD_INFO_H -- cgit v1.2.3