您的位置:首页 > 其它

基于帧的分时调度框架设计

2013-07-26 08:27 204 查看
随着项目的推进,越来越多的需要在帧与帧之间写一些pause&continue的任务,写了几个后,觉得还是要从框架上来解决这个问题比较好。比如你需要渲染一个很大很大的表格。而表格单元里的内容和大小是是先不知道的,每一个表格的里单元渲染完毕都有可能直接引发整体的重新布局,这个消耗是非常大的,因此渲染和布局的任务不能一次性完成,就像加载页面的浏览器,如果在页面载入的时候不能进行任何操作,估计没有人能够忍受。

分时调度的基本思想是把原本一份执行过程切分成N分,一次执行一份或几份,如果在本帧内执行不完,就留到下一帧执行,直到全部执行完毕。这样保证前端的流畅度并且能完成任务,此外,如果有多个任务在执行的话,就存在调度的问题,不然大家就会撞车,结果还是跟不分开执行没什么么区别。

这时候,要是用python,ruby,或lua这样的软件来写程序就爽死了,直接在方法中放入yield。要做的事情是最少的。go的话,据说有coroutine,应该也不错。不支持yield的程序语言,有的人肯定想到了用线程……如果要用线程,权衡下由之引发的问题,宁可寻找一种不那么直接的处理方法。

接口设计:

function add(type:int,tasks:Array,callback:function)

type决定了一个此tasks的运行方式,基本类型有
1.顺次执行

假设一个任务的流程是

function foo(){
//do something1
//do something2
//do something3
return result
}

改写成

function foo(callback){
function do1(){
//do something1
}
function do2(){
//do something2
}
function do3(){
//do something3
}
function getresult(){
callback(result)
}

add(1,[do1,do2,do3],getresult)

}

2.链形

链形每次返回下次执行的方法,直到返回null结束,比如for循环

function foo(){
for(i=0;i<10;i++){
//do something1
}
}

改写后变成

function foo(callback){
i = 0;
function doNext(){
//do something1
i++;
if(i<10){
return doNext;
}else{
callback();
return null;
}
}

add(2,[doNext],null);
}

可以选择将callback交给调度器返回,也可自行返回,自由决定。

调度主循环

function startLoop(){
timeleft = 0;
onExitFrame(){
timeleft = getTime();
}
onEnterFrame(){
timeleft = 1000/30-(timeleft-getTime());//比较两个差值记录本帧剩余时间量。假设一秒钟运行30帧
if(timeleft<=0){
//即使帧内时间已耗尽,至少执行一次
return;
}
while(timeleft){
time = getTime();
//遍历每个任务,执行
timeleft -= getTime()-time;//减去执行任务的损耗
},
}

}

差不多了,其实还可以加上优先级别,再加上挂起,中断等方法,这就是个线程框架了,实施代码要多些。
虽然没有yield,但是人工的将代码分割,也并不是那么复杂的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: