--先上一個實例,再附源代碼啦~
--日常使用本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