Lua - Объединить несколько аргументов, переданных в функцию, до тех пор, пока условие не будет выполнено, затем передать строку следующей функции - PullRequest
0 голосов
/ 12 февраля 2020

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

Example.
pvMessage #1 = thisispart1msg
pvMessage #2 = now part two is being received
pvMessage #3 = Part 3

MasterMessage = thisispart1msgnow part two is being receivedPart 3

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

    function ProcessClientMessage( pvMessage ) 
         if StartMessage == "" then
            StartMessage = pvMessage                
            pvMessage = ""
         end

         if pvMessage ~= "" then
             if MiddleMessage == "" then
                MiddleMessage = pvMessage
                pvMessage = StartMessage .. MiddleMessage
                pvMessage = ""
             end
          end

         if pvMessage ~= "" then
            if EndMessage == "" then
                EndMessage = pvMessage
                pvMessage = StartMessage .. MiddleMessage .. EndMessage
                pvMessage = ""
             end
         end

         if pvMessage ~= "" then
            ProcessClientMessageReset()
         end 
    end

Ответы [ 3 ]

0 голосов
/ 12 февраля 2020

Эту проблему также можно решить с помощью сопрограмм:

local function consumer(consume)
   print(consume()..consume()..consume())
   return consumer(consume)
end

local process = coroutine.wrap(consumer)
process(coroutine.yield)

process('foo')
process('bar')
process('baz')

process('hello')
process('world')
process('test')

РЕДАКТИРОВАТЬ: Как отметил Егор, порядок оценки технически не определен (хотя он слева направо в каждом Lua реализация, о которой я знаю), так что вот альтернатива, которая будет работать, даже если ваш интерпретатор выполняет gcc -O3 -подобные оптимизации:

local function consumer(consume)
   local a = consume()
   local b = consume()
   local c = consume()
   print(a .. b .. c)
   return consumer(consume)
end
0 голосов
/ 16 февраля 2020

Вы можете использовать присваивание "или", чтобы упростить инициализацию глобальной переменной, а затем объединить строку с результатом. Рассмотрим:

function ProcessClientMessage(msg)
    msg_global_ = (msg_global_ or "")..msg
    print(msg_global_) -- Just for debug purposes so we can print each step
end

do
    ProcessClientMessage("thisispart1msg")
    ProcessClientMessage("now part two is being received")
    ProcessClientMessage("Part 3")
end

Переменная msg_global_ содержит строящуюся строку. Если он еще не был добавлен, он будет равен нулю. В этом случае or "" будет выполнено и по умолчанию строка будет пустой.

Затем мы просто добавим строку msg.

Вывод будет выглядеть так:

thisispart1msg
thisispart1msgnow part two is being received
thisispart1msgnow part two is being receivedPart 3

Когда вы на самом деле обрабатываете сообщение, просто установите глобальную переменную равной nil, и у вас снова получится go.

0 голосов
/ 12 февраля 2020

Если всегда есть три части, которые вы хотите объединить, может сработать что-то вроде этого:

local buffer = {}
local function ProcessClientMessage(pvMessage) 
  if #buffer < 3 then
    table.insert(buffer, pvMessage)
  else
    --ProcessClientMessageReset(table.concat(buffer, ""))
    print(table.concat(buffer, ""))
    buffer = {}
  end
end
ProcessClientMessage("thisispart1msg")
ProcessClientMessage("now part two is being received")
ProcessClientMessage("Part 3")

ProcessClientMessage("more thisispart1msg")
ProcessClientMessage("some now part two is being received")
ProcessClientMessage("Part 4")

Это должно вывести:

thisispart1msgnow part two is being receivedPart 3
more thisispart1msgsome now part two is being receivedPart 4
...