mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-10-28 06:46:03 +03:00
190 lines
4.7 KiB
C++
190 lines
4.7 KiB
C++
#include "ui/FrameScript_Object.hpp"
|
|
#include "util/Lua.hpp"
|
|
#include <cstdint>
|
|
#include <storm/String.hpp>
|
|
|
|
int32_t FrameScript_Object::s_objectTypes = 0;
|
|
|
|
int32_t FrameScript_Object::CreateScriptMetaTable(lua_State* L, void (*a2)(lua_State* L)) {
|
|
lua_createtable(L, 0, 0);
|
|
lua_pushstring(L, "__index");
|
|
lua_createtable(L, 0, 0);
|
|
|
|
a2(L);
|
|
|
|
lua_settable(L, -3);
|
|
return luaL_ref(L, LUA_REGISTRYINDEX);
|
|
}
|
|
|
|
void FrameScript_Object::FillScriptMethodTable(lua_State *L, FrameScript_Method methods[], int32_t count) {
|
|
for (int32_t i = 0; i < count; i++) {
|
|
lua_pushstring(L, methods[i].name);
|
|
lua_pushcclosure(L, methods[i].method, 0);
|
|
lua_settable(L, -3);
|
|
}
|
|
}
|
|
|
|
FrameScript_Object::~FrameScript_Object() {
|
|
if (this->m_onEvent.luaRef) {
|
|
luaL_unref(FrameScript_GetContext(), LUA_REGISTRYINDEX, this->m_onEvent.luaRef);
|
|
}
|
|
}
|
|
|
|
const char* FrameScript_Object::GetDisplayName() {
|
|
const char* name = this->GetName();
|
|
return name ? name : "<unnamed>";
|
|
}
|
|
|
|
FrameScript_Object::ScriptIx* FrameScript_Object::GetScriptByName(const char* name, FrameScript_Object::ScriptData& data) {
|
|
if (!SStrCmpI(name, "OnEvent", STORM_MAX_STR)) {
|
|
data.wrapper = "return function(self,event,...) %s end";
|
|
return &this->m_onEvent;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
int32_t FrameScript_Object::RegisterScriptEvent(const char* name) {
|
|
auto event = FrameScript::s_scriptEventsHash.Ptr(name);
|
|
|
|
if (!event) {
|
|
return 0;
|
|
}
|
|
|
|
if (event->pendingSignalCount) {
|
|
auto node = event->unregisterListeners.Head();
|
|
|
|
while (node) {
|
|
if (node->listener == this) {
|
|
break;
|
|
}
|
|
|
|
node = node->Next();
|
|
}
|
|
|
|
if (node) {
|
|
event->unregisterListeners.DeleteNode(node);
|
|
}
|
|
}
|
|
|
|
auto node = event->listeners.Head();
|
|
|
|
while (node) {
|
|
if (node->listener == this) {
|
|
break;
|
|
}
|
|
|
|
node = node->Next();
|
|
}
|
|
|
|
if (!node) {
|
|
FrameScript_RegisterScriptEvent(this, event);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void FrameScript_Object::RegisterScriptObject(const char* name) {
|
|
auto L = FrameScript_GetContext();
|
|
|
|
if (!this->lua_registered) {
|
|
// TODO
|
|
// v4 = lua_taintexpected++ == -1;
|
|
// v5 = lua_tainted;
|
|
// if (!v4 && !lua_taintedclosure) {
|
|
// lua_tainted = 0;
|
|
// }
|
|
|
|
lua_createtable(L, 0, 0);
|
|
lua_pushnumber(L, 0.0);
|
|
lua_pushlightuserdata(L, this);
|
|
lua_rawset(L, -3);
|
|
|
|
int32_t metatable = this->GetScriptMetaTable();
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, metatable);
|
|
lua_setmetatable(L, -2);
|
|
|
|
this->lua_objectRef = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
|
// TODO
|
|
// if (lua_taintexpected && !lua_taintedclosure) {
|
|
// lua_tainted = v5;
|
|
// }
|
|
// if (--lua_taintexpected <= 0) {
|
|
// lua_taintexpected = 0;
|
|
// }
|
|
}
|
|
|
|
this->lua_registered++;
|
|
|
|
if (name) {
|
|
int32_t v8 = 0;
|
|
|
|
lua_pushstring(L, name);
|
|
lua_rawget(L, LUA_GLOBALSINDEX);
|
|
|
|
if (lua_type(L, -1)) {
|
|
v8 = 1;
|
|
}
|
|
|
|
lua_settop(L, -2);
|
|
|
|
if (!v8) {
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, this->lua_objectRef);
|
|
lua_pushstring(L, name);
|
|
lua_insert(L, -2);
|
|
lua_rawset(L, LUA_GLOBALSINDEX);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FrameScript_Object::RunScript(ScriptIx const& script, int32_t argCount, const char* a4) {
|
|
FrameScript_Execute(script.luaRef, this, argCount, a4 ? a4 : script.unk, nullptr);
|
|
}
|
|
|
|
void FrameScript_Object::UnregisterScriptObject(const char* name) {
|
|
auto L = FrameScript_GetContext();
|
|
|
|
if (this->lua_registered > 0) {
|
|
this->lua_registered--;
|
|
|
|
if (this->lua_registered == 0) {
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, this->lua_objectRef);
|
|
lua_pushnumber(L, 0.0);
|
|
lua_pushnil(L);
|
|
lua_rawset(L, -3);
|
|
lua_settop(L, -2);
|
|
luaL_unref(L, LUA_REGISTRYINDEX, this->lua_objectRef);
|
|
|
|
this->lua_objectRef = -2;
|
|
}
|
|
}
|
|
|
|
if (name) {
|
|
lua_pushnil(L);
|
|
lua_pushstring(L, name);
|
|
lua_insert(L, -2);
|
|
lua_rawset(L, LUA_GLOBALSINDEX);
|
|
}
|
|
}
|
|
|
|
FrameScript_Object* FrameScript_GetObjectThis(lua_State* L, int32_t type) {
|
|
if (lua_type(L, 1) != LUA_TTABLE) {
|
|
luaL_error(L, "Attempt to find 'this' in non-table object (used '.' instead of ':' ?)");
|
|
}
|
|
|
|
lua_rawgeti(L, 1, 0);
|
|
auto object = static_cast<FrameScript_Object*>(lua_touserdata(L, -1));
|
|
lua_settop(L, -2);
|
|
|
|
if (!object) {
|
|
luaL_error(L, "Attempt to find 'this' in non-framescript object");
|
|
}
|
|
|
|
if (!object->IsA(type)) {
|
|
luaL_error(L, "Wrong object type for member function");
|
|
}
|
|
|
|
return object;
|
|
}
|