Skip to content

Commit

Permalink
Make NavMap objects request sync only on demand
Browse files Browse the repository at this point in the history
Replaces brute-force sync check loop with a self-listing system where each object is responsible for its own dirty sync, requesting it on demand only.
  • Loading branch information
smix8 committed Nov 24, 2024
1 parent 0c45ace commit 3ddc9d0
Show file tree
Hide file tree
Showing 10 changed files with 348 additions and 79 deletions.
63 changes: 57 additions & 6 deletions modules/navigation/nav_agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@

#include "nav_map.h"

NavAgent::NavAgent() {
}

void NavAgent::set_avoidance_enabled(bool p_enabled) {
avoidance_enabled = p_enabled;
_update_rvo_agent_properties();
Expand Down Expand Up @@ -87,13 +84,17 @@ void NavAgent::_update_rvo_agent_properties() {
}
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_map(NavMap *p_map) {
if (map == p_map) {
return;
}

cancel_sync_request();

if (map) {
map->remove_agent(this);
}
Expand All @@ -106,6 +107,8 @@ void NavAgent::set_map(NavMap *p_map) {
if (avoidance_enabled) {
map->set_agent_as_controlled(this);
}

request_sync();
}
}

Expand Down Expand Up @@ -156,6 +159,8 @@ void NavAgent::set_neighbor_distance(real_t p_neighbor_distance) {
rvo_agent_2d.neighborDist_ = neighbor_distance;
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_max_neighbors(int p_max_neighbors) {
Expand All @@ -166,6 +171,8 @@ void NavAgent::set_max_neighbors(int p_max_neighbors) {
rvo_agent_2d.maxNeighbors_ = max_neighbors;
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_time_horizon_agents(real_t p_time_horizon) {
Expand All @@ -176,6 +183,8 @@ void NavAgent::set_time_horizon_agents(real_t p_time_horizon) {
rvo_agent_2d.timeHorizon_ = time_horizon_agents;
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_time_horizon_obstacles(real_t p_time_horizon) {
Expand All @@ -186,6 +195,8 @@ void NavAgent::set_time_horizon_obstacles(real_t p_time_horizon) {
rvo_agent_2d.timeHorizonObst_ = time_horizon_obstacles;
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_radius(real_t p_radius) {
Expand All @@ -196,6 +207,8 @@ void NavAgent::set_radius(real_t p_radius) {
rvo_agent_2d.radius_ = radius;
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_height(real_t p_height) {
Expand All @@ -206,6 +219,8 @@ void NavAgent::set_height(real_t p_height) {
rvo_agent_2d.height_ = height;
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_max_speed(real_t p_max_speed) {
Expand All @@ -218,6 +233,8 @@ void NavAgent::set_max_speed(real_t p_max_speed) {
}
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_position(const Vector3 p_position) {
Expand All @@ -231,6 +248,8 @@ void NavAgent::set_position(const Vector3 p_position) {
}
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_target_position(const Vector3 p_target_position) {
Expand All @@ -249,6 +268,8 @@ void NavAgent::set_velocity(const Vector3 p_velocity) {
}
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_velocity_forced(const Vector3 p_velocity) {
Expand All @@ -265,6 +286,8 @@ void NavAgent::set_velocity_forced(const Vector3 p_velocity) {
}
}
agent_dirty = true;

request_sync();
}

void NavAgent::update() {
Expand All @@ -286,6 +309,8 @@ void NavAgent::set_avoidance_mask(uint32_t p_mask) {
rvo_agent_2d.avoidance_mask_ = avoidance_mask;
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_avoidance_layers(uint32_t p_layers) {
Expand All @@ -296,6 +321,8 @@ void NavAgent::set_avoidance_layers(uint32_t p_layers) {
rvo_agent_2d.avoidance_layers_ = avoidance_layers;
}
agent_dirty = true;

request_sync();
}

void NavAgent::set_avoidance_priority(real_t p_priority) {
Expand All @@ -308,12 +335,16 @@ void NavAgent::set_avoidance_priority(real_t p_priority) {
rvo_agent_2d.avoidance_priority_ = avoidance_priority;
}
agent_dirty = true;

request_sync();
}

bool NavAgent::is_dirty() const {
return agent_dirty;
}

bool NavAgent::check_dirty() {
const bool was_dirty = agent_dirty;
void NavAgent::sync() {
agent_dirty = false;
return was_dirty;
}

const Dictionary NavAgent::get_avoidance_data() const {
Expand Down Expand Up @@ -372,3 +403,23 @@ void NavAgent::set_paused(bool p_paused) {
bool NavAgent::get_paused() const {
return paused;
}

void NavAgent::request_sync() {
if (map && !sync_dirty_request_list_element.in_list()) {
map->add_agent_sync_dirty_request(&sync_dirty_request_list_element);
}
}

void NavAgent::cancel_sync_request() {
if (map && sync_dirty_request_list_element.in_list()) {
map->remove_agent_sync_dirty_request(&sync_dirty_request_list_element);
}
}

NavAgent::NavAgent() :
sync_dirty_request_list_element(this) {
}

NavAgent::~NavAgent() {
cancel_sync_request();
}
9 changes: 8 additions & 1 deletion modules/navigation/nav_agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "core/object/class_db.h"
#include "core/templates/local_vector.h"
#include "core/templates/self_list.h"

#include <Agent2d.h>
#include <Agent3d.h>
Expand Down Expand Up @@ -74,8 +75,11 @@ class NavAgent : public NavRid {
uint32_t last_map_iteration_id = 0;
bool paused = false;

SelfList<NavAgent> sync_dirty_request_list_element;

public:
NavAgent();
~NavAgent();

void set_avoidance_enabled(bool p_enabled);
bool is_avoidance_enabled() { return avoidance_enabled; }
Expand Down Expand Up @@ -141,7 +145,10 @@ class NavAgent : public NavRid {
void set_paused(bool p_paused);
bool get_paused() const;

bool check_dirty();
bool is_dirty() const;
void sync();
void request_sync();
void cancel_sync_request();

// Updates this agent with rvo data after the rvo simulation avoidance step.
void update();
Expand Down
39 changes: 36 additions & 3 deletions modules/navigation/nav_link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ void NavLink::set_map(NavMap *p_map) {
return;
}

cancel_sync_request();

if (map) {
map->remove_link(this);
}
Expand All @@ -46,6 +48,7 @@ void NavLink::set_map(NavMap *p_map) {

if (map) {
map->add_link(this);
request_sync();
}
}

Expand All @@ -57,6 +60,8 @@ void NavLink::set_enabled(bool p_enabled) {

// TODO: This should not require a full rebuild as the link has not really changed.
link_dirty = true;

request_sync();
}

void NavLink::set_bidirectional(bool p_bidirectional) {
Expand All @@ -65,6 +70,8 @@ void NavLink::set_bidirectional(bool p_bidirectional) {
}
bidirectional = p_bidirectional;
link_dirty = true;

request_sync();
}

void NavLink::set_start_position(const Vector3 p_position) {
Expand All @@ -73,6 +80,8 @@ void NavLink::set_start_position(const Vector3 p_position) {
}
start_position = p_position;
link_dirty = true;

request_sync();
}

void NavLink::set_end_position(const Vector3 p_position) {
Expand All @@ -81,11 +90,35 @@ void NavLink::set_end_position(const Vector3 p_position) {
}
end_position = p_position;
link_dirty = true;

request_sync();
}

bool NavLink::check_dirty() {
const bool was_dirty = link_dirty;
bool NavLink::is_dirty() const {
return link_dirty;
}

void NavLink::sync() {
link_dirty = false;
return was_dirty;
}

void NavLink::request_sync() {
if (map && !sync_dirty_request_list_element.in_list()) {
map->add_link_sync_dirty_request(&sync_dirty_request_list_element);
}
}

void NavLink::cancel_sync_request() {
if (map && sync_dirty_request_list_element.in_list()) {
map->remove_link_sync_dirty_request(&sync_dirty_request_list_element);
}
}

NavLink::NavLink() :
sync_dirty_request_list_element(this) {
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK;
}

NavLink::~NavLink() {
cancel_sync_request();
}
15 changes: 11 additions & 4 deletions modules/navigation/nav_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include "nav_base.h"
#include "nav_utils.h"

#include "core/templates/self_list.h"

class NavLink : public NavBase {
NavMap *map = nullptr;
bool bidirectional = true;
Expand All @@ -43,10 +45,11 @@ class NavLink : public NavBase {

bool link_dirty = true;

SelfList<NavLink> sync_dirty_request_list_element;

public:
NavLink() {
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK;
}
NavLink();
~NavLink();

void set_map(NavMap *p_map);
NavMap *get_map() const {
Expand All @@ -71,7 +74,11 @@ class NavLink : public NavBase {
return end_position;
}

bool check_dirty();
bool is_dirty() const;
void sync();
void request_sync();
void cancel_sync_request();

};

#endif // NAV_LINK_H
Loading

0 comments on commit 3ddc9d0

Please sign in to comment.