Flushes commands just before the navigation server is destroyed

This commit is contained in:
Andrea Catania 2020-02-26 09:42:51 +01:00
parent 2ca5f22bce
commit c143b5c677
6 changed files with 33 additions and 16 deletions

View File

@ -358,13 +358,15 @@
Control activation of this server. Control activation of this server.
</description> </description>
</method> </method>
<method name="step"> <method name="process">
<return type="void"> <return type="void">
</return> </return>
<argument index="0" name="delta_time" type="float"> <argument index="0" name="delta_time" type="float">
</argument> </argument>
<description> <description>
Steps the server. This is not threadsafe and must be called in single thread. Process the collision avoidance agents.
The result of this process is needed by the physics server, so this must be called in the main thread.
Note: This function is not thread safe.
</description> </description>
</method> </method>
</methods> </methods>

View File

@ -203,6 +203,7 @@ void finalize_physics() {
void initialize_navigation_server() { void initialize_navigation_server() {
ERR_FAIL_COND(navigation_server != NULL); ERR_FAIL_COND(navigation_server != NULL);
navigation_server = NavigationServerManager::new_default_server(); navigation_server = NavigationServerManager::new_default_server();
navigation_2d_server = memnew(Navigation2DServer); navigation_2d_server = memnew(Navigation2DServer);
} }
@ -210,6 +211,7 @@ void initialize_navigation_server() {
void finalize_navigation_server() { void finalize_navigation_server() {
memdelete(navigation_server); memdelete(navigation_server);
navigation_server = NULL; navigation_server = NULL;
memdelete(navigation_2d_server); memdelete(navigation_2d_server);
navigation_2d_server = NULL; navigation_2d_server = NULL;
} }
@ -2037,9 +2039,9 @@ bool Main::iteration() {
break; break;
} }
message_queue->flush(); NavigationServer::get_singleton_mut()->process(frame_slice * time_scale);
NavigationServer::get_singleton_mut()->step(frame_slice * time_scale); message_queue->flush();
PhysicsServer::get_singleton()->step(frame_slice * time_scale); PhysicsServer::get_singleton()->step(frame_slice * time_scale);

View File

@ -121,6 +121,7 @@ GdNavigationServer::GdNavigationServer() :
} }
GdNavigationServer::~GdNavigationServer() { GdNavigationServer::~GdNavigationServer() {
flush_queries();
memdelete(operations_mutex); memdelete(operations_mutex);
memdelete(commands_mutex); memdelete(commands_mutex);
} }
@ -474,12 +475,9 @@ void GdNavigationServer::set_active(bool p_active) const {
mut_this->operations_mutex->unlock(); mut_this->operations_mutex->unlock();
} }
void GdNavigationServer::step(real_t p_delta_time) { void GdNavigationServer::flush_queries() {
if (!active) { // In c++ we can't be sure that this is performed in the main thread
return; // even with mutable functions.
}
// With c++ we can't be 100% sure this is called in single thread so use the mutex.
commands_mutex->lock(); commands_mutex->lock();
operations_mutex->lock(); operations_mutex->lock();
for (size_t i(0); i < commands.size(); i++) { for (size_t i(0); i < commands.size(); i++) {
@ -489,13 +487,24 @@ void GdNavigationServer::step(real_t p_delta_time) {
commands.clear(); commands.clear();
operations_mutex->unlock(); operations_mutex->unlock();
commands_mutex->unlock(); commands_mutex->unlock();
}
// These are internal operations so don't need to be shielded. void GdNavigationServer::process(real_t p_delta_time) {
flush_queries();
if (!active) {
return;
}
// In c++ we can't be sure that this is performed in the main thread
// even with mutable functions.
operations_mutex->lock();
for (int i(0); i < active_maps.size(); i++) { for (int i(0); i < active_maps.size(); i++) {
active_maps[i]->sync(); active_maps[i]->sync();
active_maps[i]->step(p_delta_time); active_maps[i]->step(p_delta_time);
active_maps[i]->dispatch_callbacks(); active_maps[i]->dispatch_callbacks();
} }
operations_mutex->unlock();
} }
#undef COMMAND_1 #undef COMMAND_1

View File

@ -131,7 +131,9 @@ public:
COMMAND_1(free, RID, p_object); COMMAND_1(free, RID, p_object);
virtual void set_active(bool p_active) const; virtual void set_active(bool p_active) const;
virtual void step(real_t p_delta_time);
void flush_queries();
virtual void process(real_t p_delta_time);
}; };
#undef COMMAND_1 #undef COMMAND_1

View File

@ -75,7 +75,7 @@ void NavigationServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("free", "object"), &NavigationServer::free); ClassDB::bind_method(D_METHOD("free", "object"), &NavigationServer::free);
ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer::set_active); ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer::set_active);
ClassDB::bind_method(D_METHOD("step", "delta_time"), &NavigationServer::step); ClassDB::bind_method(D_METHOD("process", "delta_time"), &NavigationServer::process);
} }
const NavigationServer *NavigationServer::get_singleton() { const NavigationServer *NavigationServer::get_singleton() {

View File

@ -175,9 +175,11 @@ public:
/// Control activation of this server. /// Control activation of this server.
virtual void set_active(bool p_active) const = 0; virtual void set_active(bool p_active) const = 0;
/// Step the server /// Process the collision avoidance agents.
/// NOTE: This function is not Threadsafe and MUST be called in single thread. /// The result of this process is needed by the physics server,
virtual void step(real_t delta_time) = 0; /// so this must be called in the main thread.
/// Note: This function is not thread safe.
virtual void process(real_t delta_time) = 0;
NavigationServer(); NavigationServer();
virtual ~NavigationServer(); virtual ~NavigationServer();