Skip to content

Commit

Permalink
perf: optimize SpSnippet (skyrim-multiplayer#1911)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pospelove authored Apr 10, 2024
1 parent becfb79 commit 7c0b194
Show file tree
Hide file tree
Showing 15 changed files with 61 additions and 38 deletions.
5 changes: 5 additions & 0 deletions skymp5-client/src/services/services/spSnippetService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ export class SpSnippetService extends ClientListener {
this.controller.once('update', async () => {
this.run(msg)
.then((res) => {
const isNoResultSnippet = msg.snippetIdx === 0xffffffff;
if (isNoResultSnippet) {
return;
}

if (res === undefined) {
res = null;
}
Expand Down
2 changes: 1 addition & 1 deletion skymp5-server/cpp/server_guest_lib/MpActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ bool MpActor::OnEquip(uint32_t baseId)
auto targetRefr = dynamic_cast<MpActor*>(listener);
if (targetRefr && targetRefr != this) {
SpSnippet("Actor", "EquipItem", serializedArgs.data(), GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
} else if (isBook) {
Expand Down
6 changes: 4 additions & 2 deletions skymp5-server/cpp/server_guest_lib/SpSnippet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ SpSnippet::SpSnippet(const char* cl_, const char* func_, const char* args_,
{
}

Viet::Promise<VarValue> SpSnippet::Execute(MpActor* actor)
Viet::Promise<VarValue> SpSnippet::Execute(MpActor* actor, SpSnippetMode mode)
{
auto worldState = actor->GetParent();
if (!actor->IsCreatedAsPlayer()) {
Expand All @@ -24,7 +24,9 @@ Viet::Promise<VarValue> SpSnippet::Execute(MpActor* actor)

Viet::Promise<VarValue> promise;

auto snippetIdx = actor->NextSnippetIndex(promise);
const uint32_t snippetIdx = mode == SpSnippetMode::kReturnResult
? actor->NextSnippetIndex(promise)
: std::numeric_limits<uint32_t>::max();

// Player character is always 0x14 on client, but 0xff000000+ in our server
// See also SpSnippetFunctionGen.cpp
Expand Down
8 changes: 7 additions & 1 deletion skymp5-server/cpp/server_guest_lib/SpSnippet.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@

class MpActor;

enum class SpSnippetMode
{
kNoReturnResult,
kReturnResult,
};

class SpSnippet
{
public:
SpSnippet(const char* cl_, const char* func_, const char* args_,
uint32_t selfId_ = 0);

Viet::Promise<VarValue> Execute(MpActor* actor);
Viet::Promise<VarValue> Execute(MpActor* actor, SpSnippetMode mode);

private:
const char *const cl, *const func, *const args;
Expand Down
7 changes: 5 additions & 2 deletions skymp5-server/cpp/server_guest_lib/SpSnippetFunctionGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,20 @@ class SpSnippetFunctionGen
static uint32_t GetFormId(VarValue varValue);
};

// TODO: unhardcode mode
#define DEFINE_STATIC_SPSNIPPET(name) \
VarValue name(VarValue self, const std::vector<VarValue>& arguments) \
{ \
if (auto actor = compatibilityPolicy->GetDefaultActor( \
GetName(), #name, self.GetMetaStackId())) { \
auto s = SpSnippetFunctionGen::SerializeArguments(arguments, actor); \
SpSnippet(GetName(), (#name), s.data()).Execute(actor); \
SpSnippet(GetName(), (#name), s.data()) \
.Execute(actor, SpSnippetMode::kNoReturnResult); \
} \
return VarValue::None(); \
}

// TODO: unhardcode mode
#define DEFINE_METHOD_SPSNIPPET(name) \
VarValue name(VarValue self, const std::vector<VarValue>& arguments) \
{ \
Expand All @@ -33,7 +36,7 @@ class SpSnippetFunctionGen
auto s = SpSnippetFunctionGen::SerializeArguments(arguments, actor); \
auto promise = SpSnippet(GetName(), (#name), s.data(), \
SpSnippetFunctionGen::GetFormId(self)) \
.Execute(actor); \
.Execute(actor, SpSnippetMode::kReturnResult); \
return VarValue(promise); \
} \
\
Expand Down
8 changes: 5 additions & 3 deletions skymp5-server/cpp/server_guest_lib/SweetPieScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ void SweetPieScript::Notify(MpActor& actor, const WorldState& worldState,
<< (static_cast<bool>(silent) ? "true" : "false");
ss << "]";
std::string args = ss.str();
(void)SpSnippet("SkympHacks", "AddItem", args.data()).Execute(&actor);
(void)SpSnippet("SkympHacks", "AddItem", args.data())
.Execute(&actor, SpSnippetMode::kNoReturnResult);
}

void SweetPieScript::Play(MpActor& actor, WorldState& worldState,
Expand Down Expand Up @@ -242,8 +243,9 @@ void SweetPieScript::EquipItem(MpActor& actor, uint32_t baseId,
std::string args = ss.str();
spdlog::info("Equipping item: {}", args);
SpSnippet("Actor", "EquipItem", args.data(), actor.GetFormId())
.Execute(&actor);
.Execute(&actor, SpSnippetMode::kNoReturnResult);
if (!isShield && !isArrow) {
SpSnippet("Actor", "DrawWeapon", "[]", actor.GetFormId()).Execute(&actor);
SpSnippet("Actor", "DrawWeapon", "[]", actor.GetFormId())
.Execute(&actor, SpSnippetMode::kNoReturnResult);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ VarValue PapyrusActor::SetActorValue(VarValue self,
actor->GetFormId())
.Execute(it == actor->GetParent()->hosters.end()
? actor
: &actor->GetParent()->GetFormAt<MpActor>(it->second));
: &actor->GetParent()->GetFormAt<MpActor>(it->second),
SpSnippetMode::kNoReturnResult);
}
return VarValue();
}
Expand Down Expand Up @@ -171,7 +172,7 @@ VarValue PapyrusActor::SetAlpha(VarValue self,
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data(),
selfRefr->GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down Expand Up @@ -219,7 +220,7 @@ VarValue PapyrusActor::EquipItem(VarValue self,
SpSnippet(GetName(), "EquipItem",
SpSnippetFunctionGen::SerializeArguments(arguments).data(),
actor->GetFormId())
.Execute(actor);
.Execute(actor, SpSnippetMode::kNoReturnResult);
}
return VarValue::None();
}
Expand All @@ -235,7 +236,7 @@ VarValue PapyrusActor::UnequipItem(VarValue self,
SpSnippet(GetName(), "UnequipItem",
SpSnippetFunctionGen::SerializeArguments(arguments).data(),
actor->GetFormId())
.Execute(actor);
.Execute(actor, SpSnippetMode::kNoReturnResult);
}
return VarValue::None();
}
Expand All @@ -250,7 +251,7 @@ VarValue PapyrusActor::SetDontMove(VarValue self,
SpSnippet(GetName(), "SetDontMove",
SpSnippetFunctionGen::SerializeArguments(arguments).data(),
actor->GetFormId())
.Execute(actor);
.Execute(actor, SpSnippetMode::kNoReturnResult);
}
return VarValue::None();
}
Expand Down Expand Up @@ -336,7 +337,7 @@ VarValue PapyrusActor::AddSpell(VarValue self,
SpSnippet(GetName(), "AddSpell",
SpSnippetFunctionGen::SerializeArguments(arguments).data(),
actor->GetFormId())
.Execute(actor);
.Execute(actor, SpSnippetMode::kNoReturnResult);

return VarValue(true);
}
Expand Down Expand Up @@ -380,7 +381,7 @@ VarValue PapyrusActor::RemoveSpell(VarValue self,
SpSnippet(GetName(), "RemoveSpell",
SpSnippetFunctionGen::SerializeArguments(arguments).data(),
actor->GetFormId())
.Execute(actor);
.Execute(actor, SpSnippetMode::kNoReturnResult);

return VarValue(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ VarValue PapyrusDebug::SendAnimationEvent(
if (targetActor) {
auto funcName = "SendAnimationEvent";
auto s = SpSnippetFunctionGen::SerializeArguments(arguments, targetActor);
SpSnippet(GetName(), funcName, s.data()).Execute(targetActor);
SpSnippet(GetName(), funcName, s.data())
.Execute(targetActor, SpSnippetMode::kNoReturnResult);
}
return VarValue::None();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ void PapyrusEffectShader::Helper(VarValue& self, const char* funcName,
SpSnippetFunctionGen::SerializeArguments(arguments, targetRefr)
.data(),
selfRec.ToGlobalId(selfRec.rec->GetId()))
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
// Workaround to use this function on player clone
if (actorForm->GetFormId() == targetRefr->GetFormId()) {
SpSnippet(
GetName(), funcName,
SpSnippetFunctionGen::SerializeArguments(arguments).data(),
selfRec.ToGlobalId(selfRec.rec->GetId()))
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ VarValue PapyrusGame::GetCameraState(VarValue self,
GetName(), "GetCameraState", self.GetMetaStackId())) {
Viet::Promise<VarValue> promise =
SpSnippet(GetName(), "GetCameraState", serializedArgs.data())
.Execute(actor);
.Execute(actor, SpSnippetMode::kReturnResult);
return VarValue(Viet::Promise<VarValue>(promise));
}
return VarValue(-1);
Expand All @@ -113,7 +113,8 @@ void PapyrusGame::RaceMenuHelper(VarValue& self, const char* funcName,
if (auto actor = compatibilityPolicy->GetDefaultActor(
GetName(), funcName, self.GetMetaStackId())) {
actor->SetRaceMenuOpen(true);
SpSnippet(GetName(), funcName, serializedArgs.data()).Execute(actor);
SpSnippet(GetName(), funcName, serializedArgs.data())
.Execute(actor, SpSnippetMode::kNoReturnResult);
}
}

Expand Down Expand Up @@ -163,7 +164,8 @@ VarValue PapyrusGame::ShakeController(VarValue self,
auto serializedArgs = SpSnippetFunctionGen::SerializeArguments(arguments);
if (auto actor = compatibilityPolicy->GetDefaultActor(
GetName(), funcName, self.GetMetaStackId())) {
SpSnippet(GetName(), funcName, serializedArgs.data()).Execute(actor);
SpSnippet(GetName(), funcName, serializedArgs.data())
.Execute(actor, SpSnippetMode::kNoReturnResult);
}

return VarValue::None();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ VarValue PapyrusNetImmerse::SetNodeTextureSet(
auto targetRefr = dynamic_cast<MpActor*>(listener);
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}

Expand Down Expand Up @@ -70,7 +70,7 @@ VarValue PapyrusNetImmerse::SetNodeScale(
auto targetRefr = dynamic_cast<MpActor*>(listener);
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ VarValue PapyrusObjectReference::AddItem(
if (!silent && count > 0) {
if (auto actor = dynamic_cast<MpActor*>(selfRefr)) {
auto args = SpSnippetFunctionGen::SerializeArguments(arguments);
(void)SpSnippet("SkympHacks", "AddItem", args.data()).Execute(actor);
(void)SpSnippet("SkympHacks", "AddItem", args.data())
.Execute(actor, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down Expand Up @@ -251,7 +252,7 @@ VarValue PapyrusObjectReference::RemoveItem(
if (auto actor = dynamic_cast<MpActor*>(selfRefr)) {
auto args = SpSnippetFunctionGen::SerializeArguments(arguments);
(void)SpSnippet("SkympHacks", "RemoveItem", args.data())
.Execute(actor);
.Execute(actor, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down Expand Up @@ -316,7 +317,7 @@ void PlaceAtMeSpSnippet(MpObjectReference* self,
if (targetRefr) {
SpSnippet("ObjectReference", funcName, serializedArgs.data(),
self->GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down Expand Up @@ -414,7 +415,7 @@ VarValue PapyrusObjectReference::Enable(VarValue self,
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data(),
selfRefr->GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand All @@ -438,7 +439,7 @@ VarValue PapyrusObjectReference::Disable(
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data(),
selfRefr->GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down Expand Up @@ -551,7 +552,7 @@ VarValue PapyrusObjectReference::SetPosition(
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data(),
selfRefr->GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down Expand Up @@ -593,7 +594,7 @@ VarValue PapyrusObjectReference::PlayAnimation(
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data(),
selfRefr->GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down Expand Up @@ -621,7 +622,7 @@ VarValue PapyrusObjectReference::PlayAnimationAndWait(
if (targetRefr) {
auto promise = SpSnippet(GetName(), funcName, serializedArgs.data(),
selfRefr->GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kReturnResult);
promises.push_back(promise);
}
}
Expand Down Expand Up @@ -663,7 +664,7 @@ VarValue PapyrusObjectReference::PlayGamebryoAnimation(
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data(),
selfRefr->GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down Expand Up @@ -867,7 +868,7 @@ VarValue PapyrusObjectReference::SetDisplayName(
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data(),
selfRefr->GetFormId())
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ VarValue PapyrusSound::Play(VarValue self,
auto targetRefr = dynamic_cast<MpActor*>(listener);
if (targetRefr) {
SpSnippet(GetName(), funcName, serializedArgs.data(), selfId)
.Execute(targetRefr);
.Execute(targetRefr, SpSnippetMode::kNoReturnResult);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion unit/ConsoleCommandTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ TEST_CASE("AddItem executes", "[ConsoleCommand][espm]")
REQUIRE(
p.Messages()[1].j ==
nlohmann::json::parse(
R"({"arguments":[{"formId":77495,"type":"weapon"},264,false],"class":"SkympHacks","function":"AddItem","selfId":0,"snippetIdx":0,"type":"spSnippet"})"));
R"({"arguments":[{"formId":77495,"type":"weapon"},264,false],"class":"SkympHacks","function":"AddItem","selfId":0,"snippetIdx":4294967295,"type":"spSnippet"})"));

p.DestroyActor(0xff000000);
DoDisconnect(p, 0);
Expand Down
4 changes: 2 additions & 2 deletions unit/PapyrusDebugTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ TEST_CASE("Notification", "[Papyrus][Debug]")
REQUIRE(p.Messages()[1].reliable);
REQUIRE(p.Messages()[1].j ==
nlohmann::json{ { "type", "spSnippet" },
{ "snippetIdx", 0 },
{ "snippetIdx", 4294967295 },
{ "selfId", 0 },
{ "class", "debug" },
{ "function", "Notification" },
Expand All @@ -46,7 +46,7 @@ TEST_CASE("Notification", "[Papyrus][Debug]")
REQUIRE(p.Messages()[2].reliable);
REQUIRE(p.Messages()[2].j ==
nlohmann::json{ { "type", "spSnippet" },
{ "snippetIdx", 1 },
{ "snippetIdx", 4294967295 },
{ "selfId", 0 },
{ "class", "debug" },
{ "function", "Notification" },
Expand Down

0 comments on commit 7c0b194

Please sign in to comment.