Skip to content

Commit

Permalink
perf(skymp5-server): avoid copying in DynamicFields.set (mp.set) (sky…
Browse files Browse the repository at this point in the history
  • Loading branch information
nic11 authored Dec 14, 2024
1 parent 6058819 commit b5a603d
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 44 deletions.
7 changes: 3 additions & 4 deletions skymp5-server/cpp/server_guest_lib/DynamicFields.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#include "DynamicFields.h"

#include <unordered_map>
#include <vector>

void DynamicFields::Set(const std::string& propName,
const nlohmann::json& value)
void DynamicFields::Set(const std::string& propName, nlohmann::json value)
{
jsonCache.reset();
props[propName] = value;
props[propName] = std::move(value);
}

const nlohmann::json& DynamicFields::Get(const std::string& propName) const
Expand Down
8 changes: 4 additions & 4 deletions skymp5-server/cpp/server_guest_lib/DynamicFields.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#pragma once
#include <cstdint>
#include <memory>
#include <nlohmann/json.hpp>

#include <optional>
#include <string>

#include <nlohmann/json.hpp>

class DynamicFields
{
public:
void Set(const std::string& propName, const nlohmann::json& value);
void Set(const std::string& propName, nlohmann::json value);
const nlohmann::json& Get(const std::string& propName) const;

const nlohmann::json& GetAsJson() const;
Expand Down
51 changes: 23 additions & 28 deletions skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
#include "Inventory.h"
#include "LeveledListUtils.h"
#include "MathUtils.h"
#include "MessageBase.h"
#include "MpActor.h"
#include "MpChangeForms.h"
#include "MsgType.h"
#include "Primitive.h"
#include "ScopedTask.h"
#include "ScriptVariablesHolder.h"
#include "TimeUtils.h"
#include "UpdatePropertyMessage.h"
#include "WorldState.h"
#include "gamemode_events/ActivateEvent.h"
#include "gamemode_events/PutItemEvent.h"
Expand Down Expand Up @@ -567,7 +569,9 @@ void MpObjectReference::SetHarvested(bool harvested)
EditChangeForm([&](MpChangeFormREFR& changeForm) {
changeForm.isHarvested = harvested;
});
SendPropertyToListeners("isHarvested", harvested);
SendMessageToActorListeners(
CreatePropertyMessage(this, "isHarvested", /*value=*/harvested),
/*reliable=*/true);
}
}

Expand All @@ -576,7 +580,9 @@ void MpObjectReference::SetOpen(bool open)
if (open != ChangeForm().isOpen) {
EditChangeForm(
[&](MpChangeFormREFR& changeForm) { changeForm.isOpen = open; });
SendPropertyToListeners("isOpen", open);
SendMessageToActorListeners(
CreatePropertyMessage(this, "isOpen", /*value=*/open),
/*reliable=*/true);
}
}

Expand Down Expand Up @@ -686,26 +692,28 @@ void MpObjectReference::UpdateHoster(uint32_t newHosterId)
auto hostedMsg = CreatePropertyMessage(this, "isHostedByOther", true);
auto notHostedMsg = CreatePropertyMessage(this, "isHostedByOther", false);
for (auto listener : this->GetActorListeners()) {
this->SendPropertyTo(
newHosterId != 0 && newHosterId != listener->GetFormId() ? hostedMsg
: notHostedMsg,
*listener);
if (newHosterId != 0 && newHosterId != listener->GetFormId()) {
listener->SendToUser(hostedMsg, /*reliable=*/true);
} else {
listener->SendToUser(notHostedMsg, /*reliable=*/true);
}
}
}

