gilzoide / godot-lua-pluginscript

Godot PluginScript for the Lua language, currently based on LuaJIT's FFI
https://gilzoide.github.io/godot-lua-pluginscript/topics/README.md.html
MIT License
300 stars 21 forks source link

Unable to execute text from textEdit's text property with loadstring() #49

Open Oolks opened 1 year ago

Oolks commented 1 year ago
local Executor = {
    extends = "Node",
}

function Executor:execute(code)
    if code == nil or code == "" then
        return false
    end
    -- Code to execute
    local temp_code = loadstring(code)

    -- Execute the code and capture the results
    local success, result = pcall(temp_code)

    -- Check if there was an error and print it if necessary
    if not success then
        print("Error executing code:", result)
        return false
    end

    -- Print the output of the code if there is any
    if result ~= nil then
        print("Output:", result)
    end

    return true
end

function Executor:_process()
    local value = self:get_parent():get_parent().play
    if value == true then
        local code_to_run = self:get_parent():get_parent():get_node("CoreUI/ScriptEditor/TextEdit").text
        print(type(code_to_run))

        self:execute(code_to_run)
    end
end

return Executor```
it keeps on giving me error of:

E 0:00:13.272 loadstring: bad argument #1 to 'loadstring' (function expected, got cdata) stack traceback: [string "res://Scripts/Core/Scripting/Executor.lua"]:10: in function 'execute'

in call _process @ "res://Scripts/Core/Scripting/Executor.lua"
Executor.lua:10 @ loadstring() ```
gilzoide commented 1 year ago

Hi @OoIks. This happens because Godot Strings are not translated to Lua strings automatically (cdata is the name LuaJIT gives to any FFI-defined type, which includes anything related to Godot). I let it be like that because it avoided marshalling (copying/converting data to/from Lua/Godot) and Godot's String class has more functionality than Lua's built-in string type. In hindsight, this was probably a bad design choice, people would expect a string in Lua to be of Lua's string type, regardless if it comes from Godot data.

Now, to fix your problem right now, just call tostring passing your code variable and it will be converted to a Lua string, which loadstring accepts:

function Executor:execute(code)
        if code == nil or code == "" then
        return false
    end
    -- Code to execute
    local temp_code = loadstring(tostring(code))
                                  -- ^ here!

        -- ... rest of your code ...
end