diff options
-rw-r--r-- | doc/classes/Input.xml | 5 | ||||
-rw-r--r-- | editor/import/editor_scene_importer_gltf.cpp | 21 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 144 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.h | 3 | ||||
-rw-r--r-- | modules/mono/config.py | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 31 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.cpp | 26 | ||||
-rw-r--r-- | platform/javascript/detect.py | 3 | ||||
-rw-r--r-- | platform/osx/os_osx.h | 1 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 49 | ||||
-rw-r--r-- | scene/gui/grid_container.cpp | 4 |
11 files changed, 194 insertions, 95 deletions
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index 5b2e019c4c..f3bff5a146 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -182,7 +182,8 @@ <argument index="0" name="action" type="String"> </argument> <description> - Returns [code]true[/code] when you start pressing the action event. + Returns [code]true[/code] when the user starts pressing the action event, meaning it's true only on the frame that the user pressed down the button. + This is useful for code that needs to run only once when an action is pressed, instead of every frame while it's pressed. </description> </method> <method name="is_action_just_released" qualifiers="const"> @@ -191,7 +192,7 @@ <argument index="0" name="action" type="String"> </argument> <description> - Returns [code]true[/code] when you stop pressing the action event. + Returns [code]true[/code] when the user stops pressing the action event, meaning it's true only on the frame that the user released the button. </description> </method> <method name="is_action_pressed" qualifiers="const"> diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 2636839764..321d29f2f6 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -762,14 +762,22 @@ PoolVector<Color> EditorSceneImporterGLTF::_decode_accessor_as_color(GLTFState & PoolVector<Color> ret; if (attribs.size() == 0) return ret; - ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret); + int type = state.accessors[p_accessor].type; + ERR_FAIL_COND_V(!(type == TYPE_VEC3 || type == TYPE_VEC4), ret); + int components; + if (type == TYPE_VEC3) { + components = 3; + } else { // TYPE_VEC4 + components = 4; + } + ERR_FAIL_COND_V(attribs.size() % components != 0, ret); const double *attribs_ptr = attribs.ptr(); - int ret_size = attribs.size() / 4; + int ret_size = attribs.size() / components; ret.resize(ret_size); { PoolVector<Color>::Write w = ret.write(); for (int i = 0; i < ret_size; i++) { - w[i] = Color(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]); + w[i] = Color(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], components == 4 ? attribs_ptr[i * 4 + 3] : 1.0); } } return ret; @@ -1875,6 +1883,8 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye animation.instance(); animation->set_name(name); + float length = 0; + for (Map<int, GLTFAnimation::Track>::Element *E = anim.tracks.front(); E; E = E->next()) { const GLTFAnimation::Track &track = E->get(); @@ -1893,8 +1903,6 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye node_path = ap->get_parent()->get_path_to(node->godot_nodes[i]); } - float length = 0; - for (int i = 0; i < track.rotation_track.times.size(); i++) { length = MAX(length, track.rotation_track.times[i]); } @@ -1911,8 +1919,6 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye } } - animation->set_length(length); - if (track.rotation_track.values.size() || track.translation_track.values.size() || track.scale_track.values.size()) { //make transform track int track_idx = animation->get_track_count(); @@ -2030,6 +2036,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye } } } + animation->set_length(length); ap->add_animation(name, animation); } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index a502048726..67323fa753 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -855,8 +855,8 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (b->get_button_index() == BUTTON_WHEEL_DOWN) { // Scroll or pan down if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) { - v_scroll->set_value(v_scroll->get_value() + int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor()); - _update_scroll(0); + view_offset.y += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); + _update_scrollbars(); viewport->update(); } else { _zoom_on_position(zoom * (1 - (0.05 * b->get_factor())), b->get_position()); @@ -867,8 +867,8 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (b->get_button_index() == BUTTON_WHEEL_UP) { // Scroll or pan up if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) { - v_scroll->set_value(v_scroll->get_value() - int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor()); - _update_scroll(0); + view_offset.y -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); + _update_scrollbars(); viewport->update(); } else { _zoom_on_position(zoom * ((0.95 + (0.05 * b->get_factor())) / 0.95), b->get_position()); @@ -879,7 +879,9 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (b->get_button_index() == BUTTON_WHEEL_LEFT) { // Pan left if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) { - h_scroll->set_value(h_scroll->get_value() - int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor()); + view_offset.x -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); + _update_scrollbars(); + viewport->update(); return true; } } @@ -887,7 +889,9 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (b->get_button_index() == BUTTON_WHEEL_RIGHT) { // Pan right if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) { - h_scroll->set_value(h_scroll->get_value() + int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor()); + view_offset.x += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); + _update_scrollbars(); + viewport->update(); return true; } } @@ -907,9 +911,10 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { } else { relative = m->get_relative(); } - - h_scroll->set_value(h_scroll->get_value() - relative.x / zoom); - v_scroll->set_value(v_scroll->get_value() - relative.y / zoom); + view_offset.x -= relative.x / zoom; + view_offset.y -= relative.y / zoom; + _update_scrollbars(); + viewport->update(); return true; } } @@ -926,8 +931,10 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (pan_gesture.is_valid()) { // Pan gesture const Vector2 delta = (int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom) * pan_gesture->get_delta(); - h_scroll->set_value(h_scroll->get_value() + delta.x); - v_scroll->set_value(v_scroll->get_value() + delta.y); + view_offset.x += delta.x; + view_offset.y += delta.y; + _update_scrollbars(); + viewport->update(); return true; } @@ -2552,6 +2559,11 @@ void CanvasItemEditor::_build_bones_list(Node *p_node) { } void CanvasItemEditor::_draw_viewport() { + // Update the transform + transform = Transform2D(); + transform.scale_basis(Size2(zoom, zoom)); + transform.elements[2] = -view_offset * zoom; + editor->get_scene_root()->set_global_canvas_transform(transform); // hide/show buttons depending on the selection bool all_locked = true; @@ -2582,8 +2594,6 @@ void CanvasItemEditor::_draw_viewport() { group_button->set_disabled(selection.empty()); ungroup_button->set_visible(all_group); - _update_scrollbars(); - _draw_grid(); _draw_selection(); _draw_axis(); @@ -2784,17 +2794,18 @@ void CanvasItemEditor::edit(CanvasItem *p_canvas_item) { // Clear the selection editor_selection->clear(); //_clear_canvas_items(); editor_selection->add_node(p_canvas_item); - viewport->update(); } void CanvasItemEditor::_update_scrollbars() { updating_scroll = true; + // Move the zoom buttons Point2 zoom_hb_begin = Point2(5, 5); zoom_hb_begin += (show_rulers) ? Point2(RULER_WIDTH, RULER_WIDTH) : Point2(); zoom_hb->set_begin(zoom_hb_begin); + // Move and resize the scrollbars Size2 size = viewport->get_size(); Size2 hmin = h_scroll->get_minimum_size(); Size2 vmin = v_scroll->get_minimum_size(); @@ -2805,8 +2816,8 @@ void CanvasItemEditor::_update_scrollbars() { h_scroll->set_begin(Point2((show_rulers) ? RULER_WIDTH : 0, size.height - hmin.height)); h_scroll->set_end(Point2(size.width - vmin.width, size.height)); + // Get the visible frame Size2 screen_rect = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); - Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height)); bone_last_frame++; @@ -2836,48 +2847,56 @@ void CanvasItemEditor::_update_scrollbars() { canvas_item_rect.size += screen_rect * 2; canvas_item_rect.position -= screen_rect; - Point2 ofs; + // Constraints the view offset and updates the scrollbars + Point2 begin = canvas_item_rect.position; + Point2 end = canvas_item_rect.position + canvas_item_rect.size - local_rect.size / zoom; if (canvas_item_rect.size.height <= (local_rect.size.y / zoom)) { + if (ABS(begin.y - previous_update_view_offset.y) < ABS(begin.y - view_offset.y)) { + view_offset.y = previous_update_view_offset.y; + } + v_scroll->hide(); - ofs.y = canvas_item_rect.position.y; } else { - - v_scroll->show(); - v_scroll->set_min(canvas_item_rect.position.y); - v_scroll->set_max(canvas_item_rect.position.y + canvas_item_rect.size.y); - v_scroll->set_page(local_rect.size.y / zoom); - if (first_update) { - //so 0,0 is visible - v_scroll->set_value(-10); - h_scroll->set_value(-10); - first_update = false; + if (view_offset.y > end.y && view_offset.y > previous_update_view_offset.y) { + view_offset.y = MAX(end.y, previous_update_view_offset.y); + } + if (view_offset.y < begin.y && view_offset.y < previous_update_view_offset.y) { + view_offset.y = MIN(begin.y, previous_update_view_offset.y); } - ofs.y = v_scroll->get_value(); + v_scroll->show(); + v_scroll->set_min(MIN(view_offset.y, begin.y)); + v_scroll->set_max(MAX(view_offset.y, end.y) + screen_rect.y); + v_scroll->set_page(screen_rect.y); } if (canvas_item_rect.size.width <= (local_rect.size.x / zoom)) { + if (ABS(begin.x - previous_update_view_offset.x) < ABS(begin.x - view_offset.x)) { + view_offset.x = previous_update_view_offset.x; + } h_scroll->hide(); - ofs.x = canvas_item_rect.position.x; } else { + if (view_offset.x > end.x && view_offset.x > previous_update_view_offset.x) { + view_offset.x = MAX(end.x, previous_update_view_offset.x); + } + if (view_offset.x < begin.x && view_offset.x < previous_update_view_offset.x) { + view_offset.x = MIN(begin.x, previous_update_view_offset.x); + } h_scroll->show(); - h_scroll->set_min(canvas_item_rect.position.x); - h_scroll->set_max(canvas_item_rect.position.x + canvas_item_rect.size.x); - h_scroll->set_page(local_rect.size.x / zoom); - ofs.x = h_scroll->get_value(); + h_scroll->set_min(MIN(view_offset.x, begin.x)); + h_scroll->set_max(MAX(view_offset.x, end.x) + screen_rect.x); + h_scroll->set_page(screen_rect.x); } - //transform=Matrix32(); - transform.elements[2] = -ofs * zoom; - - editor->get_scene_root()->set_global_canvas_transform(transform); + // Calculate scrollable area + v_scroll->set_value(view_offset.y); + h_scroll->set_value(view_offset.x); + previous_update_view_offset = view_offset; updating_scroll = false; - - //transform.scale_basis(Vector2(zoom,zoom)); } void CanvasItemEditor::_update_scroll(float) { @@ -2885,19 +2904,8 @@ void CanvasItemEditor::_update_scroll(float) { if (updating_scroll) return; - Point2 ofs; - ofs.x = h_scroll->get_value(); - ofs.y = v_scroll->get_value(); - - //current_window->set_scroll(-ofs); - - transform = Transform2D(); - - transform.scale_basis(Size2(zoom, zoom)); - transform.elements[2] = -ofs; - - editor->get_scene_root()->set_global_canvas_transform(transform); - + view_offset.x = h_scroll->get_value(); + view_offset.y = v_scroll->get_value(); viewport->update(); } @@ -2964,10 +2972,10 @@ void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) { zoom = p_zoom; Point2 ofs = p_position; ofs = ofs / prev_zoom - ofs / zoom; - h_scroll->set_value(Math::round(h_scroll->get_value() + ofs.x)); - v_scroll->set_value(Math::round(v_scroll->get_value() + ofs.y)); + view_offset.x = Math::round(view_offset.x + ofs.x); + view_offset.y = Math::round(view_offset.y + ofs.y); - _update_scroll(0); + _update_scrollbars(); viewport->update(); } @@ -3552,8 +3560,10 @@ void CanvasItemEditor::_focus_selection(int p_op) { center = rect.position + rect.size / 2; Vector2 offset = viewport->get_size() / 2 - editor->get_scene_root()->get_global_canvas_transform().xform(center); - h_scroll->set_value(h_scroll->get_value() - offset.x / zoom); - v_scroll->set_value(v_scroll->get_value() - offset.y / zoom); + view_offset.x -= offset.x / zoom; + view_offset.y -= offset.y / zoom; + _update_scrollbars(); + viewport->update(); } else { // VIEW_FRAME_TO_SELECTION @@ -3562,7 +3572,7 @@ void CanvasItemEditor::_focus_selection(int p_op) { float scale_y = viewport->get_size().y / rect.size.y; zoom = scale_x < scale_y ? scale_x : scale_y; zoom *= 0.90; - _update_scroll(0); + viewport->update(); call_deferred("_popup_callback", VIEW_CENTER_TO_SELECTION); } } @@ -3575,6 +3585,7 @@ void CanvasItemEditor::_bind_methods() { ClassDB::bind_method("_button_zoom_plus", &CanvasItemEditor::_button_zoom_plus); ClassDB::bind_method("_button_toggle_snap", &CanvasItemEditor::_button_toggle_snap); ClassDB::bind_method("_update_scroll", &CanvasItemEditor::_update_scroll); + ClassDB::bind_method("_update_scrollbars", &CanvasItemEditor::_update_scrollbars); ClassDB::bind_method("_popup_callback", &CanvasItemEditor::_popup_callback); ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data); ClassDB::bind_method("_button_tool_select", &CanvasItemEditor::_button_tool_select); @@ -3595,7 +3606,7 @@ Dictionary CanvasItemEditor::get_state() const { Dictionary state; state["zoom"] = zoom; - state["ofs"] = Point2(h_scroll->get_value(), v_scroll->get_value()); + state["ofs"] = view_offset; state["grid_offset"] = grid_offset; state["grid_step"] = grid_step; state["snap_rotation_offset"] = snap_rotation_offset; @@ -3629,10 +3640,9 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { } if (state.has("ofs")) { - _update_scrollbars(); // i wonder how safe is calling this here.. - Point2 ofs = p_state["ofs"]; - h_scroll->set_value(ofs.x); - v_scroll->set_value(ofs.y); + view_offset = p_state["ofs"]; + previous_update_view_offset = view_offset; + _update_scrollbars(); } if (state.has("grid_offset")) { @@ -3812,6 +3822,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { viewport_scrollable->set_clip_contents(true); viewport_scrollable->set_v_size_flags(SIZE_EXPAND_FILL); viewport_scrollable->set_h_size_flags(SIZE_EXPAND_FILL); + viewport_scrollable->connect("draw", this, "_update_scrollbars"); ViewportContainer *scene_tree = memnew(ViewportContainer); viewport_scrollable->add_child(scene_tree); @@ -3830,12 +3841,12 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { h_scroll = memnew(HScrollBar); viewport->add_child(h_scroll); - h_scroll->connect("value_changed", this, "_update_scroll", Vector<Variant>(), Object::CONNECT_DEFERRED); + h_scroll->connect("value_changed", this, "_update_scroll"); h_scroll->hide(); v_scroll = memnew(VScrollBar); viewport->add_child(v_scroll); - v_scroll->connect("value_changed", this, "_update_scroll", Vector<Variant>(), Object::CONNECT_DEFERRED); + v_scroll->connect("value_changed", this, "_update_scroll"); v_scroll->hide(); zoom_hb = memnew(HBoxContainer); @@ -3858,7 +3869,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { zoom_plus->set_focus_mode(FOCUS_NONE); updating_scroll = false; - first_update = true; select_button = memnew(ToolButton); hb->add_child(select_button); @@ -4082,6 +4092,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { show_rulers = true; show_guides = true; zoom = 1; + view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH); + previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen grid_offset = Point2(); grid_step = Point2(10, 10); grid_step_multiplier = 0; diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index a6e2ef800a..da7ce9172a 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -201,7 +201,6 @@ class CanvasItemEditor : public VBoxContainer { bool selection_menu_additive_selection; Tool tool; - bool first_update; Control *viewport; Control *viewport_scrollable; @@ -221,6 +220,8 @@ class CanvasItemEditor : public VBoxContainer { bool show_viewport; bool show_helpers; float zoom; + Point2 view_offset; + Point2 previous_update_view_offset; Point2 grid_offset; Point2 grid_step; diff --git a/modules/mono/config.py b/modules/mono/config.py index 5591ed25bf..831d849ea6 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -161,7 +161,7 @@ def configure(env): mono_lib_path = '' mono_so_name = '' - mono_prefix = subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).strip() + mono_prefix = subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).decode("utf8").strip() tmpenv = Environment() tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH')) diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 1ebef04561..0646580eaa 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -74,7 +74,31 @@ void gdmono_MonoPrintCallback(const char *string, mono_bool is_stdout) { GDMono *GDMono::singleton = NULL; +namespace { + +void setup_runtime_main_args() { + CharString execpath = OS::get_singleton()->get_executable_path().utf8(); + + List<String> cmdline_args = OS::get_singleton()->get_cmdline_args(); + + List<CharString> cmdline_args_utf8; + Vector<char *> main_args; + main_args.resize(cmdline_args.size() + 1); + + main_args[0] = execpath.ptrw(); + + int i = 1; + for (List<String>::Element *E = cmdline_args.front(); E; E = E->next()) { + CharString &stored = cmdline_args_utf8.push_back(E->get().utf8())->get(); + main_args[i] = stored.ptrw(); + i++; + } + + mono_runtime_set_main_args(main_args.size(), main_args.ptrw()); +} + #ifdef DEBUG_ENABLED + static bool _wait_for_debugger_msecs(uint32_t p_msecs) { do { @@ -96,9 +120,7 @@ static bool _wait_for_debugger_msecs(uint32_t p_msecs) { return mono_is_debugger_attached(); } -#endif -#ifdef DEBUG_ENABLED void gdmono_debug_init() { mono_debug_init(MONO_DEBUG_FORMAT_MONO); @@ -125,8 +147,11 @@ void gdmono_debug_init() { }; mono_jit_parse_options(2, (char **)options); } + #endif +} // namespace + void GDMono::initialize() { ERR_FAIL_NULL(Engine::get_singleton()); @@ -179,6 +204,8 @@ void GDMono::initialize() { GDMonoUtils::set_main_thread(GDMonoUtils::get_current_thread()); + setup_runtime_main_args(); // Required for System.Environment.GetCommandLineArgs + runtime_initialized = true; OS::get_singleton()->print("Mono: Runtime initialized\n"); diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 52ae2d51e1..d062d56dcf 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -85,19 +85,22 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d path = search_dir.plus_file(name); if (FileAccess::exists(path)) { res = _load_assembly_from(name.get_basename(), path, refonly); - break; + if (res != NULL) + break; } } else { path = search_dir.plus_file(name + ".dll"); if (FileAccess::exists(path)) { res = _load_assembly_from(name, path, refonly); - break; + if (res != NULL) + break; } path = search_dir.plus_file(name + ".exe"); if (FileAccess::exists(path)) { res = _load_assembly_from(name, path, refonly); - break; + if (res != NULL) + break; } } } @@ -152,19 +155,15 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse path = search_dir.plus_file(name); if (FileAccess::exists(path)) { res = _load_assembly_from(name.get_basename(), path, refonly); - break; + if (res != NULL) + break; } } else { path = search_dir.plus_file(name + ".dll"); if (FileAccess::exists(path)) { res = _load_assembly_from(name, path, refonly); - break; - } - - path = search_dir.plus_file(name + ".exe"); - if (FileAccess::exists(path)) { - res = _load_assembly_from(name, path, refonly); - break; + if (res != NULL) + break; } } } @@ -213,14 +212,15 @@ Error GDMonoAssembly::load(bool p_refonly) { String image_filename(path); - MonoImageOpenStatus status; + MonoImageOpenStatus status = MONO_IMAGE_OK; image = mono_image_open_from_data_with_name( (char *)&data[0], data.size(), true, &status, refonly, image_filename.utf8().get_data()); - ERR_FAIL_COND_V(status != MONO_IMAGE_OK || image == NULL, ERR_FILE_CANT_OPEN); + ERR_FAIL_COND_V(status != MONO_IMAGE_OK, ERR_FILE_CANT_OPEN); + ERR_FAIL_NULL_V(image, ERR_FILE_CANT_OPEN); #ifdef DEBUG_ENABLED String pdb_path(path + ".pdb"); diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 7e6a1518ed..989e608716 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -65,13 +65,14 @@ def configure(env): elif (env["target"] == "release_debug"): env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) - env.Append(LINKFLAGS=['-O2', '-s', 'ASSERTIONS=1']) + env.Append(LINKFLAGS=['-O2']) # retain function names at the cost of file size, for backtraces and profiling env.Append(LINKFLAGS=['--profiling-funcs']) elif (env["target"] == "debug"): env.Append(CCFLAGS=['-O1', '-D_DEBUG', '-g', '-DDEBUG_ENABLED']) env.Append(LINKFLAGS=['-O1', '-g']) + env.Append(LINKFLAGS=['-s', 'ASSERTIONS=1']) ## Compiler configuration diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 486d7af1c1..29935f197e 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -195,6 +195,7 @@ public: virtual VideoMode get_video_mode(int p_screen = 0) const; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const; + virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool p_read_stderr); virtual String get_executable_path() const; virtual LatinKeyboardVariant get_latin_keyboard_variant() const; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index a811ff585d..d125ca5a67 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -2045,6 +2045,55 @@ bool OS_OSX::get_borderless_window() { return [window_object styleMask] == NSWindowStyleMaskBorderless; } +Error OS_OSX::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool p_read_stderr) { + + NSTask *task = [[NSTask alloc] init]; + NSPipe *stdout_pipe = nil; + [task setLaunchPath:[NSString stringWithUTF8String:p_path.utf8().get_data()]]; + + NSMutableArray *arguments = [[NSMutableArray alloc] initWithCapacity:p_arguments.size()]; + for (int i = 0; i < p_arguments.size(); i++) { + [arguments addObject:[NSString stringWithUTF8String:p_arguments[i].utf8().get_data()]]; + } + [task setArguments:arguments]; + + if (p_blocking && r_pipe) { + stdout_pipe = [NSPipe pipe]; + [task setStandardOutput:stdout_pipe]; + if (p_read_stderr) [task setStandardError:[task standardOutput]]; + } + + @try { + [task launch]; + if (r_child_id) + *r_child_id = [task processIdentifier]; + + if (p_blocking) { + if (r_pipe) { + NSFileHandle *read_handle = [stdout_pipe fileHandleForReading]; + NSData *data = nil; + while ((data = [read_handle availableData]) && [data length]) { + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + (*r_pipe) += [string UTF8String]; + [string release]; + } + } else { + [task waitUntilExit]; + } + } + + [arguments release]; + [task release]; + return OK; + } @catch (NSException *exception) { + ERR_PRINTS("NSException: " + String([exception reason].UTF8String) + "; Path: " + p_path); + + [arguments release]; + [task release]; + return ERR_CANT_OPEN; + } +} + String OS_OSX::get_executable_path() const { int ret; diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 9948672097..b401abd436 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -84,8 +84,8 @@ void GridContainer::_notification(int p_what) { if (!row_expanded.has(E->key())) remaining_space.height -= E->get(); } - remaining_space.height -= vsep * (max_row - 1); - remaining_space.width -= hsep * (max_col - 1); + remaining_space.height -= vsep * MAX(max_row - 1, 0); + remaining_space.width -= hsep * MAX(max_col - 1, 0); bool can_fit = false; while (!can_fit && col_expanded.size() > 0) { |