void MpObjectReference::SetProperty(const std::string& propertyName,
const nlohmann::json& newValue,
nlohmann::json newValue,
bool isVisibleByOwner,
bool isVisibleByNeighbor)
{
auto msg = CreatePropertyMessage(this, propertyName.c_str(), newValue);
EditChangeForm([&](MpChangeFormREFR& changeForm) {
changeForm.dynamicFields.Set(propertyName, newValue);
changeForm.dynamicFields.Set(propertyName, std::move(newValue));
});
if (isVisibleByNeighbor) {
SendPropertyToListeners(propertyName.data(), newValue);
SendMessageToActorListeners(msg, /*reliable=*/true);
} else if (isVisibleByOwner) {
if (auto ac = AsActor()) {
SendPropertyTo(propertyName.data(), newValue, *ac);
ac->SendToUser(msg, /*reliable=*/true);
}
}
pImpl->setPropertyCalled = true;
Expand Down Expand Up @@ -1449,7 +1457,9 @@ void MpObjectReference::ProcessActivateNormal(
this->occupant->RemoveEventSink(this->occupantDestroySink);
}
SetOpen(true);
SendPropertyTo("inventory", GetInventory().ToJson(), *actorActivator);
actorActivator->SendToUser(
CreatePropertyMessage(this, "inventory", GetInventory().ToJson()),
/*reliable=*/true);
activationSource.SendOpenContainer(GetFormId());

this->occupant = actorActivator;
Expand Down Expand Up @@ -1935,29 +1945,14 @@ void MpObjectReference::CheckInteractionAbility(MpObjectReference& refr)
}
}

void MpObjectReference::SendPropertyToListeners(const char* name,
const nlohmann::json& value)
void MpObjectReference::SendMessageToActorListeners(const IMessageBase& msg,
bool reliable) const
{
auto msg = CreatePropertyMessage(this, name, value);
for (auto listener : GetActorListeners()) {
listener->SendToUser(msg, true);
}
}

void MpObjectReference::SendPropertyTo(const char* name,
const nlohmann::json& value,
MpActor& target)
{
auto msg = CreatePropertyMessage(this, name, value);
SendPropertyTo(msg, target);
}

void MpObjectReference::SendPropertyTo(const IMessageBase& preparedPropMsg,
MpActor& target)
{
target.SendToUser(preparedPropMsg, true);
}

void MpObjectReference::BeforeDestroy()
{
if (this->occupant && this->occupantDestroySink) {
Expand Down
12 changes: 5 additions & 7 deletions skymp5-server/cpp/server_guest_lib/MpObjectReference.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Inventory.h"
#include "JsonUtils.h"
#include "LocationalData.h"
#include "MessageBase.h"
#include "MpChangeForms.h"
#include "MpForm.h"
#include "libespm/Loader.h"
Expand Down Expand Up @@ -136,9 +137,8 @@ class MpObjectReference
void ForceSubscriptionsUpdate();
void SetPrimitive(const NiPoint3& boundsDiv2);
void UpdateHoster(uint32_t newHosterId);
void SetProperty(const std::string& propertyName,
const nlohmann::json& newValue, bool isVisibleByOwner,
bool isVisibleByNeighbor);
void SetProperty(const std::string& propertyName, nlohmann::json newValue,
bool isVisibleByOwner, bool isVisibleByNeighbor);
void SetTeleportFlag(bool value);
void SetPosAndAngleSilent(const NiPoint3& pos, const NiPoint3& rot);
void Delete();
Expand Down Expand Up @@ -215,10 +215,8 @@ class MpObjectReference

void EnsureBaseContainerAdded(espm::Loader& espm);

void SendPropertyToListeners(const char* name, const nlohmann::json& value);
void SendPropertyTo(const char* name, const nlohmann::json& value,
MpActor& target);
void SendPropertyTo(const IMessageBase& preparedPropMsg, MpActor& target);
void SendMessageToActorListeners(const IMessageBase& msg,
bool reliable) const;

private:
void AddContainerObject(const espm::CONT::ContainerObject& containerObject,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ void RespawnEvent::OnFireSuccess(WorldState*)
actor->SendAndSetDeathState(false, shouldTeleport);

// TODO: should probably not sending to ourselves. see also RespawnTest.cpp
actor->SendPropertyToListeners("isDead", false);
actor->SendMessageToActorListeners(
actor->CreatePropertyMessage(actor, "isDead", /*value=*/false),
/*reliable=*/true);
}

0 comments on commit b5a603d

Please sign in to comment.