* @brief Compiles a single Lua dataset transform; logs and skips on any error. */
| 2064 | * @brief Compiles a single Lua dataset transform; logs and skips on any error. |
| 2065 | */ |
| 2066 | void DataModel::FrameBuilder::compileTransformsLuaEntry(lua_State* L, |
| 2067 | TransformEngine& engine, |
| 2068 | const TransformEntry& entry) |
| 2069 | { |
| 2070 | const int baseTop = lua_gettop(L); |
| 2071 | |
| 2072 | try { |
| 2073 | lua_newtable(L); |
| 2074 | lua_createtable(L, 0, 1); |
| 2075 | lua_pushglobaltable(L); |
| 2076 | lua_setfield(L, -2, "__index"); |
| 2077 | lua_setmetatable(L, -2); |
| 2078 | |
| 2079 | const QByteArray utf8 = entry.code.toUtf8(); |
| 2080 | const QByteArray chunkName = |
| 2081 | QByteArray("=transform[") + QByteArray::number(entry.uniqueId) + "]"; |
| 2082 | if (luaL_loadbufferx(L, utf8.constData(), utf8.size(), chunkName.constData(), "t") != LUA_OK) { |
| 2083 | qWarning() << "[FrameBuilder] Transform compile error for dataset" << entry.uniqueId << ":" |
| 2084 | << lua_tostring(L, -1); |
| 2085 | lua_settop(L, baseTop); |
| 2086 | return; |
| 2087 | } |
| 2088 | |
| 2089 | lua_pushvalue(L, -2); |
| 2090 | lua_setupvalue(L, -2, 1); |
| 2091 | |
| 2092 | if (lua_pcall(L, 0, 0, 0) != LUA_OK) { |
| 2093 | qWarning() << "[FrameBuilder] Transform runtime error for dataset" << entry.uniqueId << ":" |
| 2094 | << lua_tostring(L, -1); |
| 2095 | lua_settop(L, baseTop); |
| 2096 | return; |
| 2097 | } |
| 2098 | |
| 2099 | lua_getfield(L, -1, "transform"); |
| 2100 | if (!lua_isfunction(L, -1)) { |
| 2101 | qWarning() << "[FrameBuilder] Dataset" << entry.uniqueId |
| 2102 | << "transform code does not define transform()"; |
| 2103 | lua_settop(L, baseTop); |
| 2104 | return; |
| 2105 | } |
| 2106 | |
| 2107 | bool acceptsInfo = false; |
| 2108 | lua_pushvalue(L, -1); |
| 2109 | lua_Debug ar; |
| 2110 | if (lua_getinfo(L, ">u", &ar) != 0) [[likely]] |
| 2111 | acceptsInfo = (ar.nparams >= 2); |
| 2112 | |
| 2113 | auto existingIt = engine.luaRefs.find(entry.uniqueId); |
| 2114 | if (existingIt != engine.luaRefs.end()) [[unlikely]] |
| 2115 | luaL_unref(L, LUA_REGISTRYINDEX, existingIt->second.ref); |
| 2116 | |
| 2117 | engine.luaRefs[entry.uniqueId] = LuaTransformRef{luaL_ref(L, LUA_REGISTRYINDEX), acceptsInfo}; |
| 2118 | |
| 2119 | lua_pop(L, 1); |
| 2120 | Q_ASSERT(lua_gettop(L) == baseTop); |
| 2121 | } catch (const std::exception& e) { |
| 2122 | qWarning() << "[FrameBuilder] Transform compile uncaught exception for dataset" |
| 2123 | << entry.uniqueId << ":" << e.what(); |
nothing calls this directly
no test coverage detected