diff options
| author | Opportunity <[email protected]> | 2020-05-24 01:30:38 +0800 |
|---|---|---|
| committer | Opportunity <[email protected]> | 2020-05-25 20:12:28 +0800 |
| commit | fe8e6ea390531932439ba772b2ac434f38e8a2bd (patch) | |
| tree | 70e445ea88ea644e4a1efbe020d7f71bed5c2d58 /xmake/modules/private | |
| parent | 05b37be8865ff1af2051766a835e7576a6780e55 (diff) | |
A better progress indicator
Diffstat (limited to 'xmake/modules/private')
| -rw-r--r-- | xmake/modules/private/async/runjobs.lua | 58 | ||||
| -rw-r--r-- | xmake/modules/private/utils/progress.lua | 91 |
2 files changed, 117 insertions, 32 deletions
diff --git a/xmake/modules/private/async/runjobs.lua b/xmake/modules/private/async/runjobs.lua index 2b848bde5..cd130e6c9 100644 --- a/xmake/modules/private/async/runjobs.lua +++ b/xmake/modules/private/async/runjobs.lua @@ -20,31 +20,24 @@ -- imports import("core.base.scheduler") +import("private.utils.progress") -- print back characters function _print_backchars(backnum) if backnum > 0 then - local str = "" - for i = 1, backnum do - str = str .. '\b' - end - for i = 1, backnum do - str = str .. ' ' - end - for i = 1, backnum do - str = str .. '\b' - end + local str = ('\b'):rep(backnum) .. (' '):rep(backnum) .. ('\b'):rep(backnum) if #str > 0 then printf(str) end end end --- asynchronous run jobs +-- asynchronous run jobs -- --- e.g. +-- e.g. -- runjobs("test", function (index) print("hello") end, {total = 100, comax = 6, timeout = 1000, timer = function (running_jobs_indices) end}) --- runjobs("test", function () os.sleep(10000) end, {showtips = true}) +-- runjobs("test", function () os.sleep(10000) end, { progress = true }) +-- runjobs("test", function () os.sleep(10000) end, { progress = { chars = {'/','\'} } }) -- see module private.utils.progress -- -- local jobs = jobpool.new() -- local root = jobs:addjob("job/root", function (idx, total) @@ -71,10 +64,14 @@ function main(name, jobs, opt) assert(jobs, "runjobs: no jobs!") -- show waiting tips? - local waitindex = 0 - local waitchars = opt.waitchars or {'\\', '-', '/', '|'} + local showprogress = io.isatty() and (opt.progress or opt.showtips) -- we need hide wait characters if is not a tty + local progress_helper local backnum = 0 - local showtips = io.isatty() and opt.showtips -- we need hide wait characters if is not a tty + if showprogress then + local opt = nil + if type(showprogress) == 'table' then opt = showprogress end + progress_helper = progress.new(nil, opt) + end -- run timer local stop = false @@ -88,17 +85,13 @@ function main(name, jobs, opt) end end end) - elseif showtips then + elseif showprogress then scheduler.co_start_named(name .. "/tips", function () while not stop do os.sleep(timeout) if not stop then - -- print back characters - _print_backchars(backnum) - -- show waitchars - waitindex = ((waitindex + 1) % #waitchars) local tips = nil local waitobjs = scheduler.co_group_waitobjs(group_name) if waitobjs:size() > 0 then @@ -121,14 +114,16 @@ function main(name, jobs, opt) tips = string.format("(%d/%s)", waitobjs:size(), names) end end + + -- print back characters + progress_helper:clear() + _print_backchars(backnum) + if tips then - cprintf("${dim}%s${clear} %s", tips, waitchars[waitindex + 1]) - backnum = #tips + 2 - else - printf(waitchars[waitindex + 1]) - backnum = 1 + cprintf("${dim}%s${clear} ", tips) + backnum = #tips + 1 end - io.flush() + progress_helper:write() end end end) @@ -198,10 +193,9 @@ function main(name, jobs, opt) stop = true -- remove wait charactor - if showtips then + if showprogress then _print_backchars(backnum) - print("") - io.flush() + progress_helper:stop() end -- do exit callback @@ -235,9 +229,9 @@ function main(name, jobs, opt) stop = true -- remove wait charactor - if showtips then + if showprogress then _print_backchars(backnum) - io.flush() + progress_helper:stop() end -- do exit callback diff --git a/xmake/modules/private/utils/progress.lua b/xmake/modules/private/utils/progress.lua new file mode 100644 index 000000000..f95baa088 --- /dev/null +++ b/xmake/modules/private/utils/progress.lua @@ -0,0 +1,91 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-2020, TBOOX Open Source Group. +-- +-- @author OpportunityLiu +-- @file progress.lua +-- + +-- imports +import('core.base.object') + +-- print back characters +function _make_clearchars(backnum) + if backnum > 0 then + return ('\b'):rep(backnum) .. (' '):rep(backnum) .. ('\b'):rep(backnum) + end + return '' +end + +-- define module +local process = process or object { _init = { "_RUNNING", "_INDEX", "_STREAM", "_OPT", "_CLEAR" } } + +-- stop the progress indicator, clear written frames +function process:stop() + if self._RUNNING ~= 0 then + self:clear() + self._RUNNING = 0 + self._INDEX = 0 + end +end + +function process:_clear() + if self._RUNNING == 1 then + self._STREAM:write(self._CLEAR) + self._RUNNING = 2 + return true + end +end + +-- clear previous frame of the progress indicator +function process:clear() + if self:_clear() then + self._STREAM:flush() + end +end + +-- write next frame of the progress indicator +function process:write() + local chars = self._OPT.chars[self._INDEX % #self._OPT.chars + 1] + self:_clear() + self._STREAM:write(chars) + self._STREAM:flush() + self._INDEX = self._INDEX + 1 + self._RUNNING = 1 +end + +-- check if the progress indicator is running +function process:running() + return self._RUNNING and true or false +end + +-- build a progress indicator +-- @params stream - stream to write to, will use io.stdout if not provided +-- @params opt - options +-- - chars - an array of chars for progress indicator +-- - width - width of progress indicator, will use #opt.chars[0] if not provided +function new(stream, opt) + + -- set default values + stream = stream or io.stdout + opt = opt or {} + if opt.chars == nil or #opt.chars == 0 then + opt.chars = {'⢎⠀', '⢆⡀', '⢄⡠', '⢀⡰','⠀⡱', '⠈⠱', '⠊⠑', '⠎⠁'} + opt.width = 2 + end + opt.width = opt.width or #opt.chars[1] + + return process { _OPT = opt, _STREAM = stream, _RUNNING = 0, _INDEX = 0, _CLEAR = _make_clearchars(opt.width) } +end
\ No newline at end of file |
