Panakotta00 / FicsIt-Networks

Control, Monitor, Manage and Automate your Satisfactory.
https://ficsit.app/mod/FicsItNetworks
GNU General Public License v3.0
168 stars 53 forks source link

Value from coroutine.yield() not returned by coroutine.resume() #351

Closed Feuermurmel closed 6 days ago

Feuermurmel commented 1 week ago

Describe the bug

It seems that values yielded from coroutines become functions, and the value is lost.

[SMMDebug-2024-11-05-22-12-37.zip](https://github.com/user-attachments/files/17639435/SMMDebug-2024-11-05-22-12-37.zip)

To Reproduce

Pasting this code into the EEPROM of a computer and running it will show the problem:

coro = coroutine.create(function()
    coroutine.yield(1)
end)

ok, value = coroutine.resume(coro)

print(type(value))
print(value())
print(value)

When running the code, I get this:

image

In this case, value is some kind of function instead of the value 1.

Additionally, __tostring does not return a string in this case, which made debugging this issue in a complex application hard. 😅

Expected behavior

Lua usually returns the yielded values from a call to coroutine.resume(). This was working in earlier versions of FicsIt Networks (but I haven't played for about 2 years, so I don't know when this broke).

Additional context

Satisfactory 1.0.0.4, SMM 3.0.3, FicsIt Networks 0.3.24.

Workaround

You can add this snippet to the start of your script to fix the issue. You will need to remove the snippet once the bug has been fixed:

local origResume = _G.coroutine.resume

-- TODO: Workaround for bug in FicsIt networks.
--  coroutine.resume() inserts an additional value before the
--  yielded values.
--  https://github.com/Panakotta00/FicsIt-Networks/issues/351
function _G.coroutine.resume(...)
    local result = table.pack(origResume(...))

    if result[1] then
        table.remove(result, 2)
    end

    return table.unpack(result)
end
Panakotta00 commented 1 week ago

Until next update. A simple fix is that the expected value is the third value. Which indeed is not how it should be, and will be fixed in the next update.

coro = coroutine.create(function()
    print("meep")
    coroutine.yield(42)
end)

ok, func, value = coroutine.resume(coro)
print(type(value))
print(func())
print(value)
Feuermurmel commented 6 days ago

Thanks for the quick reply and the workaround! 🥰