From 2bb646d98e250dd48bf2770f1d00acc8ae503504 Mon Sep 17 00:00:00 2001 From: cheapie Date: Sat, 1 Jan 2022 19:11:08 -0600 Subject: Add Luacontroller library support Fixes upstream #557 --- mesecons/util.lua | 18 ++++++++++++++++++ mesecons_luacontroller/init.lua | 20 ++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/mesecons/util.lua b/mesecons/util.lua index 7fb95cc..a89d234 100644 --- a/mesecons/util.lua +++ b/mesecons/util.lua @@ -474,3 +474,21 @@ function mesecon.execute_autoconnect_hooks_queue(pos, node) mesecon.queue:add_action(pos, "autoconnect_hook_"..name, {node}) end end + +-- Performs a deep copy of a table, changing the environment of any functions. +-- Adapted from the builtin table.copy() function. +function mesecon.tablecopy_change_env(t, env, seen) + local n = {} + seen = seen or {} + seen[t] = n + for k, v in pairs(t) do + if type(v) == "function" then + setfenv(v, env) + n[(type(k) == "table" and (seen[k] or mesecon.tablecopy_change_env(k, env, seen))) or k] = v + else + n[(type(k) == "table" and (seen[k] or mesecon.tablecopy_change_env(k, env, seen))) or k] = + (type(v) == "table" and (seen[v] or mesecon.tablecopy_change_env(v, env, seen))) or v + end + end + return n +end diff --git a/mesecons_luacontroller/init.lua b/mesecons_luacontroller/init.lua index 1c411dd..3abe6ed 100644 --- a/mesecons_luacontroller/init.lua +++ b/mesecons_luacontroller/init.lua @@ -37,6 +37,24 @@ local rules = { d = {x = 0, y = 0, z = -1, name="D"}, } +-- Mods can place their own "libraries" in here to be loaded via require() from in a Luacontroller. +-- These can take two different forms: +-- Function (recommended for libraries adding new functionality): A function that, when called, returns something that will be passed to the LuaC code. +-- Function signature is getlibrary(env, pos) where 'env' is the environment that the Luacontroller code is running in, and 'pos' is the position of the controller. +-- Table (recommended for libraries containing mostly lookup tables): A table that will be copied, and the copy returned to the LuaC code. +-- When using the table format, any functions in the table will have their environment changed to that of the Luacontroller. +mesecon.luacontroller_libraries = {} + +--This prepares the actual require() function that will be available in the LuaC environment. +local function get_require(pos, env) + return function(name) + if type(mesecon.luacontroller_libraries[name]) == "function" then + return mesecon.luacontroller_libraries[name](env, pos) + elseif type(mesecon.luacontroller_libraries[name]) == "table" then + return mesecon.tablecopy_change_env(mesecon.luacontroller_libraries[name], env) + end + end +end ------------------ -- Action stuff -- @@ -546,6 +564,8 @@ local function create_environment(pos, mem, event, itbl, send_warning) for _, name in pairs(safe_globals) do env[name] = _G[name] end + + env.require = get_require(pos, env) return env end -- cgit v1.2.3