您的位置:首页 > 编程语言 > Lua

[LUA]taskMaid——多线程任务管理器(支持异步)

2018-06-17 19:43 190 查看
--先上一个实例,再附源代码啦~

--日常使用本taskMaid的完整操作

taskMaid:onInit()    --初始化任务管理器

--小任务:数苹果

--任务失败的回调函数
local function f_callback(n_delta)
print(n_delta)
end
--数一个苹果
local function f_task(t_cache)
t_cache[1]=t_cache[1]+1
return true                --这条任务成功完成
end
local apple={0}

--注册一个任务
local order=taskMaid:requestNewTaskOrder("calculate_the_number_of_apples",f_callback,apple,1)

--为这个任务添加若干任务函数。在任务执行时,每一帧会执行一次任务
taskMaid:pushTask(order,f_task,1,"failed to calculate the number of apple!")
taskMaid:pushTask(order,function (t_cache)
t_cache[1]=t_cache[1]+5
return true
end,"failed to calculate the number of apple!")
--taskMaid:pushTask...
taskMaid:pushTask(order,function (t_cache)
chiefMaid:printLog("We have got %d apples!",t_cache[1])
end)

--开始启动这个任务
taskMaid:startTask(order)

--注意:taskMaid的任务并不是即时执行的,而是以一帧一步的方式执行的。在这一帧启动或终止任务,意为从下一帧开始执行或清理该任务。

while(true) do
taskMaid:onUpdate()
end

这是一个近写的lua多线程任务管理器。

接口简洁,功能实用,我**吹爆!(乛◡乛)

这个管理器的特殊处在于需要调用taskMaid:onUpdate来进行刷新,故支持异步处理任务,非常适合在游戏项目中接入(比如搞一个进度条)。
作者为lua鲜肉一只,欢迎各位不吝赐教、提问
local tasks
taskMaid={}
--[[
--任务的状态
TaskStatus=
{
"suspended",
"running",
"dead",
"failed",
}

--task类型的数据结构
Task={
[1]={
name="",
        speed=1,
dirty=false,
routine=coroutine.create(),
status="suspended",
callback=nil,
cache=nil,
totalProgress=...,只有运行任务队列后totalProgress才会被更新
currentProgress=...,
[1]=f_task_1,
[2]=...
}
}
--]]

--初始化taskMaid
function taskMaid:onInit()
tasks={}
return true
end

--刷新taskMaid
function taskMaid:onUpdate()
for order,task in pairs(tasks) do
taskMaid:updateTask(order)
end
end

--查看当前帧是否存在需要执行的任务
function taskMaid:hasTaskRunning()
for _,v in pairs(tasks) do
if(v.status=="running") then return true end
end
return false
end

local f_coroutineFuntion=function (task)
local least=task.speed
for _,t in ipairs(task) do
if(t[1](task.cache)) then
if(task.callback) then
task.callback(t[2]/task.totalProgress)
end
task.currentProgress=task.currentProgress+t[2]
else
task.status="failed"
if(type(t[3])=="function") then
t[3](task.cache)
elseif(type(t[3]=="string")) then
--fixme_str
end
end
least=least-1
if(least<=0 or task.status~="running") then
coroutine.yield()
end
end
task.status="dead"
end
--申请得到一个新的任务指令,接下来可以通过这条指令来下达、执行、暂停或终止某项任务;f_onProgressChange=function(n_deltaPercent) end:在进度变化时的回调函数,输入参数为进度变化的分数(0.0~1.0),每执行一条任务函数都会导致任务进度变化;t_cache内容由开发者自定,作为辅助数据,将作为参数传入任务函数中;i_speed为执行速度,即每步(每帧)执行的任务函数数量,必须为一个正数
function taskMaid:requestNewTaskOrder(s_name --[[nilable]],f_onProgressChange--[[nilable]],t_cache --[[nilable]],i_speed--[[nilable]])
i_speed=i_speed and i_speed>0 and math.ceil(i_speed) or 1
local task={speed=i_speed,dirty=false,status="suspended",callback=f_onProgressChange,name=s_name,currentProgress=0,cache=t_cache}
task.routine=coroutine.create(f_coroutineFuntion)
local ret=#tasks+1
table.insert(tasks,task)
return ret
end

function taskMaid:getTaskOrderByName(s_name)
for order,task in pairs(tasks) do
if(task.name==s_name) then
return order
end
end
end

--根据任务指令,在任务尾部新添一条分任务。注意,不可以对一个正在运行中的任务进行以下操作!f_task =function(t_cache) return true --[[success]] end:任务函数。n_taskAmount:这一条任务函数所占的任务量。sf_onFail=function (t_cache) end or "message":这条分任务出错时的回调函数
function taskMaid:pushTask(n_order,f_task,n_taskAmount --[[nilable]],sf_onFail --[[nilable]])
local task=tasks[n_order]
if(not task) then return end --fixme_str
if(task.status=="running") then return end --fixme_str
task.dirty=true
table.insert(task,{f_task,n_taskAmount or 1,sf_onFail})
end

function taskMaid:refreshTask(n_order)
local task=tasks[n_order]
if(not task) then return end --fixme_str
if(not task.dirty) then return end
local totalTaskNum=0
for _,t in ipairs(task) do
totalTaskNum=totalTaskNum+t[2]
end
task.totalProgress=totalTaskNum
task.dirty=false
end

--直接设置某项任务的状态。谨慎调用。框架在每条任务函数结束完成后,都会检查一次任务状态,来判断该任务是否需要暂停、结束等。框架在每帧开始时都会检查一次任务状态,来判断该任务是否需要执行、销毁等。
function taskMaid:setTaskStatus(n_order,s_status)
local task=tasks[n_order]
if(task) then
task.status=s_status
end
end

--执行或恢复执行某任务。(会重新计算totalProgress的值)
function taskMaid:startTask(n_order)
taskMaid:setTaskStatus(n_order,"running")
end

--暂停某项任务
function taskMaid:suspendTask(n_order)
taskMaid:setTaskStatus(n_order,"suspended")
end

--终止某项任务
function taskMaid:stopTask(n_order)
taskMaid:setTaskStatus(n_order,"dead")
end

--根据指令获取某任务的数据,将允许对数据内容直接操作,谨慎调用
function taskMaid:getTaskData(n_order)
return tasks[n_order]
end

--获取某项任务的状态
function taskMaid:getTaskStatus(n_order)
local task=tasks[n_order]
if(task) then return task.status end
end

--刷新某项任务,系统在每一帧都会为所有任务调用一次
function taskMaid:updateTask(n_order)
taskMaid:refreshTask(n_order)
local task=tasks[n_order]
if(not task) then return end
if(task.status=="running") then
--do task
coroutine.resume(task.routine,task)
elseif(task.status=="dead") then
--release task
tasks[n_order]=nil
elseif(task.status=="failed") then
--show information
--fixme
end
end


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: