From 28e931928a55757e10d001bfe3573c4af4a5ea10 Mon Sep 17 00:00:00 2001 From: VDm Date: Mon, 11 Aug 2025 01:32:21 +0400 Subject: [PATCH] feat(ui): implement CSimpleFrame_SetAttribute --- src/ui/CSimpleFrame.cpp | 28 ++++++++++++++++++++++++++++ src/ui/CSimpleFrame.hpp | 3 +++ src/ui/CSimpleFrameScript.cpp | 26 +++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/ui/CSimpleFrame.cpp b/src/ui/CSimpleFrame.cpp index 71dcc3f..7a5e945 100644 --- a/src/ui/CSimpleFrame.cpp +++ b/src/ui/CSimpleFrame.cpp @@ -450,6 +450,19 @@ void CSimpleFrame::RunOnUpdateScript(float elapsedSec) { } } +void CSimpleFrame::RunOnAttributeChangedScript(const char* name, int32_t luaRef) { + if (this->m_onAttributeChange.luaRef) { + auto L = FrameScript_GetContext(); + // TODO: LUA Tainted + auto loweredName = static_cast(alloca(SStrLen(name) + 1)); + SStrCopy(loweredName, name, STORM_MAX_STR); + SStrLower(loweredName); + lua_pushstring(L, loweredName); + lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef); + this->RunScript(this->m_onAttributeChange, 2, nullptr); + } +} + void CSimpleFrame::PreLoadXML(XMLNode* node, CStatus* status) { const char* name = node->GetAttributeByName("name"); @@ -749,6 +762,7 @@ void CSimpleFrame::LoadXML_Attributes(XMLNode* node, CStatus* status) { // TODO: LUA Tainted Logic attribute->luaRef = luaL_ref(L, LUA_REGISTRYINDEX); + s_testMap[name] = attribute->luaRef; child = child->m_next; } @@ -1648,3 +1662,17 @@ bool CSimpleFrame::GetAttribute(const char* name, int32_t& luaRef) { luaRef = attribute->luaRef; return true; } + +void CSimpleFrame::SetAttribute(const char* name, int32_t luaRef) { + auto attribute = this->m_attributes.Ptr(name); + if (!attribute) { + attribute = this->m_attributes.New(name, 0, 0); + } + attribute->luaRef = luaRef; + this->RunOnAttributeChangedScript(name, luaRef); +} + +bool CSimpleFrame::AttributeChangesAllowed() const { + // TODO + return true; +} diff --git a/src/ui/CSimpleFrame.hpp b/src/ui/CSimpleFrame.hpp index e25d1e5..fcc9d55 100644 --- a/src/ui/CSimpleFrame.hpp +++ b/src/ui/CSimpleFrame.hpp @@ -153,6 +153,7 @@ class CSimpleFrame : public CScriptRegion { void RunOnShowScript(); void RunOnSizeChangedScript(float width, float height); void RunOnUpdateScript(float elapsedSec); + void RunOnAttributeChangedScript(const char* name, int32_t luaRef); void SetBackdrop(CBackdropGenerator* backdrop); void SetBeingScrolled(int32_t a2, int32_t a3); void SetFrameAlpha(uint8_t alpha); @@ -166,6 +167,8 @@ class CSimpleFrame : public CScriptRegion { int32_t TestHitRect(const C2Vector& pt); void UnregisterForEvents(int32_t a2); bool GetAttribute(const char* name, int32_t& luaRef); + void SetAttribute(const char* name, int32_t luaRef); + bool AttributeChangesAllowed() const; }; #endif diff --git a/src/ui/CSimpleFrameScript.cpp b/src/ui/CSimpleFrameScript.cpp index e50e569..2b68e78 100644 --- a/src/ui/CSimpleFrameScript.cpp +++ b/src/ui/CSimpleFrameScript.cpp @@ -295,7 +295,31 @@ int32_t CSimpleFrame_GetAttribute(lua_State* L) { } int32_t CSimpleFrame_SetAttribute(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleFrame::GetObjectType(); + auto frame = static_cast(FrameScript_GetObjectThis(L, type)); + + if (!frame->ProtectedFunctionsAllowed() && !frame->AttributeChangesAllowed()) { + // TODO: CSimpleTop::s_instance->dword1254(); // fptr call + return 0; + } + + lua_settop(L, 3); + if (!lua_isstring(L, 2) || lua_type(L, 3) == LUA_TNONE) { + return luaL_error(L, "Usage: %s:SetAttribute(\"name\", value)", frame->GetDisplayName()); + } + + int32_t luaRef = -1; + + auto name = lua_tolstring(L, 2, nullptr); + if (frame->GetAttribute(name, luaRef)) { + luaL_unref(L, LUA_REGISTRYINDEX, luaRef); + } + + // TODO: LUA Tainted + luaRef = luaL_ref(L, LUA_REGISTRYINDEX); + frame->SetAttribute(name, luaRef); + + return 0; } int32_t CSimpleFrame_GetEffectiveScale(lua_State* L) {