2014-10-22 3 views
1

У меня есть исполняемый исполняемый файл Lua-интерпретатора с встроенной встроенной функциональностью сокетов. Это не Luasocket, и насколько бы я хотел использовать Luasocket здесь, t (поэтому, пожалуйста, не предлагайте это как ответ).Как сделать функциональный блок Lua до тех пор, пока не будет вызвано замыкание

API-интерфейс сокета, с которым я работаю, опирается на асинхронные замыкания, чтобы сигнализировать о завершении сетевой операции. Итак, в приведенном ниже коде socketConnect() немедленно возвращается, а затем onConnect() вызывается позже, когда соединение завершено.

local function onConnect(cookie, err, sock) 
    print("Connected!") 
end 

local function connect(host, port) 
    local success, err = socketConnect(host, port, onConnect) 
    print("Connecting...") 
end 

Итак, вот вопрос. Я хочу сделать функциональный блок connect() до тех пор, пока не будет вызвано замыкание onConnect(). Я довольно новичок в Lua, но я надеюсь, что сопрограммы могут быть полезны здесь?

EDIT: Вот моя попытка сделать функциональный блок с помощью сопрограммы:

local connected = false 
local function onConnect(cookie, err, sock) 
    print("Connected!") 
    connected = true 
end 

local coroConnect = coroutine.create(
    function() 
    local success, err = socketConnect(m_sHost, m_nPort, onConnect); 
    while not connected do 
     coroutine.yield() 
    end 
    end 
) 

local function connect(sHost, nPort) 
    m_sHost = sHost 
    m_nPort = nPort 
    while not coroutine.status(coroConnect) ~= "dead" do 
    coroutine.resume(coroConnect) 
    print("Connecting...") 
    end 
end 
+1

Lua не поддерживает многопоточные или асинхронные обратные вызовы, поэтому либо «socketConnect» вызывает обратный вызов перед его возвратом, либо код использует некоторое многопоточное расширение, и в этом случае было бы полезно узнать, какой из них. –

+0

My * custom * Lua interpreter имеет рабочий поток, из которого вызывается обратный вызов. Если бы я вызвал вышеуказанный connect(), выход для печати был бы «Подключение ... Подключено!» – mikejonesguy

ответ

1

Если вы хотите использовать сопрограммы, то вдоль этих линий может работать для вас (или дать вам представление о том, что попробовать):

-- this should really be a socket property, but good enough for this example 
local connected 
local function onConnect(cookie, err, sock) 
    print("Connected!") 
    connected = true 
end 

local function connect(host, port) 
    connected = false 
    local success, err = socketConnect(host, port, onConnect) 
    while not connected do 
    coroutine.yield() 
    end 
    print("Connecting...") 
end 

Если теперь создать сопрограмму из connect функции и по-прежнему называя эту сопрограмму с coroutine.resume до его завершения (coroutine.status для этого сопрограммного вернутся «мертвыми»), вы получите желаемое ре Sult. Очевидно, вы можете переместить этот цикл while в функцию socketConnect, которая будет выполнять синхронно с точки зрения пользователя, так как она ничего не вернет, пока не будет выполнен onConnect.

+0

Paul, я пробовал этот подход, но сопрограмма продолжается бесконечно. :/Я надеялся, что я делаю это неправильно, и что есть какой-то волшебный соус, чтобы заставить его работать, но я подозреваю, что архитектура моего пользовательского интерпретатора лежит в основе этой проблемы. – mikejonesguy

+0

Я собираюсь принять этот ответ, так как я думаю, что предложение звуковое, хотя оно и не решило мою проблему. – mikejonesguy

+0

Хм, я бы не ожидал, что сопрограмма продолжит бесконечно, так как после печати «Подключение ...» она закончится и вернется, что сделает ее статусом «мертвым». Похоже, вы не можете выполнять последние «возобновления» звонков, которые оставляют сопрограмму в статусе «unfihised». Это все еще не большая проблема, как если бы не было других ссылок, указывающих на это, это будет сбор мусора. –