summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/class_db.cpp1
-rw-r--r--core/io/packet_peer.cpp5
-rw-r--r--core/io/resource_format_binary.cpp2
-rw-r--r--core/make_binders.py3
-rw-r--r--core/map.h2
-rw-r--r--core/math/camera_matrix.cpp4
-rw-r--r--core/set.h2
-rw-r--r--core/ustring.cpp45
-rw-r--r--core/ustring.h4
-rw-r--r--core/variant_call.cpp5
-rw-r--r--doc/classes/String.xml28
-rw-r--r--editor/import/editor_import_collada.cpp50
-rw-r--r--editor/import/resource_importer_scene.cpp1
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp2
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp6
-rw-r--r--editor/scene_tree_dock.cpp2
-rw-r--r--editor/script_editor_debugger.h2
-rw-r--r--main/tests/test_string.cpp39
-rw-r--r--modules/bullet/rigid_body_bullet.h2
-rw-r--r--modules/bullet/space_bullet.cpp4
-rw-r--r--modules/gdnative/gdnative/string.cpp14
-rw-r--r--modules/gdnative/gdnative_api.json20
-rw-r--r--modules/gdnative/include/gdnative/string.h2
-rw-r--r--modules/mono/glue/Managed/Files/StringExtensions.cs60
-rw-r--r--platform/uwp/export/export.cpp4
-rw-r--r--platform/x11/joypad_linux.cpp2
-rw-r--r--platform/x11/power_x11.cpp4
-rw-r--r--scene/main/instance_placeholder.cpp2
-rw-r--r--scene/main/scene_tree.cpp5
-rw-r--r--scene/resources/visual_shader_nodes.h4
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp2
-rw-r--r--servers/physics/collision_solver_sat.cpp4
-rw-r--r--servers/physics/collision_solver_sw.cpp4
-rw-r--r--servers/physics/joints/hinge_joint_sw.cpp1
-rw-r--r--servers/physics_2d/body_2d_sw.cpp24
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.cpp2
-rw-r--r--servers/physics_2d/collision_solver_2d_sat.cpp4
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.cpp2
-rw-r--r--servers/visual/shader_language.cpp4
-rw-r--r--servers/visual_server.cpp4
40 files changed, 300 insertions, 77 deletions
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 794d990083..49e3f94d8f 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -480,6 +480,7 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
for (List<StringName>::Element *F = snames.front(); F; F = F->next()) {
PropertySetGet *psg = t->property_setget.getptr(F->get());
+ ERR_FAIL_COND_V(!psg, 0);
hash = hash_djb2_one_64(F->get().hash(), hash);
hash = hash_djb2_one_64(psg->setter.hash(), hash);
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index c77c81f9e2..1e4ea715b3 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -110,10 +110,11 @@ Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) {
Variant PacketPeer::_bnd_get_var(bool p_allow_objects) {
Variant var;
- get_var(var, p_allow_objects);
+ Error err = get_var(var, p_allow_objects);
+ ERR_FAIL_COND_V(err != OK, Variant());
return var;
-};
+}
Error PacketPeer::_put_packet(const PoolVector<uint8_t> &p_buffer) {
return put_packet_buffer(p_buffer);
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 38bef2768e..146480e5a2 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -718,8 +718,8 @@ Error ResourceInteractiveLoaderBinary::poll() {
Resource *r = Object::cast_to<Resource>(obj);
if (!r) {
error = ERR_FILE_CORRUPT;
- memdelete(obj); //bye
ERR_EXPLAIN(local_path + ":Resource type in resource field not a resource, type is: " + obj->get_class());
+ memdelete(obj); //bye
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
diff --git a/core/make_binders.py b/core/make_binders.py
index 24901c42a1..c38db5cef4 100644
--- a/core/make_binders.py
+++ b/core/make_binders.py
@@ -334,9 +334,6 @@ def make_version(template, nargs, argmax, const, ret):
elif (cmd == "noarg"):
for i in range(nargs + 1, argmax + 1):
outtext += data.replace("@", str(i))
- elif (cmd == "noarg"):
- for i in range(nargs + 1, argmax + 1):
- outtext += data.replace("@", str(i))
from_pos = end + 1
diff --git a/core/map.h b/core/map.h
index a701ba36f7..c8197639f2 100644
--- a/core/map.h
+++ b/core/map.h
@@ -38,7 +38,7 @@
*/
// based on the very nice implementation of rb-trees by:
-// http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
+// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
template <class K, class V, class C = Comparator<K>, class A = DefaultAllocator>
class Map {
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 8b3b6c82f3..30c0cab909 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -302,8 +302,8 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform &p_transform)
/** Fast Plane Extraction from combined modelview/projection matrices.
* References:
- * http://www.markmorley.com/opengl/frustumculling.html
- * http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
+ * https://web.archive.org/web/20011221205252/http://www.markmorley.com/opengl/frustumculling.html
+ * https://web.archive.org/web/20061020020112/http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
*/
Vector<Plane> planes;
diff --git a/core/set.h b/core/set.h
index 81250068af..b2c717880d 100644
--- a/core/set.h
+++ b/core/set.h
@@ -39,7 +39,7 @@
*/
// based on the very nice implementation of rb-trees by:
-// http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
+// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
template <class T, class C = Comparator<T>, class A = DefaultAllocator>
class Set {
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 75e3b6f22e..ed401c3763 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -2729,6 +2729,51 @@ bool String::is_quoted() const {
return is_enclosed_in("\"") || is_enclosed_in("'");
}
+int String::_count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const {
+ if (p_string.empty()) {
+ return 0;
+ }
+ int len = length();
+ int slen = p_string.length();
+ if (len < slen) {
+ return 0;
+ }
+ String str;
+ if (p_from >= 0 && p_to >= 0) {
+ if (p_to == 0) {
+ p_to = len;
+ } else if (p_from >= p_to) {
+ return 0;
+ }
+ if (p_from == 0 && p_to == len) {
+ str = String();
+ str.copy_from_unchecked(&c_str()[0], len);
+ } else {
+ str = substr(p_from, p_to - p_from);
+ }
+ } else {
+ return 0;
+ }
+ int c = 0;
+ int idx = -1;
+ do {
+ idx = p_case_insensitive ? str.findn(p_string) : str.find(p_string);
+ if (idx != -1) {
+ str = str.substr(idx + slen, str.length() - slen);
+ ++c;
+ }
+ } while (idx != -1);
+ return c;
+}
+
+int String::count(const String &p_string, int p_from, int p_to) const {
+ return _count(p_string, p_from, p_to, false);
+}
+
+int String::countn(const String &p_string, int p_from, int p_to) const {
+ return _count(p_string, p_from, p_to, true);
+}
+
bool String::_base_is_subsequence_of(const String &p_string, bool case_insensitive) const {
int len = length();
diff --git a/core/ustring.h b/core/ustring.h
index 8a52c53238..3eb5c47b3a 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -137,6 +137,7 @@ class String {
void copy_from(const CharType &p_char);
void copy_from_unchecked(const CharType *p_char, const int p_length);
bool _base_is_subsequence_of(const String &p_string, bool case_insensitive) const;
+ int _count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const;
public:
enum {
@@ -279,6 +280,9 @@ public:
String to_upper() const;
String to_lower() const;
+ int count(const String &p_string, int p_from = 0, int p_to = 0) const;
+ int countn(const String &p_string, int p_from = 0, int p_to = 0) const;
+
String left(int p_pos) const;
String right(int p_pos) const;
String dedent() const;
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index b637e745af..377cc889b8 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -237,6 +237,8 @@ struct _VariantCall {
VCALL_LOCALMEM1R(String, casecmp_to);
VCALL_LOCALMEM1R(String, nocasecmp_to);
VCALL_LOCALMEM0R(String, length);
+ VCALL_LOCALMEM3R(String, count);
+ VCALL_LOCALMEM3R(String, countn);
VCALL_LOCALMEM2R(String, substr);
VCALL_LOCALMEM2R(String, find);
VCALL_LOCALMEM1R(String, find_last);
@@ -1502,6 +1504,9 @@ void register_variant_methods() {
ADDFUNC2R(STRING, INT, String, find, STRING, "what", INT, "from", varray(0));
+ ADDFUNC3R(STRING, INT, String, count, STRING, "what", INT, "from", INT, "to", varray(0, 0));
+ ADDFUNC3R(STRING, INT, String, countn, STRING, "what", INT, "from", INT, "to", varray(0, 0));
+
ADDFUNC1R(STRING, INT, String, find_last, STRING, "what", varray());
ADDFUNC2R(STRING, INT, String, findn, STRING, "what", INT, "from", varray(0));
ADDFUNC2R(STRING, INT, String, rfind, STRING, "what", INT, "from", varray(-1));
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index e513a44b1d..6dc3e35558 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -272,6 +272,34 @@
Performs a case-sensitive comparison to another string. Returns [code]-1[/code] if less than, [code]+1[/code] if greater than, or [code]0[/code] if equal.
</description>
</method>
+ <method name="count">
+ <return type="int">
+ </return>
+ <argument index="0" name="what" type="String">
+ </argument>
+ <argument index="1" name="from" type="int" default="0">
+ </argument>
+ <argument index="2" name="to" type="int" default="0">
+ </argument>
+ </argument>
+ <description>
+ Returns the number of occurrences of substring [code]what[/code] between [code]from[/code] and [code]to[/code] positions. If [code]from[/code] and [code]to[/code] equals 0 the whole string will be used. If only [code]to[/code] equals 0 the remained substring will be used.
+ </description>
+ </method>
+ <method name="countn">
+ <return type="int">
+ </return>
+ <argument index="0" name="what" type="String">
+ </argument>
+ <argument index="1" name="from" type="int" default="0">
+ </argument>
+ <argument index="2" name="to" type="int" default="0">
+ </argument>
+ </argument>
+ <description>
+ Returns the number of occurrences of substring [code]what[/code] (ignoring case) between [code]from[/code] and [code]to[/code] positions. If [code]from[/code] and [code]to[/code] equals 0 the whole string will be used. If only [code]to[/code] equals 0 the remained substring will be used.
+ </description>
+ </method>
<method name="dedent">
<return type="String">
</return>
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index e152827c63..1c4a8c43a9 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -1175,35 +1175,33 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
morph = &collada.state.morph_controller_data_map[ngsource];
meshid = morph->mesh;
- Vector<String> targets;
-
- morph->targets.has("MORPH_TARGET");
- String target = morph->targets["MORPH_TARGET"];
- bool valid = false;
- if (morph->sources.has(target)) {
- valid = true;
- Vector<String> names = morph->sources[target].sarray;
- for (int i = 0; i < names.size(); i++) {
-
- String meshid2 = names[i];
- if (collada.state.mesh_data_map.has(meshid2)) {
- Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
- const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid2];
- mesh->set_name(meshdata.name);
- Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), false);
- ERR_FAIL_COND_V(err, err);
-
- morphs.push_back(mesh);
- } else {
- valid = false;
+ if (morph->targets.has("MORPH_TARGET")) {
+ String target = morph->targets["MORPH_TARGET"];
+ bool valid = false;
+ if (morph->sources.has(target)) {
+ valid = true;
+ Vector<String> names = morph->sources[target].sarray;
+ for (int i = 0; i < names.size(); i++) {
+
+ String meshid2 = names[i];
+ if (collada.state.mesh_data_map.has(meshid2)) {
+ Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
+ const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid2];
+ mesh->set_name(meshdata.name);
+ Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), false);
+ ERR_FAIL_COND_V(err, err);
+
+ morphs.push_back(mesh);
+ } else {
+ valid = false;
+ }
}
}
- }
-
- if (!valid)
- morphs.clear();
- ngsource = "";
+ if (!valid)
+ morphs.clear();
+ ngsource = "";
+ }
}
if (ngsource != "") {
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 53b67c46b0..8e6a56a929 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -435,6 +435,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
Object::cast_to<Spatial>(sb)->set_transform(Object::cast_to<Spatial>(p_node)->get_transform());
p_node->replace_by(sb);
memdelete(p_node);
+ p_node = NULL;
CollisionShape *colshape = memnew(CollisionShape);
if (empty_draw_type == "CUBE") {
BoxShape *boxShape = memnew(BoxShape);
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index e582f6ded2..1fc6dae978 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -201,6 +201,8 @@ void MeshLibraryEditor::_import_scene_cbk(const String &p_str) {
ERR_FAIL_COND(ps.is_null());
Node *scene = ps->instance();
+ ERR_FAIL_COND(!scene);
+
_import_scene(scene, mesh_library, option == MENU_OPTION_UPDATE_FROM_SCENE);
memdelete(scene);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 21349e18d4..52fadf1e71 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -69,7 +69,7 @@
#define FREELOOK_SPEED_MULTIPLIER 1.08
#define MIN_Z 0.01
-#define MAX_Z 10000
+#define MAX_Z 1000000.0
#define MIN_FOV 0.01
#define MAX_FOV 179
@@ -645,7 +645,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
Vector3 r;
- if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * 10000.0, grabber_pos, grabber_radius, &r)) {
+ if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) {
float d = r.distance_to(ray_pos);
if (d < col_d) {
col_d = d;
@@ -753,7 +753,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
Vector3 r;
- if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * 10000.0, grabber_pos, grabber_radius, &r)) {
+ if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) {
float d = r.distance_to(ray_pos);
if (d < col_d) {
col_d = d;
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 009ac603e2..aeee829de2 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -301,6 +301,8 @@ bool SceneTreeDock::_track_inherit(const String &p_target_scene_path, Node *p_de
Ref<PackedScene> data = ResourceLoader::load(path);
if (data.is_valid()) {
p = data->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
+ if (!p)
+ continue;
instances.push_back(p);
} else
break;
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index 505eab266f..947b0cca52 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -173,7 +173,7 @@ class ScriptEditorDebugger : public Control {
void _set_reason_text(const String &p_reason, MessageType p_type);
void _scene_tree_property_select_object(ObjectID p_object);
void _scene_tree_property_value_edited(const String &p_prop, const Variant &p_value);
- int _update_scene_tree(TreeItem *parent, const Array &items, int current_index);
+ int _update_scene_tree(TreeItem *parent, const Array &nodes, int current_index);
void _video_mem_request();
diff --git a/main/tests/test_string.cpp b/main/tests/test_string.cpp
index 05df888f40..ab5fb64252 100644
--- a/main/tests/test_string.cpp
+++ b/main/tests/test_string.cpp
@@ -1078,6 +1078,44 @@ bool test_34() {
return state;
}
+bool test_35() {
+#define COUNT_TEST(x) \
+ { \
+ bool success = x; \
+ state = state && success; \
+ if (!success) { \
+ OS::get_singleton()->print("\tfailed at: %s\n", #x); \
+ } \
+ }
+
+ OS::get_singleton()->print("\n\nTest 35: count and countn function\n");
+ bool state = true;
+
+ COUNT_TEST(String("").count("Test") == 0);
+ COUNT_TEST(String("Test").count("") == 0);
+ COUNT_TEST(String("Test").count("test") == 0);
+ COUNT_TEST(String("Test").count("TEST") == 0);
+ COUNT_TEST(String("TEST").count("TEST") == 1);
+ COUNT_TEST(String("Test").count("Test") == 1);
+ COUNT_TEST(String("aTest").count("Test") == 1);
+ COUNT_TEST(String("Testa").count("Test") == 1);
+ COUNT_TEST(String("TestTestTest").count("Test") == 3);
+ COUNT_TEST(String("TestTestTest").count("TestTest") == 1);
+ COUNT_TEST(String("TestGodotTestGodotTestGodot").count("Test") == 3);
+
+ COUNT_TEST(String("TestTestTestTest").count("Test", 4, 8) == 1);
+ COUNT_TEST(String("TestTestTestTest").count("Test", 4, 12) == 2);
+ COUNT_TEST(String("TestTestTestTest").count("Test", 4, 16) == 3);
+ COUNT_TEST(String("TestTestTestTest").count("Test", 4) == 3);
+
+ COUNT_TEST(String("Test").countn("test") == 1);
+ COUNT_TEST(String("Test").countn("TEST") == 1);
+ COUNT_TEST(String("testTest-Testatest").countn("tEst") == 4);
+ COUNT_TEST(String("testTest-TeStatest").countn("tEsT", 4, 16) == 2);
+
+ return state;
+}
+
typedef bool (*TestFunc)(void);
TestFunc test_funcs[] = {
@@ -1116,6 +1154,7 @@ TestFunc test_funcs[] = {
test_32,
test_33,
test_34,
+ test_35,
0
};
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index 2c9bdb8b0b..f63148092f 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -305,7 +305,7 @@ public:
void reload_axis_lock();
/// Doc:
- /// http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Anti_tunneling_by_Motion_Clamping
+ /// https://web.archive.org/web/20180404091446/http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Anti_tunneling_by_Motion_Clamping
void set_continuous_collision_detection(bool p_enable);
bool is_continuous_collision_detection_enabled() const;
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 738b415d16..9d632aaf83 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -581,6 +581,10 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
} else {
world_mem = malloc(sizeof(btDiscreteDynamicsWorld));
}
+ if (!world_mem) {
+ ERR_EXPLAIN("Out of memory");
+ ERR_FAIL();
+ }
if (p_create_soft_world) {
collisionConfiguration = bulletnew(GodotSoftCollisionConfiguration(static_cast<btDiscreteDynamicsWorld *>(world_mem)));
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 913c57eb56..9086121940 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -186,6 +186,20 @@ godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_
return self->ends_with(*string);
}
+godot_int GDAPI godot_string_count(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to) {
+ const String *self = (const String *)p_self;
+ String *what = (String *)&p_what;
+
+ return self->count(*what, p_from, p_to);
+}
+
+godot_int GDAPI godot_string_countn(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to) {
+ const String *self = (const String *)p_self;
+ String *what = (String *)&p_what;
+
+ return self->countn(*what, p_from, p_to);
+}
+
godot_int GDAPI godot_string_find(const godot_string *p_self, godot_string p_what) {
const String *self = (const String *)p_self;
String *what = (String *)&p_what;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 6c12ee6534..7372990d5f 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -44,6 +44,26 @@
["const godot_vector2 *", "p_to"],
["const godot_real", "p_delta"]
]
+ },
+ {
+ "name": "godot_string_count",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"],
+ ["godot_int", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_string_countn",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"],
+ ["godot_int", "p_to"]
+ ]
}
]
},
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index f045ac9d58..7500d70f20 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -102,6 +102,8 @@ godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self,
godot_array GDAPI godot_string_bigrams(const godot_string *p_self);
godot_string GDAPI godot_string_chr(wchar_t p_character);
godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string);
+godot_int GDAPI godot_string_count(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to);
+godot_int GDAPI godot_string_countn(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to);
godot_int GDAPI godot_string_find(const godot_string *p_self, godot_string p_what);
godot_int GDAPI godot_string_find_from(const godot_string *p_self, godot_string p_what, godot_int p_from);
godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_array *p_keys);
diff --git a/modules/mono/glue/Managed/Files/StringExtensions.cs b/modules/mono/glue/Managed/Files/StringExtensions.cs
index b43034fbb5..6045c83e95 100644
--- a/modules/mono/glue/Managed/Files/StringExtensions.cs
+++ b/modules/mono/glue/Managed/Files/StringExtensions.cs
@@ -98,6 +98,66 @@ namespace Godot
}
// <summary>
+ // Return the amount of substrings in string.
+ // </summary>
+ public static int Count(this string instance, string what, bool caseSensitive = true, int from = 0, int to = 0)
+ {
+ if (what.Length == 0)
+ {
+ return 0;
+ }
+
+ int len = instance.Length;
+ int slen = what.Length;
+
+ if (len < slen)
+ {
+ return 0;
+ }
+
+ string str;
+
+ if (from >= 0 && to >= 0)
+ {
+ if (to == 0)
+ {
+ to = len;
+ }
+ else if (from >= to)
+ {
+ return 0;
+ }
+ if (from == 0 && to == len)
+ {
+ str = instance;
+ }
+ else
+ {
+ str = instance.Substring(from, to - from);
+ }
+ }
+ else
+ {
+ return 0;
+ }
+
+ int c = 0;
+ int idx;
+
+ do
+ {
+ idx = str.IndexOf(what, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
+ if (idx != -1)
+ {
+ str = str.Substring(idx + slen);
+ ++c;
+ }
+ } while (idx != -1);
+
+ return c;
+ }
+
+ // <summary>
// Return a copy of the string with special characters escaped using the C language standard.
// </summary>
public static string CEscape(this string instance)
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index abb7b391d3..75ce422e9e 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -519,7 +519,9 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
int total_out_before = strm.total_out;
- deflate(&strm, Z_FULL_FLUSH);
+ int err = deflate(&strm, Z_FULL_FLUSH);
+ ERR_FAIL_COND_V(err >= 0, ERR_BUG); // Negative means bug
+
bh.compressed_size = strm.total_out - total_out_before;
//package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before);
diff --git a/platform/x11/joypad_linux.cpp b/platform/x11/joypad_linux.cpp
index e6328ee14d..4242952374 100644
--- a/platform/x11/joypad_linux.cpp
+++ b/platform/x11/joypad_linux.cpp
@@ -513,6 +513,8 @@ void JoypadLinux::process_joypads() {
break;
default:
+ if (ev.code >= MAX_ABS)
+ return;
if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) {
InputDefault::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value);
joy->curr_axis[joy->abs_map[ev.code]] = value;
diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp
index 758bd84114..c33c77e16b 100644
--- a/platform/x11/power_x11.cpp
+++ b/platform/x11/power_x11.cpp
@@ -268,9 +268,7 @@ bool PowerX11::GetPowerInfo_Linux_proc_acpi() {
check_proc_acpi_battery(node.utf8().get_data(), &have_battery, &charging /*, seconds, percent*/);
node = dirp->get_next();
}
- memdelete(dirp);
}
-
dirp->change_dir(proc_acpi_ac_adapter_path);
err = dirp->list_dir_begin();
if (err != OK) {
@@ -281,7 +279,6 @@ bool PowerX11::GetPowerInfo_Linux_proc_acpi() {
check_proc_acpi_ac_adapter(node.utf8().get_data(), &have_ac);
node = dirp->get_next();
}
- memdelete(dirp);
}
if (!have_battery) {
@@ -294,6 +291,7 @@ bool PowerX11::GetPowerInfo_Linux_proc_acpi() {
this->power_state = OS::POWERSTATE_ON_BATTERY;
}
+ memdelete(dirp);
return true; /* definitive answer. */
}
diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp
index 71addd6fea..99ecc8bc37 100644
--- a/scene/main/instance_placeholder.cpp
+++ b/scene/main/instance_placeholder.cpp
@@ -92,6 +92,8 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene
if (!ps.is_valid())
return NULL;
Node *scene = ps->instance();
+ if (!scene)
+ return NULL;
scene->set_name(get_name());
int pos = get_position_in_parent();
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 2badf19f2b..dbf3150ae0 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -1507,8 +1507,11 @@ void SceneTree::_live_edit_instance_node_func(const NodePath &p_parent, const St
Node *n2 = n->get_node(p_parent);
Node *no = ps->instance();
- no->set_name(p_name);
+ if (!no) {
+ continue;
+ }
+ no->set_name(p_name);
n2->add_child(no);
}
}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index cafc7a0f00..4585e7fdcc 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1624,13 +1624,13 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- void set_comparsion_type(ComparsionType p_func);
+ void set_comparsion_type(ComparsionType p_type);
ComparsionType get_comparsion_type() const;
void set_function(Function p_func);
Function get_function() const;
- void set_condition(Condition p_mode);
+ void set_condition(Condition p_cond);
Condition get_condition() const;
virtual Vector<StringName> get_editable_properties() const;
diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index c250f2e2bd..ec3182685f 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -70,7 +70,7 @@
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice and this license appear in all source copies.
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF
-* ANY KIND. See http://www.dspguru.com/wol.htm for more information.
+* ANY KIND. See https://dspguru.com/wide-open-license/ for more information.
*
*****************************************************************************/
diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp
index a13fa65009..d0f8fd8aff 100644
--- a/servers/physics/collision_solver_sat.cpp
+++ b/servers/physics/collision_solver_sat.cpp
@@ -274,8 +274,8 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po
points_B = p_points_B;
}
- int version_A = (pointcount_A > 3 ? 3 : pointcount_A) - 1;
- int version_B = (pointcount_B > 3 ? 3 : pointcount_B) - 1;
+ int version_A = (pointcount_A > 2 ? 2 : pointcount_A) - 1;
+ int version_B = (pointcount_B > 2 ? 2 : pointcount_B) - 1;
GenerateContactsFunc contacts_func = generate_contacts_func_table[version_A][version_B];
ERR_FAIL_COND(!contacts_func);
diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp
index 0d10dae8cc..d970dd39fb 100644
--- a/servers/physics/collision_solver_sw.cpp
+++ b/servers/physics/collision_solver_sw.cpp
@@ -233,8 +233,6 @@ bool CollisionSolverSW::solve_static(const ShapeSW *p_shape_A, const Transform &
return collision_solver(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, r_sep_axis, p_margin_A, p_margin_B);
}
-
- return false;
}
void CollisionSolverSW::concave_distance_callback(void *p_userdata, ShapeSW *p_convex) {
@@ -371,6 +369,4 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform
return gjk_epa_calculate_distance(p_shape_A, p_transform_A, p_shape_B, p_transform_B, r_point_A, r_point_B); //should pass sepaxis..
}
-
- return false;
}
diff --git a/servers/physics/joints/hinge_joint_sw.cpp b/servers/physics/joints/hinge_joint_sw.cpp
index 1d1b30286e..209cddda5e 100644
--- a/servers/physics/joints/hinge_joint_sw.cpp
+++ b/servers/physics/joints/hinge_joint_sw.cpp
@@ -198,7 +198,6 @@ bool HingeJointSW::setup(real_t p_step) {
plane_space(m_rbAFrame.basis.get_axis(2), jointAxis0local, jointAxis1local);
- A->get_transform().basis.xform(m_rbAFrame.basis.get_axis(2));
Vector3 jointAxis0 = A->get_transform().basis.xform(jointAxis0local);
Vector3 jointAxis1 = A->get_transform().basis.xform(jointAxis1local);
Vector3 hingeAxisWorld = A->get_transform().basis.xform(m_rbAFrame.basis.get_axis(2));
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index 60bbcef4b6..5dff655ea1 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -185,28 +185,28 @@ real_t Body2DSW::get_param(Physics2DServer::BodyParameter p_param) const {
case Physics2DServer::BODY_PARAM_BOUNCE: {
return bounce;
- } break;
+ }
case Physics2DServer::BODY_PARAM_FRICTION: {
return friction;
- } break;
+ }
case Physics2DServer::BODY_PARAM_MASS: {
return mass;
- } break;
+ }
case Physics2DServer::BODY_PARAM_INERTIA: {
return _inv_inertia == 0 ? 0 : 1.0 / _inv_inertia;
- } break;
+ }
case Physics2DServer::BODY_PARAM_GRAVITY_SCALE: {
return gravity_scale;
- } break;
+ }
case Physics2DServer::BODY_PARAM_LINEAR_DAMP: {
return linear_damp;
- } break;
+ }
case Physics2DServer::BODY_PARAM_ANGULAR_DAMP: {
return angular_damp;
- } break;
+ }
default: {
}
}
@@ -343,19 +343,19 @@ Variant Body2DSW::get_state(Physics2DServer::BodyState p_state) const {
switch (p_state) {
case Physics2DServer::BODY_STATE_TRANSFORM: {
return get_transform();
- } break;
+ }
case Physics2DServer::BODY_STATE_LINEAR_VELOCITY: {
return linear_velocity;
- } break;
+ }
case Physics2DServer::BODY_STATE_ANGULAR_VELOCITY: {
return angular_velocity;
- } break;
+ }
case Physics2DServer::BODY_STATE_SLEEPING: {
return !is_active();
- } break;
+ }
case Physics2DServer::BODY_STATE_CAN_SLEEP: {
return can_sleep;
- } break;
+ }
}
return Variant();
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
index 1bbb50c974..6dd19c2868 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
@@ -673,7 +673,7 @@ public IEnumerable<Point3D> GetCellsOnRay(Ray ray, int maxDepth)
// "A Fast Voxel Traversal Algorithm for Ray Tracing"
// John Amanatides, Andrew Woo
// http://www.cse.yorku.ca/~amana/research/grid.pdf
- // http://www.devmaster.net/articles/raytracing_series/A%20faster%20voxel%20traversal%20algorithm%20for%20ray%20tracing.pdf
+ // https://web.archive.org/web/20100616193049/http://www.devmaster.net/articles/raytracing_series/A%20faster%20voxel%20traversal%20algorithm%20for%20ray%20tracing.pdf
// NOTES:
// * This code assumes that the ray's position and direction are in 'cell coordinates', which means
diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp
index 9d75f71ff0..19e4b8c1d9 100644
--- a/servers/physics_2d/collision_solver_2d_sat.cpp
+++ b/servers/physics_2d/collision_solver_2d_sat.cpp
@@ -172,8 +172,8 @@ static void _generate_contacts_from_supports(const Vector2 *p_points_A, int p_po
points_B = p_points_B;
}
- int version_A = (pointcount_A > 3 ? 3 : pointcount_A) - 1;
- int version_B = (pointcount_B > 3 ? 3 : pointcount_B) - 1;
+ int version_A = (pointcount_A > 2 ? 2 : pointcount_A) - 1;
+ int version_B = (pointcount_B > 2 ? 2 : pointcount_B) - 1;
GenerateContactsFunc contacts_func = generate_contacts_func_table[version_A][version_B];
ERR_FAIL_COND(!contacts_func);
diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp
index e49961c048..03c0fd5981 100644
--- a/servers/physics_2d/collision_solver_2d_sw.cpp
+++ b/servers/physics_2d/collision_solver_2d_sw.cpp
@@ -249,6 +249,4 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
return collision_solver(p_shape_A, p_transform_A, p_motion_A, p_shape_B, p_transform_B, p_motion_B, p_result_callback, p_userdata, false, sep_axis, margin_A, margin_B);
}
-
- return false;
}
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 14fefbf195..25973aa295 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -967,7 +967,7 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String
bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type) {
bool valid = false;
- DataType ret_type;
+ DataType ret_type = TYPE_VOID;
switch (p_op->op) {
case OP_EQUAL:
@@ -3059,7 +3059,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
String ident = identifier;
bool ok = true;
- DataType member_type;
+ DataType member_type = TYPE_VOID;
switch (dt) {
case TYPE_BVEC2:
case TYPE_IVEC2:
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index c6468694fd..25e18d0623 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1118,7 +1118,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim
}
offsets[i] = elem_size;
continue;
- } break;
+ }
default: {
ERR_FAIL();
}
@@ -1286,7 +1286,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
}
offsets[i] = elem_size;
continue;
- } break;
+ }
default: {
ERR_FAIL_V(Array());
}