summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/array.cpp57
-rw-r--r--core/array.h5
-rw-r--r--core/ustring.cpp18
-rw-r--r--core/variant_call.cpp2
-rw-r--r--doc/classes/Array.xml15
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp4
-rw-r--r--editor/inspector_dock.cpp2
-rw-r--r--editor/project_settings_editor.cpp4
-rw-r--r--modules/gdnative/gdnative/array.cpp9
-rw-r--r--modules/gdnative/gdnative_api.json11
-rw-r--r--modules/gdnative/include/gdnative/array.h2
11 files changed, 124 insertions, 5 deletions
diff --git a/core/array.cpp b/core/array.cpp
index 108d9f7386..ac30df08bc 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -222,6 +222,63 @@ Array Array::duplicate(bool p_deep) const {
return new_arr;
}
+
+int Array::_fix_slice_index(int p_index, int p_arr_len, int p_top_mod) {
+ p_index = CLAMP(p_index, -p_arr_len, p_arr_len + p_top_mod);
+ if (p_index < 0) {
+ p_index = (p_index % p_arr_len + p_arr_len) % p_arr_len; // positive modulo
+ }
+ return p_index;
+}
+
+int Array::_clamp_index(int p_index) const {
+ return CLAMP(p_index, -size() + 1, size() - 1);
+}
+
+#define ARRAY_GET_DEEP(idx, is_deep) is_deep ? get(idx).duplicate(is_deep) : get(idx)
+
+Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // like python, but inclusive on upper bound
+ Array new_arr;
+
+ p_begin = Array::_fix_slice_index(p_begin, size(), -1); // can't start out of range
+ p_end = Array::_fix_slice_index(p_end, size(), 0);
+
+ int x = p_begin;
+ int new_arr_i = 0;
+
+ ERR_FAIL_COND_V(p_step == 0, new_arr);
+ if (Array::_clamp_index(p_begin) == Array::_clamp_index(p_end)) { // don't include element twice
+ new_arr.resize(1);
+ // new_arr[0] = 1;
+ new_arr[0] = ARRAY_GET_DEEP(Array::_clamp_index(p_begin), p_deep);
+ return new_arr;
+ } else {
+ int element_count = ceil((int)MAX(0, (p_end - p_begin) / p_step)) + 1;
+ if (element_count == 1) { // delta going in wrong direction to reach end
+ new_arr.resize(0);
+ return new_arr;
+ }
+ new_arr.resize(element_count);
+ }
+
+ // if going backwards, have to have a different terminating condition
+ if (p_step < 0) {
+ while (x >= p_end) {
+ new_arr[new_arr_i] = ARRAY_GET_DEEP(Array::_clamp_index(x), p_deep);
+ x += p_step;
+ new_arr_i += 1;
+ }
+ } else if (p_step > 0) {
+ while (x <= p_end) {
+ new_arr[new_arr_i] = ARRAY_GET_DEEP(Array::_clamp_index(x), p_deep);
+ x += p_step;
+ new_arr_i += 1;
+ }
+ }
+
+ return new_arr;
+}
+
struct _ArrayVariantSort {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
diff --git a/core/array.h b/core/array.h
index d4e937a486..7a754d53ea 100644
--- a/core/array.h
+++ b/core/array.h
@@ -44,6 +44,9 @@ class Array {
void _ref(const Array &p_from) const;
void _unref() const;
+ int _clamp_index(int p_index) const;
+ static int _fix_slice_index(int p_index, int p_arr_len, int p_top_mod);
+
public:
Variant &operator[](int p_idx);
const Variant &operator[](int p_idx) const;
@@ -91,6 +94,8 @@ public:
Array duplicate(bool p_deep = false) const;
+ Array slice(int p_begin, int p_end, int p_step = 1, bool p_deep = false) const;
+
Variant min() const;
Variant max() const;
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 237e86aaf1..dee554716f 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -3285,18 +3285,26 @@ static int _humanize_digits(int p_num) {
String String::humanize_size(size_t p_size) {
uint64_t _div = 1;
- static const char *prefix[] = { " B", " KiB", " MiB", " GiB", " TiB", " PiB", " EiB", "" };
+ Vector<String> prefixes;
+ prefixes.push_back(RTR("B"));
+ prefixes.push_back(RTR("KiB"));
+ prefixes.push_back(RTR("MiB"));
+ prefixes.push_back(RTR("GiB"));
+ prefixes.push_back(RTR("TiB"));
+ prefixes.push_back(RTR("PiB"));
+ prefixes.push_back(RTR("EiB"));
+
int prefix_idx = 0;
- while (p_size > (_div * 1024) && prefix[prefix_idx][0]) {
+ while (prefix_idx < prefixes.size() && p_size > (_div * 1024)) {
_div *= 1024;
prefix_idx++;
}
- int digits = prefix_idx > 0 ? _humanize_digits(p_size / _div) : 0;
- double divisor = prefix_idx > 0 ? _div : 1;
+ const int digits = prefix_idx > 0 ? _humanize_digits(p_size / _div) : 0;
+ const double divisor = prefix_idx > 0 ? _div : 1;
- return String::num(p_size / divisor).pad_decimals(digits) + RTR(prefix[prefix_idx]);
+ return String::num(p_size / divisor).pad_decimals(digits) + " " + prefixes[prefix_idx];
}
bool String::is_abs_path() const {
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 5e3876d6a4..c288c50abf 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -534,6 +534,7 @@ struct _VariantCall {
VCALL_LOCALMEM2R(Array, bsearch);
VCALL_LOCALMEM4R(Array, bsearch_custom);
VCALL_LOCALMEM1R(Array, duplicate);
+ VCALL_LOCALMEM4R(Array, slice);
VCALL_LOCALMEM0(Array, invert);
VCALL_LOCALMEM0R(Array, max);
VCALL_LOCALMEM0R(Array, min);
@@ -1759,6 +1760,7 @@ void register_variant_methods() {
ADDFUNC4R(ARRAY, INT, Array, bsearch_custom, NIL, "value", OBJECT, "obj", STRING, "func", BOOL, "before", varray(true));
ADDFUNC0NC(ARRAY, NIL, Array, invert, varray());
ADDFUNC1R(ARRAY, ARRAY, Array, duplicate, BOOL, "deep", varray(false));
+ ADDFUNC4R(ARRAY, ARRAY, Array, slice, INT, "begin", INT, "end", INT, "step", BOOL, "deep", varray(1, false));
ADDFUNC0R(ARRAY, NIL, Array, max, varray());
ADDFUNC0R(ARRAY, NIL, Array, min, varray());
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index 130908b842..45d40cccea 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -124,6 +124,21 @@
[b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior.
</description>
</method>
+ <method name="slice">
+ <return type="Array">
+ </return>
+ <argument index="0" name="begin" type="int">
+ </argument>
+ <argument index="1" name="end" type="int">
+ </argument>
+ <argument index="2" name="step" type="int" default="1">
+ </argument>
+ <argument index="3" name="deep" type="bool" default="False">
+ </argument>
+ <description>
+ Duplicates the subset described in the function and returns it in an array, deeply copying the array if [code]deep[/code] is true. Lower and upper index are inclusive, with the [code]step[/code] describing the change between indices while slicing.
+ </description>
+ </method>
<method name="clear">
<description>
Clears the array. This is equivalent to using [method resize] with a size of [code]0[/code].
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 1cab3d89aa..35f414cf09 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -4330,6 +4330,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
if (storage->frame.current_rt->buffers.active) {
current_fbo = storage->frame.current_rt->buffers.fbo;
} else {
+ if (storage->frame.current_rt->effects.mip_maps[0].sizes.size() == 0) {
+ ERR_PRINT_ONCE("Can't use canvas background mode in a render target configured without sampling");
+ return;
+ }
current_fbo = storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo;
}
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 8ba7d9fba7..e4411e436a 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -408,6 +408,7 @@ void InspectorDock::update(Object *p_object) {
warning->hide();
search->set_editable(false);
+ editor_path->set_disabled(true);
editor_path->set_text("");
editor_path->set_tooltip("");
editor_path->set_icon(NULL);
@@ -420,6 +421,7 @@ void InspectorDock::update(Object *p_object) {
object_menu->set_disabled(false);
search->set_editable(true);
+ editor_path->set_disabled(false);
resource_save_button->set_disabled(!is_resource);
PopupMenu *p = object_menu->get_popup();
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index edc14ccf71..91ce256be5 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -1007,8 +1007,12 @@ void ProjectSettingsEditor::_copy_to_platform_about_to_show() {
presets.insert("pvrtc");
presets.insert("debug");
presets.insert("release");
+ presets.insert("editor");
+ presets.insert("standalone");
presets.insert("32");
presets.insert("64");
+ // Not available as an export platform yet, so it needs to be added manually
+ presets.insert("Server");
for (int i = 0; i < EditorExport::get_singleton()->get_export_platform_count(); i++) {
List<String> p;
diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp
index 1ef8e9f900..e97a75cca8 100644
--- a/modules/gdnative/gdnative/array.cpp
+++ b/modules/gdnative/gdnative/array.cpp
@@ -327,6 +327,15 @@ godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_b
return res;
}
+godot_array GDAPI godot_array_slice(const godot_array *p_self, const godot_int p_begin, const godot_int p_end, const godot_int p_step, const godot_bool p_deep) {
+ const Array *self = (const Array *)p_self;
+ godot_array res;
+ Array *val = (Array *)&res;
+ memnew_placement(val, Array);
+ *val = self->slice(p_begin, p_end, p_step, p_deep);
+ return res;
+}
+
godot_variant GDAPI godot_array_max(const godot_array *p_self) {
const Array *self = (const Array *)p_self;
godot_variant v;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 03258584ce..55ba4ecc1e 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -80,6 +80,17 @@
["const godot_vector2 *", "p_self"],
["const godot_vector2 *", "p_to"]
]
+ },
+ {
+ "name": "godot_array_slice",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_int", "p_begin"],
+ ["const godot_int", "p_end"],
+ ["const godot_int", "p_step"],
+ ["const godot_bool", "p_deep"]
+ ]
}
]
},
diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h
index 10ef8a73d2..2e3ce58033 100644
--- a/modules/gdnative/include/gdnative/array.h
+++ b/modules/gdnative/include/gdnative/array.h
@@ -132,6 +132,8 @@ void GDAPI godot_array_destroy(godot_array *p_self);
godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_bool p_deep);
+godot_array GDAPI godot_array_slice(const godot_array *p_self, const godot_int p_begin, const godot_int p_end, const godot_int p_delta, const godot_bool p_deep);
+
godot_variant GDAPI godot_array_max(const godot_array *p_self);
godot_variant GDAPI godot_array_min(const godot_array *p_self);