@spearwolf/twopoint5d
Version:
Create 2.5D realtime graphics and pixelart with WebGL and three.js
115 lines • 3.87 kB
JavaScript
import { VOBufferPool } from './VOBufferPool.js';
import { VOUtils } from './VOUtils.js';
import { VertexObjectBuffer } from './VertexObjectBuffer.js';
import { createVertexObject } from './createVertexObject.js';
import { voBuffer } from './constants.js';
export class VertexObjectPool extends VOBufferPool {
#voIndex;
constructor(descriptor, capacityOrData) {
super(descriptor, capacityOrData);
this.#voIndex = new Array(this.capacity);
}
resize(capacity) {
if (capacity < 0 || !Number.isInteger(capacity)) {
throw new Error('Capacity must be a non-negative integer');
}
if (capacity === this.capacity)
return;
const newBuffer = new VertexObjectBuffer(this.descriptor, capacity);
const copyCount = Math.min(this.usedCount, capacity);
if (copyCount > 0) {
const { vertexCount } = this.descriptor;
for (const [bufferName, oldBuf] of this.buffer.buffers) {
const newBuf = newBuffer.buffers.get(bufferName);
const copyLength = copyCount * vertexCount * oldBuf.itemSize;
newBuf.typedArray.set(oldBuf.typedArray.subarray(0, copyLength));
newBuf.serial++;
}
}
this.buffer = newBuffer;
const newVoIndex = new Array(capacity);
for (let i = 0; i < copyCount; i++) {
const vo = this.#voIndex[i];
if (vo != null) {
vo[voBuffer] = newBuffer;
newVoIndex[i] = vo;
}
}
this.#voIndex = newVoIndex;
Object.defineProperty(this, 'capacity', {
value: capacity,
writable: false,
enumerable: true,
configurable: true,
});
this.usedCount = Math.min(this.usedCount, capacity);
}
createVO() {
if (this.usedCount < this.capacity) {
const idx = this.usedCount++;
const vo = this.#createVO(idx);
this.#voIndex[idx] = vo;
return vo;
}
return undefined;
}
containsVO(vo) {
return VOUtils.isBuffer(vo, this.buffer);
}
dispose() {
if (this.isDisposed)
return;
for (let i = 0; i < this.#voIndex.length; i++) {
const vo = this.#voIndex[i];
if (vo != null) {
if (this.onDestroyVO != null) {
this.onDestroyVO(vo);
}
VOUtils.clearBuffer(vo);
}
}
this.#voIndex.length = 0;
super.dispose();
}
freeVO(vo) {
if (!this.containsVO(vo))
return;
const idx = VOUtils.getIndex(vo);
const lastUsedIdx = this.usedCount - 1;
if (idx === lastUsedIdx) {
this.#destroyVO(idx);
}
else {
this.buffer.copyWithin(idx, lastUsedIdx, lastUsedIdx + 1);
const lastUsedVO = this.#voIndex[lastUsedIdx];
VOUtils.setIndex(lastUsedVO, idx);
this.#voIndex[idx] = lastUsedVO;
}
this.usedCount--;
VOUtils.clearBuffer(vo);
}
getVO(idx) {
let vo = this.#voIndex[idx];
if (vo == null && idx < this.usedCount) {
vo = this.#createVO(idx);
this.#voIndex[idx] = vo;
}
return vo;
}
#destroyVO(idx) {
const vo = this.#voIndex[idx];
if (vo != null && this.onDestroyVO != null) {
this.onDestroyVO(vo);
}
this.#voIndex[idx] = undefined;
}
#createVO(idx) {
const vo = createVertexObject(this.descriptor, this.buffer, idx);
this.buffer.touch();
if (this.onCreateVO != null) {
return this.onCreateVO(vo) ?? vo;
}
return vo;
}
}
//# sourceMappingURL=VertexObjectPool.js.map