diff options
author | Juan Linietsky <reduzio@gmail.com> | 2018-11-16 08:49:26 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2018-11-16 08:49:26 -0300 |
commit | 0b1e93ccd43815d93de031b4f23fbfcd9ae7a34c (patch) | |
tree | d0d09cf6c744eb61438ed6ce775eafed22f5b4a1 | |
parent | 26d33d1c6eedf9271bac20a24ea37453c21ef890 (diff) |
-Make sure monitorable cant be flipped while flushing queries, fixes #17330
-Also added set_deferred, this was missing.
-rw-r--r-- | core/object.cpp | 6 | ||||
-rw-r--r-- | core/object.h | 1 | ||||
-rw-r--r-- | modules/bullet/bullet_physics_server.h | 2 | ||||
-rw-r--r-- | scene/2d/area_2d.cpp | 8 | ||||
-rw-r--r-- | scene/3d/area.cpp | 8 | ||||
-rw-r--r-- | servers/physics/physics_server_sw.cpp | 17 | ||||
-rw-r--r-- | servers/physics/physics_server_sw.h | 4 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.cpp | 19 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.h | 4 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_wrap_mt.h | 4 | ||||
-rw-r--r-- | servers/physics_2d_server.h | 2 | ||||
-rw-r--r-- | servers/physics_server.h | 2 |
12 files changed, 69 insertions, 8 deletions
diff --git a/core/object.cpp b/core/object.cpp index 6a6749f3b8..1eff56f026 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1715,6 +1715,8 @@ void Object::_bind_methods() { ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_deferred", &Object::_call_deferred_bind, mi); } + ClassDB::bind_method(D_METHOD("set_deferred", "property", "value"), &Object::set_deferred); + ClassDB::bind_method(D_METHOD("callv", "method", "arg_array"), &Object::callv); ClassDB::bind_method(D_METHOD("has_method", "method"), &Object::has_method); @@ -1771,6 +1773,10 @@ void Object::call_deferred(const StringName &p_method, VARIANT_ARG_DECLARE) { MessageQueue::get_singleton()->push_call(this, p_method, VARIANT_ARG_PASS); } +void Object::set_deferred(const StringName &p_property, const Variant &p_value) { + MessageQueue::get_singleton()->push_set(this, p_property, p_value); +} + void Object::set_block_signals(bool p_block) { _block_signals = p_block; diff --git a/core/object.h b/core/object.h index 25d41140aa..88a98dacbe 100644 --- a/core/object.h +++ b/core/object.h @@ -698,6 +698,7 @@ public: bool is_connected(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const; void call_deferred(const StringName &p_method, VARIANT_ARG_LIST); + void set_deferred(const StringName &p_property, const Variant &p_value); void set_block_signals(bool p_block); bool is_blocking_signals() const; diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 6b7dcd86e6..c8c782267e 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -397,6 +397,8 @@ public: virtual void flush_queries(); virtual void finish(); + virtual bool is_flushing_queries() const { return false; } + virtual int get_process_info(ProcessInfo p_info); CollisionObjectBullet *get_collisin_object(RID p_object) const; diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 48537f3cfc..ae5891fa50 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -399,7 +399,7 @@ void Area2D::set_monitoring(bool p_enable) { if (p_enable == monitoring) return; if (locked) { - ERR_EXPLAIN("Function blocked during in/out signal. Use call_deferred(\"set_monitoring\",true/false)"); + ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitoring\",true/false)"); } ERR_FAIL_COND(locked); @@ -424,10 +424,10 @@ bool Area2D::is_monitoring() const { void Area2D::set_monitorable(bool p_enable) { - if (locked) { - ERR_EXPLAIN("This function can't be used during the in/out signal."); + if (locked || Physics2DServer::get_singleton()->is_flushing_queries()) { + ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitorable\",true/false)"); } - ERR_FAIL_COND(locked); + ERR_FAIL_COND(locked || Physics2DServer::get_singleton()->is_flushing_queries()); if (p_enable == monitorable) return; diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index 40a1029201..5e78368804 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -290,7 +290,7 @@ void Area::_notification(int p_what) { void Area::set_monitoring(bool p_enable) { if (locked) { - ERR_EXPLAIN("This function can't be used during the in/out signal."); + ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitoring\",true/false)"); } ERR_FAIL_COND(locked); @@ -437,10 +437,10 @@ Array Area::get_overlapping_bodies() const { void Area::set_monitorable(bool p_enable) { - if (locked) { - ERR_EXPLAIN("This function can't be used during the in/out signal."); + if (locked || PhysicsServer::get_singleton()->is_flushing_queries()) { + ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitorable\",true/false)"); } - ERR_FAIL_COND(locked); + ERR_FAIL_COND(locked || PhysicsServer::get_singleton()->is_flushing_queries()); if (p_enable == monitorable) return; diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 76a6138817..fddb531a4f 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -40,6 +40,12 @@ #include "joints/pin_joint_sw.h" #include "joints/slider_joint_sw.h" +#define FLUSH_QUERY_CHECK \ + if (flushing_queries) { \ + ERR_EXPLAIN("Can't change this state while flushing queries. Use call_deferred()/set_deferred() to change monitoring state instead"); \ + ERR_FAIL(); \ + } + RID PhysicsServerSW::shape_create(ShapeType p_shape) { ShapeSW *shape = NULL; @@ -352,6 +358,8 @@ void PhysicsServerSW::area_clear_shapes(RID p_area) { void PhysicsServerSW::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) { + FLUSH_QUERY_CHECK + AreaSW *area = area_owner.get(p_area); ERR_FAIL_COND(!area); ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count()); @@ -435,6 +443,8 @@ void PhysicsServerSW::area_set_collision_mask(RID p_area, uint32_t p_mask) { void PhysicsServerSW::area_set_monitorable(RID p_area, bool p_monitorable) { + FLUSH_QUERY_CHECK + AreaSW *area = area_owner.get(p_area); ERR_FAIL_COND(!area); @@ -582,6 +592,8 @@ RID PhysicsServerSW::body_get_shape(RID p_body, int p_shape_idx) const { void PhysicsServerSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { + FLUSH_QUERY_CHECK + BodySW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); @@ -1459,6 +1471,8 @@ void PhysicsServerSW::flush_queries() { doing_sync = true; + flushing_queries = true; + uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); for (Set<const SpaceSW *>::Element *E = active_spaces.front(); E; E = E->next()) { @@ -1467,6 +1481,8 @@ void PhysicsServerSW::flush_queries() { space->call_queries(); } + flushing_queries = false; + if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_profiling()) { uint64_t total_time[SpaceSW::ELAPSED_TIME_MAX]; @@ -1580,6 +1596,7 @@ PhysicsServerSW::PhysicsServerSW() { collision_pairs = 0; active = true; + flushing_queries = false; }; PhysicsServerSW::~PhysicsServerSW(){ diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index 4131c5e248..b3c61403aa 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -51,6 +51,8 @@ class PhysicsServerSW : public PhysicsServer { int active_objects; int collision_pairs; + bool flushing_queries; + StepSW *stepper; Set<const SpaceSW *> active_spaces; @@ -365,6 +367,8 @@ public: virtual void flush_queries(); virtual void finish(); + virtual bool is_flushing_queries() const { return flushing_queries; } + int get_process_info(ProcessInfo p_info); PhysicsServerSW(); diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index 2df09057c4..45310ec4b3 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -36,6 +36,12 @@ #include "core/project_settings.h" #include "core/script_language.h" +#define FLUSH_QUERY_CHECK \ + if (flushing_queries) { \ + ERR_EXPLAIN("Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead"); \ + ERR_FAIL(); \ + } + RID Physics2DServerSW::_shape_create(ShapeType p_shape) { Shape2DSW *shape = NULL; @@ -401,6 +407,8 @@ void Physics2DServerSW::area_set_shape_transform(RID p_area, int p_shape_idx, co void Physics2DServerSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) { + FLUSH_QUERY_CHECK + Area2DSW *area = area_owner.get(p_area); ERR_FAIL_COND(!area); @@ -539,6 +547,8 @@ void Physics2DServerSW::area_set_pickable(RID p_area, bool p_pickable) { void Physics2DServerSW::area_set_monitorable(RID p_area, bool p_monitorable) { + FLUSH_QUERY_CHECK + Area2DSW *area = area_owner.get(p_area); ERR_FAIL_COND(!area); @@ -617,6 +627,8 @@ RID Physics2DServerSW::body_get_space(RID p_body) const { void Physics2DServerSW::body_set_mode(RID p_body, BodyMode p_mode) { + FLUSH_QUERY_CHECK + Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); @@ -719,6 +731,8 @@ void Physics2DServerSW::body_clear_shapes(RID p_body) { void Physics2DServerSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { + FLUSH_QUERY_CHECK + Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); @@ -1348,6 +1362,8 @@ void Physics2DServerSW::flush_queries() { if (!active) return; + flushing_queries = true; + uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { @@ -1356,6 +1372,8 @@ void Physics2DServerSW::flush_queries() { space->call_queries(); } + flushing_queries = false; + if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_profiling()) { uint64_t total_time[Space2DSW::ELAPSED_TIME_MAX]; @@ -1434,6 +1452,7 @@ Physics2DServerSW::Physics2DServerSW() { active_objects = 0; collision_pairs = 0; using_threads = int(ProjectSettings::get_singleton()->get("physics/2d/thread_model")) == 2; + flushing_queries = false; }; Physics2DServerSW::~Physics2DServerSW(){ diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index f41c599579..4f33873219 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -54,6 +54,8 @@ class Physics2DServerSW : public Physics2DServer { bool using_threads; + bool flushing_queries; + Step2DSW *stepper; Set<const Space2DSW *> active_spaces; @@ -278,6 +280,8 @@ public: virtual void end_sync(); virtual void finish(); + virtual bool is_flushing_queries() const { return flushing_queries; } + int get_process_info(ProcessInfo p_info); Physics2DServerSW(); diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index 58517bf1a7..e736854077 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -312,6 +312,10 @@ public: virtual void flush_queries(); virtual void finish(); + virtual bool is_flushing_queries() const { + return physics_2d_server->is_flushing_queries(); + } + int get_process_info(ProcessInfo p_info) { return physics_2d_server->get_process_info(p_info); } diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 2e91d89c53..32e1dd1a08 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -584,6 +584,8 @@ public: virtual void end_sync() = 0; virtual void finish() = 0; + virtual bool is_flushing_queries() const = 0; + enum ProcessInfo { INFO_ACTIVE_OBJECTS, diff --git a/servers/physics_server.h b/servers/physics_server.h index d80d76305a..cbb325dea3 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -744,6 +744,8 @@ public: virtual void flush_queries() = 0; virtual void finish() = 0; + virtual bool is_flushing_queries() const = 0; + enum ProcessInfo { INFO_ACTIVE_OBJECTS, |