lua потоки

g305noobo

Известный
Автор темы
211
190
Версия MoonLoader
.026-beta
привет, столкнулся с проблемой потоков и возврата значений.
при создании потока на конкретную функцию, всё окей, но стоит только добавить return - поток сразу зацикливается.
казалось бы можно отказаться от return, но в моем случае это невозможно.

Lua:
function a(b)
    print(b)
    return true
end
lua_thread.create(a, "some text")
[ML] (script) test_arc.lua: some text
[ML] (system) test_arc.lua: Loaded successfully.
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
и так далее..
Lua:
function a(b)
    print(b)
end
lua_thread.create(a, "some text")
[ML] (script) test_arc.lua: some text
 

why ega

РП игрок
Модератор
2,545
2,236
но стоит только добавить return - поток сразу зацикливается
это происходит, т.к. поток выполняется отдельно от того, в котором ты его вызываешь, следовательно, чтобы получить его результат, пришлось тормозить основной поток (тот, из которого вызываешь), что лишало бы их смысла
 

СоМиК

Известный
457
310
привет, столкнулся с проблемой потоков и возврата значений.
при создании потока на конкретную функцию, всё окей, но стоит только добавить return - поток сразу зацикливается.
казалось бы можно отказаться от return, но в моем случае это невозможно.

Lua:
function a(b)
    print(b)
    return true
end
lua_thread.create(a, "some text")
[ML] (script) test_arc.lua: some text
[ML] (system) test_arc.lua: Loaded successfully.
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
[ML] (script) test_arc.lua: nil
и так далее..
Lua:
function a(b)
    print(b)
end
lua_thread.create(a, "some text")
[ML] (script) test_arc.lua: some text
Ты можешь создать компактное подобие асинхронной функции используя метатаблицу, если шо
 
  • Bug
Реакции: DZONE

g305noobo

Известный
Автор темы
211
190

СоМиК

Известный
457
310
это будет использоваться в контексте распаковки множества архивов, хочу сделать что-то вроде мультипотоков
короче хз попробовал чета накалякать для примера
Example:
local asyncFunc = setmetatable( -- создаём метатаблицу
    {
        data = {i = 0} -- какая то общая дата, в ней можно что нибудь хранить, например, счётчик i
    },
    {
        __call = function(self --[[ параметр метаметода передающийся автоматически при вызове функции ]], data --[[ какая то локальная дата функции, передающаяся как её параметры]], resolve --[[ первый "каллбек", будет вызываться, если всё ок ]], reject --[[ второй "каллбек", будет вызываться, если чёта не так ]]) -- делаем так, чтобы к метатаблице можно было обращаться как к функции. self указывается в параметрах автоматически при вызове метатаблицы
            lua_thread.create(function() -- сам поток для недо-подобия асинхронности в луа (и то конкретно мунлоадер)
                if self.data.i < 2 then -- обращаемся к общей дате, к счётчику
                    self.data.i = self.data.i + 1 -- увлеичиваем значение счётчика на +1
                    data.updated = true -- изменяем локальную дату, просто ради примера
                    resolve(data) -- функция, которая будет выполняться, если всё хорошо и передавать локальную дату функции
                else
                    reject(data) -- функция, которая будет выполняться, если что-то не так и передавать локальную дату функции
                end
            end)
        end
    }
)

for i = 1, 3 do -- создаём цикл из 3 итераций для тройного вызова функции
    asyncFunc({updated = false} --[[ тут передаётся любая дата, как параметры функции ]], function(data) print(asyncFunc.data.i, data.updated) --[[ выводим показатели счётчика и локальную дату функции, данный "каллбек" сработает если всё ок ]] end, function(data) print(data.updated, 'ошибка') end)
end

вот такой код, а вот вывод в консоли:

Output:
1   true
2   true
false   ошибка

Если из за кучи комментариев, код кажется непонятным, то вот без них:

Example without comments:
local asyncFunc = setmetatable(
    {
        data = {i = 0}
    },
    {
        __call = function(self, data, resolve, reject)
            lua_thread.create(function()
                if self.data.i < 2 then
                    self.data.i = self.data.i + 1
                    data.updated = true
                    resolve(data)
                else
                    reject(data)
                end
            end)
        end
    }
)


for i = 1, 3 do
    asyncFunc({updated = false}, function(data) print(asyncFunc.data.i, data.updated) end, function(data) print(data.updated, 'ошибка') end)
end

Безусловно, подобный код выполняющий то же самое можно создать и без метатаблицы, но я думаю, что гораздо удобнее будет хранить абсолютно всю дату относящуюся к функции внутри одного объекта
 
  • Нравится
  • Вау
Реакции: why ega и g305noobo