基于帧的分时调度框架设计
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,但是人工的将代码分割,也并不是那么复杂的。
分时调度的基本思想是把原本一份执行过程切分成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,但是人工的将代码分割,也并不是那么复杂的。
相关文章推荐
- 【niubi-job——一个分布式的任务调度框架】----框架设计原理以及实现
- 分布式任务编排调度框架设计
- 【niubi-job——一个分布式的任务调度框架】----框架设计原理以及实现
- 分布式任务编排调度框架设计 -- 学习参考
- niubi-job:一个分布式的任务调度框架设计原理以及实现
- 【niubi-job——一个分布式的任务调度框架】----框架设计原理以及实现
- 一个为无阻流量规则分配与端点规则实施而设计的通用最优化框架(一)
- 框架设计(第2版):CLR Via C#
- 自己动手设计java web框架(一)-封装请求拦截器DispatchServlet
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- .net开发工具LINQ框架设计指南
- 3d游戏的总体设计框架
- unity 资源加载框架设计
- 8X8X8光立方整体框架设计&技术细节
- quartz任务调度框架中的Cron表达式详解
- Delphi项目框架设计
- Quartz调度框架应用总结<3>
- 一个基于装饰者设计模式的上报框架
- Quartz框架——实现定时任务调度
- 除了传统的设计模式外,另外还有一些大的方面-如何从宏观构建软件项目-框架模式一 基础