From 7f477c4cb91c04c243dfa6ebb60a1321d6223ac3 Mon Sep 17 00:00:00 2001 From: Ildar Mulyukov Date: Tue, 30 Jun 2020 15:43:58 +0600 Subject: [PATCH] init.lua: change method for print() from coroutines --- app/src/main/assets/call_in_mainthread.lua | 32 ++++++ app/src/main/assets/fifo.lua | 114 --------------------- app/src/main/assets/init.lua | 25 ++--- 3 files changed, 42 insertions(+), 129 deletions(-) create mode 100644 app/src/main/assets/call_in_mainthread.lua delete mode 100644 app/src/main/assets/fifo.lua diff --git a/app/src/main/assets/call_in_mainthread.lua b/app/src/main/assets/call_in_mainthread.lua new file mode 100644 index 0000000..1148778 --- /dev/null +++ b/app/src/main/assets/call_in_mainthread.lua @@ -0,0 +1,32 @@ +-- Helper module for changing call context from a coroutine to the main thread + +local mainthread_stash = {} + +local function mainthread_call(f, ...) + local thread = coroutine.running() + assert(thread, "cannot call from the main thread") + mainthread_stash[thread] = mainthread_stash[thread] or {} + mainthread_stash[thread].status = nil + mainthread_stash[thread].f = f + mainthread_stash[thread].args = {...} + while mainthread_stash[thread].status == nil do + coroutine.yield() + end + return mainthread_stash[thread].status, mainthread_stash[thread].res +end + +local function mainthread_process() + local co, main = coroutine.running() + assert( main or co == nil, "cannot call from a coroutine") + for thread,_ in pairs(mainthread_stash) do + if mainthread_stash[thread].status == nil then + mainthread_stash[thread].status, mainthread_stash[thread].res = + pcall( mainthread_stash[thread].f, unpack(mainthread_stash[thread].args) ) + end + end +end + +return { + mainthread_call = mainthread_call, + mainthread_process = mainthread_process, +} diff --git a/app/src/main/assets/fifo.lua b/app/src/main/assets/fifo.lua deleted file mode 100644 index f4ab3c2..0000000 --- a/app/src/main/assets/fifo.lua +++ /dev/null @@ -1,114 +0,0 @@ -local select , setmetatable = select , setmetatable - -local function is_integer(x) - return x % 1 == 0 -end - -local fifo = {} -local fifo_mt = { - __index = fifo ; - __newindex = function() - error("Tried to set table field in fifo") - end ; -} - -local empty_default = function ( _ ) error ( "Fifo empty" ) end - -function fifo.new ( ... ) - return setmetatable({ - empty = empty_default; - head = 1; - tail = select("#",...); - data = {...}; - }, fifo_mt) -end - -function fifo:length ( ) - return self.tail - self.head + 1 -end -fifo_mt.__len = fifo.length - --- Peek at the nth item -function fifo:peek ( n ) - n = n or 1 - assert(is_integer(n), "bad index to :peek()") - - local index = self.head - 1 + n - if index > self.tail then - return nil, false - else - return self.data[index], true - end -end - -function fifo:push ( v ) - self.tail = self.tail + 1 - self.data[self.tail] = v -end - -function fifo:pop ( ) - local head , tail = self.head , self.tail - if head > tail then return self:empty() end - - local v = self.data[head] - self.data[head] = nil - self.head = head + 1 - return v -end - -function fifo:insert ( n , v ) - local head , tail = self.head , self.tail - - if n <= 0 or head + n > tail + 2 or not is_integer(n) then - error("bad index to :insert()") - end - - local p = head + n - 1 - if p <= (head + tail)/2 then - for i = head , p do - self.data[i- 1] = self.data[i] - end - self.data[p- 1] = v - self.head = head - 1 - else - for i = tail , p , -1 do - self.data[i+ 1] = self.data[i] - end - self.data[p] = v - self.tail = tail + 1 - end -end - -function fifo:remove ( n ) - local head , tail = self.head , self.tail - - if n <= 0 or not is_integer(n) then - error("bad index to :remove()") - end - - if head + n - 1 > tail then return self:empty() end - - local p = head + n - 1 - local v = self.data[p] - - if p <= (head + tail)/2 then - for i = p , head , -1 do - self.data[i] = self.data[i-1] - end - self.head = head + 1 - else - for i = p , tail do - self.data[i] = self.data[i+1] - end - self.tail = tail - 1 - end - - return v -end - -function fifo:setempty ( func ) - self.empty = func - return self -end - -return fifo.new diff --git a/app/src/main/assets/init.lua b/app/src/main/assets/init.lua index 48615bd..c073a25 100644 --- a/app/src/main/assets/init.lua +++ b/app/src/main/assets/init.lua @@ -3,27 +3,22 @@ -- replace print local Log = luajava.bindClass 'android.util.Log' -local print_spooler_fifo = require("fifo") () ; print_spooler_fifo:setempty(function() return nil; end) -function print_spooler() - assert( not coroutine.running(), "print_spooler() cannot be used from a coroutine" ) - local msg_tab = print_spooler_fifo:pop() - while msg_tab do - Log:v("lua-print", table.concat(msg_tab,'\t')) - msg_tab = print_spooler_fifo:pop() - end -end +local cim = require 'call_in_mainthread' function print(...) local args = {...} - if tostring(args[1]):find("No such method") then - print_spooler_fifo:push( { debug.traceback() } ) - end for i=1,#args do args[i] = tostring(args[i]) end - print_spooler_fifo:push( args ) - if not coroutine.running() then - print_spooler() + if coroutine.running() then + cim.mainthread_call(Log.v, Log, "lua-print-co", table.concat(args,'\t')) + else + cim.mainthread_process() + Log:v("lua-print", table.concat(args,'\t')) + end +--[[ if tostring(args[1]):find("No such method") then + print( { debug.traceback() } ) end +]] end print "AndroidLuaSDK init finished"