@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
127 lines (97 loc) • 3.16 kB
JavaScript
import { ShadedGeometry } from "../../ShadedGeometry.js";
import { ShadedGeometryFlags } from "../../ShadedGeometryFlags.js";
export class RuntimeDrawMethodOptimizer {
constructor() {
/**
*
* @type {ShadedGeometrySystem|null}
* @private
*/
this.__system = null;
/**
*
* @type {Generator<number>}
* @private
*/
this.__entity_iterator = null;
}
/**
*
* @returns {boolean} true if a change was made, false otherwise
*/
step() {
const system = this.__system;
if (system === null) {
return false;
}
const ecd = system.entityManager.dataset;
if (ecd === null) {
// no dataset attached
return false;
}
if (!ecd.isComponentTypeRegistered(ShadedGeometry)) {
// component not registered
return false;
}
if (this.__entity_iterator === null) {
this.__entity_iterator = ecd[Symbol.iterator]();
}
const next = this.__entity_iterator.next();
if (next.done) {
this.__entity_iterator = ecd[Symbol.iterator]();
return false;
}
const entity = next.value;
if (!ecd.entityExists(entity)) {
// seems that iterator is stale, reset iterator
this.__entity_iterator = null;
return false;
}
/**
*
* @type {ShadedGeometry}
*/
const sg = ecd.getComponent(entity, ShadedGeometry);
if (sg === undefined) {
return false;
}
if (sg.getFlag(ShadedGeometryFlags.DrawMethodLocked)) {
// draw mode is locked, can't change
return false;
}
const use_count = system.getGeometryUsageCounters().get(sg.geometry.id);
/**
*
* @type {ShadedGeometryRendererContext|undefined}
*/
const first_context = system.__view_contexts.values().next().value;
if (first_context === undefined) {
return false;
}
const adapters = first_context.adapters;
const adapter_count = adapters.length;
let best_score = Number.NEGATIVE_INFINITY;
let best_adapter = -1;
for (let i = 0; i < adapter_count; i++) {
const adapter = adapters[i];
const score = adapter.score(sg.geometry, sg.material, use_count);
if (score > best_score) {
best_score = score;
best_adapter = i;
}
}
if (best_adapter === -1) {
// not found
return false;
}
if (sg.draw_method === best_adapter) {
return false;
}
if (!adapters[best_adapter].intend_draw(sg)) {
// unable to draw, don't do anything
return false;
}
sg.draw_method = best_adapter;
return true;
}
}