@turbox3d/shared
Version:
turbox shared internal utility
100 lines • 2.88 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import { Task } from './task';
import { sortBy, nextTick } from './common';
/**
* 任务优先级。数据越小,优先级越高
*/
export var TaskPriority;
(function (TaskPriority) {
/**
* 用户行为(比如:各种交互行为)
*/
TaskPriority[TaskPriority["UserAction"] = 0] = "UserAction";
/**
* 更新领域数据
*/
TaskPriority[TaskPriority["UpdateState"] = 1] = "UpdateState";
/**
* 更新 React 组件
*/
TaskPriority[TaskPriority["RenderReact"] = 2] = "RenderReact";
/**
* 更新场景视图
*
* 暂定高优先级,因为基于之后场景组件化的机制,这一帧绘制的应该是上一帧的结果
*/
TaskPriority[TaskPriority["RenderScene"] = -1] = "RenderScene";
})(TaskPriority || (TaskPriority = {}));
/**
* TODO:
* 1. 收集这里的任务排队执行情况
* 2. 根据搜集数据+行业中的任务切片方案来优化这边的任务执行
*/
// 存储的任务队列
var tasks = [];
// 是否注册了任务待执行
var readyToExecute = false;
/**
* 节流函数
*/
function throttleByFrames(func, maxFPS) {
var frameInterval = 1000 / maxFPS; // 计算每帧的时间间隔(毫秒)
var lastTime = 0;
return function () {
var now = Date.now();
if (now - lastTime >= frameInterval) {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
func.apply(this, args);
lastTime = now;
}
};
}
/**
* 执行任务队列
*/
function executeTask() {
// 得到排序后的当前任务队列
var currentTasks = sortBy(tasks, function (task) {
return task.priority;
});
// 清空存储的数据
tasks = [];
// 按顺序执行当前任务队列
currentTasks.forEach(function (task) {
var fn = task.fn;
fn();
});
readyToExecute = false;
}
/**
* throttle 函数执行为每帧一次
* @param func 要执行的函数
* @param priority 优先级
*/
export function throttleInAFrame(func) {
var priority = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : TaskPriority.UserAction;
var maxFPS = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 60;
var cacheArgs;
var isPending = false;
function execute() {
isPending = false;
func.apply(void 0, _toConsumableArray(cacheArgs));
}
var f = throttleByFrames(function () {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
cacheArgs = args;
if (!isPending) {
isPending = true;
tasks.push(Task.createTask(execute, priority));
if (!readyToExecute) {
readyToExecute = true;
nextTick(executeTask);
}
}
}, maxFPS);
return f;
}