Lua: Как мне выполнить обратный вызов, переданный из параметра? - PullRequest
0 голосов
/ 31 мая 2018

Я безуспешно искал ответ на этот вопрос.Я нашел только примеры людей, передающих обратный вызов в функцию вызывающей стороны, но не видел, как вызывающая сторона фактически выполняет код функции обратного вызова внутри.Если бы кто-то мог дать мне пример и объяснение этого, это было бы очень полезно.

Я понимаю, как обратные вызовы работают с функциональной точки зрения, я использовал их на других языках.Я просто не могу понять синтаксис того, как сделать это правильно в lua.Я либо неправильно выполняю параметр обратного вызова, либо неправильно передаю его в функцию вызывающего абонента.

Вот некоторый псевдокод того, что я пытаюсь сделать, просто простой пример, чтобы я мог видеть, как он работает.(Я визуальный ученик)

callback = function ()
    ... do stuff ...
end

function caller(callback)
    callback()
end

-- run caller function
caller(callback)

РЕДАКТИРОВАТЬ: Я получил несколько ответов о том, что мой пример выше работает, и кажется, что это действительно так.Спасибо вам за это, но я полагаю, что мне нужно получить более конкретную информацию, учитывая, что мой реальный код не работает, несмотря на правильный синтаксис.

Я делаю некоторое кодирование для сервера FiveM, который использует essentialmode.Я пытаюсь использовать обратный вызов в скрипте для очистки кода, но, похоже, он не запускает функцию обратного вызова.Вот фрагменты ...

Клиентский скрипт:

RegisterNetEvent("parachute:callback")
AddEventHandler('parachute:callback', function(callback)
    print("callback...")
    callback()
end)

Серверный скрипт:

callback = function ()
    print("callback fired")
    GiveWeaponToPed(GetPlayerPed(-1), GetHashKey("GADGET_PARACHUTE"), 150, true, true)
    SetPedComponentVariation(GetPlayerPed(-1), 5, 1, 0, 0)
end

TriggerEvent('es:addCommand', 'callback', function(source, args, user)
    TriggerClientEvent("parachute:callback", source, callback)
end, {help = "TEST"})

В приведенном выше примере функция print("callback...") выполняется, нофункция callback() не работает.Я могу сказать из-за операторов печати, которые я добавил.

Для большего контекста для тех из вас, кто не знаком с основным режимом или сценариями FiveM, есть загруженный клиентом сценарий и сценарий, загруженный сервером.На сервере TriggerEvent('es:addCommand', ... ) добавляет команду, которую можно выполнить с помощью /<cmd name>.TriggerClientEvent() запускает событие на клиенте через прослушиватель, созданный RegisterNetEvent() и AddEventHandler().Как вы можете видеть, вы передаете функции обратного вызова этим функциям, чтобы сообщить им, что выполнять при запуске события.Сама функция обратного вызова просто дает парашют моему персонажу.Однако при вводе /callback парашют не предоставляется.

Что не так, если синтаксис не такой, как я думал раньше?

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Функции могут быть переменными в lua, но они похожи на любую другую переменную.

Я не знаю, что не так с вашим примером, похоже, вы все правильно поняли.Просто ввод вашего кода работает ( попробуйте здесь ).

Обновление

Похоже, FiveM и существенный режим являются клиентом/ сервер и работает в двух разных средах исполнения.Они, вероятно, сериализуют данные для связи между клиентом и сервером, но передача функции не будет работать.

Может быть что-то, что вы можете сделать, используя loadstring() ... Вот пример, который вы можете запустить на jdoodle:

function sayHi(name)
  print("Hello, "..tostring(name).."!")
end

-- create string representation of the function
local functionDef = string.dump(sayHi)

-- convert back to a function
local func = loadstring(functionDef)
func('Jason')

-- or use a string directly, just body, no arguments so
-- we 'return' a function and call it with () after loadstring 
-- to get the returned function - [[ ]] is just syntax for a
-- multiline string
local func2 = loadstring([[
        return function(name) 
          print("Hi there, "..tostring(name).."!")
        end
    ]])()
func2('Jason')

String.dump сериализует существующую функцию в виде строки иloadstring преобразует его обратно в функцию.Вы можете передать эту строку между клиентом и сервером, но она будет выполняться в любой среде, в которой она была выполнена.Вы также можете передать тело функции, но чтобы получить аргументы, вы должны вернуть функцию с аргументами в этом теле и вызвать ее, чтобы получить возвращаемое значение для использования этой функции.

Если GiveWeaponToPed и SetPedComponentVariationвыполняются на клиенте, затем вы можете отправить эти команды вместо аргумента callback и использовать loadstring в клиенте ...

client

RegisterNetEvent("parachute:callback")
AddEventHandler('parachute:callback', function(callback)
    print("callback...")
    loadstring(callback)()
end)

сервер

codestring = [[
    GiveWeaponToPed(GetPlayerPed(-1), GetHashKey("GADGET_PARACHUTE"), 150, true, true)
    SetPedComponentVariation(GetPlayerPed(-1), 5, 1, 0, 0)
]]

TriggerEvent('es:addCommand', 'callback', function(source, args, user)
    TriggerClientEvent("parachute:callback", source, codestring)
end, {help = "TEST"})
0 голосов
/ 31 мая 2018

Это будет работать именно так, как вы это описали.Возможно, вы захотите добавить local перед вашей функцией обратного вызова, но в остальном у вас все будет хорошо.Вот рабочий пример:

local callback = function ()
    print("here")
end

function caller(callback)
    callback()
end

-- run caller function
caller(callback)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...