refactor: 删除 gl.ts,优化子元素增添的性能表现

This commit is contained in:
unanmed 2024-11-06 21:46:26 +08:00
parent 724eabd49a
commit 740dfdb6ce
4 changed files with 50 additions and 68 deletions

View File

@ -46,7 +46,7 @@ export class Container<E extends EContainerEvent = EContainerEvent>
}); });
} }
private requestSort() { requestSort() {
if (!this.needSort) { if (!this.needSort) {
this.needSort = true; this.needSort = true;
this.requestBeforeFrame(() => { this.requestBeforeFrame(() => {
@ -62,11 +62,8 @@ export class Container<E extends EContainerEvent = EContainerEvent>
*/ */
appendChild(...children: RenderItem<any>[]) { appendChild(...children: RenderItem<any>[]) {
children.forEach(v => { children.forEach(v => {
v.remove(); v.append(this);
this.children.add(v);
v.parent = this;
}); });
children.forEach(v => (v.parent = this));
this.requestSort(); this.requestSort();
this.update(this); this.update(this);
} }
@ -74,15 +71,16 @@ export class Container<E extends EContainerEvent = EContainerEvent>
removeChild(...child: RenderItem<any>[]): void { removeChild(...child: RenderItem<any>[]): void {
let changed = false; let changed = false;
child.forEach(v => { child.forEach(v => {
const success = this.children.delete(v); const success = v.remove();
if (success) changed = true; if (success) {
v.parent = void 0; changed = true;
}
}); });
if (changed) this.requestSort(); if (changed) this.requestSort();
this.update(this); this.update(this);
} }
sortChildren() { private sortChildren() {
this.sortedChildren = [...this.children].sort( this.sortedChildren = [...this.children].sort(
(a, b) => a.zIndex - b.zIndex (a, b) => a.zIndex - b.zIndex
); );

View File

@ -1,40 +0,0 @@
import { MotaOffscreenCanvas2D, MotaOffscreenCanvasGL2 } from '../fx/canvas2d';
import { RenderItem } from './item';
import { Transform } from './transform';
type GL2RenderFunc = (
canvas: MotaOffscreenCanvasGL2,
transform: Transform
) => void;
export class GL2 extends RenderItem {
canvas: MotaOffscreenCanvasGL2 = new MotaOffscreenCanvasGL2();
/** 渲染函数 */
private renderFn: GL2RenderFunc = () => {};
protected render(
canvas: MotaOffscreenCanvas2D,
transform: Transform
): void {
const gl = this.canvas.gl;
gl.viewport(0, 0, this.canvas.width, this.canvas.height);
gl.clearColor(0, 0, 0, 0);
gl.clearDepth(1);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
this.renderFn(this.canvas, transform);
canvas.ctx.drawImage(this.canvas.canvas, 0, 0, this.width, this.height);
}
/**
* gl2元素的渲染函数
* @param fn
*/
setRenderFn(fn: GL2RenderFunc) {
this.renderFn = fn;
}
}

View File

@ -67,9 +67,9 @@ export interface IRenderChildable {
removeChild(...child: RenderItem<any>[]): void; removeChild(...child: RenderItem<any>[]): void;
/** /**
* * tick的渲染前对子元素进行排
*/ */
sortChildren(): void; requestSort(): void;
} }
interface IRenderFrame { interface IRenderFrame {
@ -162,11 +162,13 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
return this._id; return this._id;
} }
set id(v: string) { set id(v: string) {
if (this.isRoot || this.findRoot()) {
if (RenderItem.itemMap.has(this._id)) { if (RenderItem.itemMap.has(this._id)) {
logger.warn(23); logger.warn(23);
RenderItem.itemMap.delete(this._id); RenderItem.itemMap.delete(this._id);
} }
RenderItem.itemMap.set(v, this); RenderItem.itemMap.set(v, this);
}
this._id = v; this._id = v;
} }
@ -193,6 +195,8 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
/** 当前元素的父元素 */ /** 当前元素的父元素 */
parent?: RenderItem & IRenderChildable; parent?: RenderItem & IRenderChildable;
/** 当前元素是否为根元素 */
readonly isRoot: boolean = false;
protected needUpdate: boolean = false; protected needUpdate: boolean = false;
@ -222,6 +226,18 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
this.cache.withGameScale(true); this.cache.withGameScale(true);
} }
private findRoot() {
let ele: RenderItem = this;
while (!ele.isRoot) {
if (!ele.parent) {
return null;
} else {
ele = ele.parent;
}
}
return ele;
}
/** /**
* *
* @param canvas * @param canvas
@ -338,7 +354,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
setZIndex(zIndex: number) { setZIndex(zIndex: number) {
this.zIndex = zIndex; this.zIndex = zIndex;
this.parent?.sortChildren?.(); this.parent?.requestSort();
} }
requestBeforeFrame(fn: () => void): void { requestBeforeFrame(fn: () => void): void {
@ -407,15 +423,27 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
* *
* @param parent * @param parent
*/ */
append(parent: IRenderChildable) { append(parent: IRenderChildable & RenderItem) {
parent.appendChild(this); this.remove();
parent.children.add(this);
this.parent = parent;
if (this._id !== '') {
const root = this.findRoot();
if (!root) return;
RenderItem.itemMap.set(this._id, this);
}
} }
/** /**
* *
*/ */
remove() { remove(): boolean {
this.parent?.removeChild(this); if (!this.parent) return false;
const success = this.parent.children.delete(this);
this.parent = void 0;
if (!success) return false;
RenderItem.itemMap.delete(this._id);
return true;
} }
/** /**
@ -431,19 +459,16 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
RenderItem.ticker.add(() => { RenderItem.ticker.add(() => {
if (beforeFrame.length > 0) { if (beforeFrame.length > 0) {
const toEmit = beforeFrame.slice(); beforeFrame.forEach(v => v());
beforeFrame.splice(0); beforeFrame.splice(0);
toEmit.forEach(v => v());
} }
if (renderFrame.length > 0) { if (renderFrame.length > 0) {
const toEmit = renderFrame.slice(); renderFrame.forEach(v => v());
renderFrame.splice(0); renderFrame.splice(0);
toEmit.forEach(v => v());
} }
if (afterFrame.length > 0) { if (afterFrame.length > 0) {
const toEmit = afterFrame.slice(); afterFrame.forEach(v => v());
afterFrame.splice(0); afterFrame.splice(0);
toEmit.forEach(v => v());
} }
}); });

View File

@ -9,6 +9,7 @@ export class MotaRenderer extends Container {
target: MotaCanvas2D; target: MotaCanvas2D;
protected needUpdate: boolean = false; protected needUpdate: boolean = false;
readonly isRoot: boolean = true;
constructor(id: string = 'render-main') { constructor(id: string = 'render-main') {
super('static', false); super('static', false);
@ -37,10 +38,8 @@ export class MotaRenderer extends Container {
protected refresh(item?: RenderItem): void { protected refresh(item?: RenderItem): void {
this.emit('beforeUpdate', item); this.emit('beforeUpdate', item);
// console.time();
this.target.clear(); this.target.clear();
this.renderContent(this.target, Transform.identity); this.renderContent(this.target, Transform.identity);
// console.timeEnd();
this.emit('afterUpdate', item); this.emit('afterUpdate', item);
} }