Skip to content

Commit

Permalink
Merge pull request #57186 from lawnjelly/gameplay_fix_ticks
Browse files Browse the repository at this point in the history
  • Loading branch information
akien-mga authored Jan 25, 2022
2 parents cb9854d + 38240fd commit d62166f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 36 deletions.
67 changes: 36 additions & 31 deletions servers/visual/portals/portal_gameplay_monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void PortalGameplayMonitor::unload(PortalRenderer &p_portal_renderer) {
for (int n = 0; n < _active_room_ids_prev->size(); n++) {
int room_id = (*_active_room_ids_prev)[n];
VSRoom &room = p_portal_renderer.get_room(room_id);
room.last_gameplay_tick_hit = 0;
room.last_room_tick_hit = 0;

VisualServerCallbacks::Message msg;
msg.object_id = room._godot_instance_ID;
Expand All @@ -121,7 +121,7 @@ void PortalGameplayMonitor::unload(PortalRenderer &p_portal_renderer) {
for (int n = 0; n < _active_roomgroup_ids_prev->size(); n++) {
int roomgroup_id = (*_active_roomgroup_ids_prev)[n];
VSRoomGroup &roomgroup = p_portal_renderer.get_roomgroup(roomgroup_id);
roomgroup.last_gameplay_tick_hit = 0;
roomgroup.last_room_tick_hit = 0;

VisualServerCallbacks::Message msg;
msg.object_id = roomgroup._godot_instance_ID;
Expand All @@ -133,7 +133,7 @@ void PortalGameplayMonitor::unload(PortalRenderer &p_portal_renderer) {
for (int n = 0; n < _active_sghost_ids_prev->size(); n++) {
int id = (*_active_sghost_ids_prev)[n];
VSStaticGhost &ghost = p_portal_renderer.get_static_ghost(id);
ghost.last_gameplay_tick_hit = 0;
ghost.last_room_tick_hit = 0;

VisualServerCallbacks::Message msg;
msg.object_id = ghost.object_id;
Expand Down Expand Up @@ -185,6 +185,9 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
// if there is no change in the source room IDs, then we can optimize out a lot of the checks
// (anything not to do with roamers)
bool source_rooms_changed = _source_rooms_changed(p_source_room_ids, p_num_source_rooms);
if (source_rooms_changed) {
_room_tick++;
}

// lock output
VisualServerCallbacks *callbacks = VSG::scene->get_callbacks();
Expand Down Expand Up @@ -249,7 +252,7 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
const VSRoom &room = p_portal_renderer.get_room(room_id);

// gone out of view
if (room.last_gameplay_tick_hit != _gameplay_tick) {
if (room.last_room_tick_hit != _room_tick) {
VisualServerCallbacks::Message msg;
msg.object_id = room._godot_instance_ID;
msg.type = _exit_callback_type;
Expand All @@ -264,7 +267,7 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
const VSRoomGroup &roomgroup = p_portal_renderer.get_roomgroup(roomgroup_id);

// gone out of view
if (roomgroup.last_gameplay_tick_hit != _gameplay_tick) {
if (roomgroup.last_room_tick_hit != _room_tick) {
VisualServerCallbacks::Message msg;
msg.object_id = roomgroup._godot_instance_ID;
msg.type = _exit_callback_type;
Expand All @@ -279,7 +282,7 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
VSStaticGhost &ghost = p_portal_renderer.get_static_ghost(id);

// gone out of view
if (ghost.last_gameplay_tick_hit != _gameplay_tick) {
if (ghost.last_room_tick_hit != _room_tick) {
VisualServerCallbacks::Message msg;
msg.object_id = ghost.object_id;
msg.type = VisualServerCallbacks::CALLBACK_NOTIFICATION_EXIT_GAMEPLAY;
Expand All @@ -293,7 +296,7 @@ void PortalGameplayMonitor::update_gameplay(PortalRenderer &p_portal_renderer, c
callbacks->unlock();

// swap the current and previous lists
_swap();
_swap(source_rooms_changed);
}

void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_renderer, int p_room_id, bool p_source_rooms_changed) {
Expand Down Expand Up @@ -367,14 +370,14 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
// later tests only relevant if a room has just come into play
bool room_came_into_play = false;

if (room.last_gameplay_tick_hit != _gameplay_tick) {
if (room.last_room_tick_hit != _room_tick) {
room_came_into_play = true;

// add the room to the active list
_active_room_ids_curr->push_back(p_room_id);

// if wasn't present in the tick before, add the notification to enter
if (room.last_gameplay_tick_hit != (_gameplay_tick - 1)) {
if (room.last_room_tick_hit != (_room_tick - 1)) {
VisualServerCallbacks::Message msg;
msg.object_id = room._godot_instance_ID;
msg.type = _enter_callback_type;
Expand All @@ -383,7 +386,7 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
}

// mark as done
room.last_gameplay_tick_hit = _gameplay_tick;
room.last_room_tick_hit = _room_tick;
}

// no need to do later tests
Expand All @@ -398,12 +401,12 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende

VSRoomGroup &roomgroup = p_portal_renderer.get_roomgroup(roomgroup_id);

if (roomgroup.last_gameplay_tick_hit != _gameplay_tick) {
if (roomgroup.last_room_tick_hit != _room_tick) {
// add the room to the active list
_active_roomgroup_ids_curr->push_back(roomgroup_id);

// if wasn't present in the tick before, add the notification to enter
if (roomgroup.last_gameplay_tick_hit != (_gameplay_tick - 1)) {
if (roomgroup.last_room_tick_hit != (_room_tick - 1)) {
VisualServerCallbacks::Message msg;
msg.object_id = roomgroup._godot_instance_ID;
msg.type = _enter_callback_type;
Expand All @@ -412,7 +415,7 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
}

// mark as done
roomgroup.last_gameplay_tick_hit = _gameplay_tick;
roomgroup.last_room_tick_hit = _room_tick;
}
} // for through roomgroups

Expand All @@ -425,14 +428,14 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
VSStaticGhost &ghost = p_portal_renderer.get_static_ghost(id);

// done already?
if (ghost.last_gameplay_tick_hit == _gameplay_tick)
if (ghost.last_room_tick_hit == _room_tick)
continue;

// add to the active list
_active_sghost_ids_curr->push_back(id);

// if wasn't present in the tick before, add the notification to enter
if (ghost.last_gameplay_tick_hit != (_gameplay_tick - 1)) {
if (ghost.last_room_tick_hit != (_room_tick - 1)) {
VisualServerCallbacks::Message msg;
msg.object_id = ghost.object_id;
msg.type = VisualServerCallbacks::CALLBACK_NOTIFICATION_ENTER_GAMEPLAY;
Expand All @@ -441,11 +444,11 @@ void PortalGameplayMonitor::_update_gameplay_room(PortalRenderer &p_portal_rende
}

// mark as done
ghost.last_gameplay_tick_hit = _gameplay_tick;
ghost.last_room_tick_hit = _room_tick;
}
}

void PortalGameplayMonitor::_swap() {
void PortalGameplayMonitor::_swap(bool p_source_rooms_changed) {
LocalVector<uint32_t, int32_t> *temp = _active_moving_pool_ids_curr;
_active_moving_pool_ids_curr = _active_moving_pool_ids_prev;
_active_moving_pool_ids_prev = temp;
Expand All @@ -456,18 +459,20 @@ void PortalGameplayMonitor::_swap() {
_active_rghost_pool_ids_prev = temp;
_active_rghost_pool_ids_curr->clear();

temp = _active_room_ids_curr;
_active_room_ids_curr = _active_room_ids_prev;
_active_room_ids_prev = temp;
_active_room_ids_curr->clear();

temp = _active_roomgroup_ids_curr;
_active_roomgroup_ids_curr = _active_roomgroup_ids_prev;
_active_roomgroup_ids_prev = temp;
_active_roomgroup_ids_curr->clear();

temp = _active_sghost_ids_curr;
_active_sghost_ids_curr = _active_sghost_ids_prev;
_active_sghost_ids_prev = temp;
_active_sghost_ids_curr->clear();
if (p_source_rooms_changed) {
temp = _active_room_ids_curr;
_active_room_ids_curr = _active_room_ids_prev;
_active_room_ids_prev = temp;
_active_room_ids_curr->clear();

temp = _active_roomgroup_ids_curr;
_active_roomgroup_ids_curr = _active_roomgroup_ids_prev;
_active_roomgroup_ids_prev = temp;
_active_roomgroup_ids_curr->clear();

temp = _active_sghost_ids_curr;
_active_sghost_ids_curr = _active_sghost_ids_prev;
_active_sghost_ids_prev = temp;
_active_sghost_ids_curr->clear();
}
}
9 changes: 8 additions & 1 deletion servers/visual/portals/portal_gameplay_monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,17 @@ class PortalGameplayMonitor {
private:
void _update_gameplay_room(PortalRenderer &p_portal_renderer, int p_room_id, bool p_source_rooms_changed);
bool _source_rooms_changed(const int *p_source_room_ids, int p_num_source_rooms);
void _swap();
void _swap(bool p_source_rooms_changed);

// gameplay ticks happen every physics tick
uint32_t _gameplay_tick = 1;

// Room ticks only happen when the rooms the cameras are within change.
// This is an optimization. This tick needs to be maintained separately from _gameplay_tick
// because testing against the previous tick is used to determine whether to send enter or exit
// gameplay notifications, and this must be synchronized differently for rooms, roomgroups and static ghosts.
uint32_t _room_tick = 1;

// we need two version, current and previous
LocalVector<uint32_t, int32_t> _active_moving_pool_ids[2];
LocalVector<uint32_t, int32_t> *_active_moving_pool_ids_curr;
Expand Down
2 changes: 1 addition & 1 deletion servers/visual/portals/portal_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct VSStaticGhost {
ObjectID object_id;

uint32_t last_tick_hit = 0;
uint32_t last_gameplay_tick_hit = 0;
uint32_t last_room_tick_hit = 0;
};

class PortalRenderer {
Expand Down
6 changes: 3 additions & 3 deletions servers/visual/portals/portal_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ struct VSRoomGroup {
}

// used for calculating gameplay notifications
uint32_t last_gameplay_tick_hit = 0;
uint32_t last_room_tick_hit = 0;

ObjectID _godot_instance_ID = 0;

Expand Down Expand Up @@ -257,7 +257,7 @@ struct VSRoom {
_secondary_pvs_size = 0;
_priority = 0;
_contains_internal_rooms = false;
last_gameplay_tick_hit = 0;
last_room_tick_hit = 0;
}

void cleanup_after_conversion() {
Expand Down Expand Up @@ -354,7 +354,7 @@ struct VSRoom {
uint16_t _secondary_pvs_size = 0;

// used for calculating gameplay notifications
uint32_t last_gameplay_tick_hit = 0;
uint32_t last_room_tick_hit = 0;

// convex hull of the room, either determined by geometry or manual bound
LocalVector<Plane, int32_t> _planes;
Expand Down

0 comments on commit d62166f

Please sign in to comment.