mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Merge pull request #198 from Phlosioneer/remove-belt-cache
Optimize belt cache
This commit is contained in:
commit
12927ec0ff
@ -5,6 +5,7 @@ import { BaseItem } from "../base_item";
|
||||
import { Vector, enumDirection } from "../../core/vector";
|
||||
import { Math_PI, Math_sin, Math_cos } from "../../core/builtins";
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { Entity } from "../entity";
|
||||
|
||||
export class BeltComponent extends Component {
|
||||
static getId() {
|
||||
@ -12,6 +13,7 @@ export class BeltComponent extends Component {
|
||||
}
|
||||
|
||||
static getSchema() {
|
||||
// The followUpCache field is not serialized.
|
||||
return {
|
||||
direction: types.string,
|
||||
sortedItems: types.array(types.pair(types.float, types.obj(gItemRegistry))),
|
||||
@ -34,6 +36,9 @@ export class BeltComponent extends Component {
|
||||
|
||||
/** @type {Array<[number, BaseItem]>} */
|
||||
this.sortedItems = [];
|
||||
|
||||
/** @type {Entity} */
|
||||
this.followUpCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,14 +13,13 @@ import { MetaBeltBaseBuilding } from "../buildings/belt_base";
|
||||
import { defaultBuildingVariant } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { Rectangle } from "../../core/rectangle";
|
||||
|
||||
const BELT_ANIM_COUNT = 6;
|
||||
const SQRT_2 = Math_sqrt(2);
|
||||
|
||||
const logger = createLogger("belt");
|
||||
|
||||
/** @typedef {Array<{ entity: Entity, followUp: Entity }>} BeltCache */
|
||||
|
||||
export class BeltSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
super(root, [BeltComponent]);
|
||||
@ -66,9 +65,8 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
this.root.signals.entityDestroyed.add(this.updateSurroundingBeltPlacement, this);
|
||||
|
||||
this.cacheNeedsUpdate = true;
|
||||
|
||||
/** @type {BeltCache} */
|
||||
this.beltCache = [];
|
||||
/** @type {Rectangle[]} */
|
||||
this.smallUpdateAreas = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,6 +117,12 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize for the common case of adding or removing buildings one at a time.
|
||||
// Clicking and dragging can fire up to 4 create/destroy signals.
|
||||
if (this.cacheNeedsUpdate) {
|
||||
this.smallUpdateAreas.push(affectedArea.expandedInAllDirections(1));
|
||||
}
|
||||
}
|
||||
|
||||
draw(parameters) {
|
||||
@ -163,42 +167,28 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a single entity to the cache
|
||||
* @param {Entity} entity
|
||||
* @param {BeltCache} cache
|
||||
* @param {Set} visited
|
||||
*/
|
||||
computeSingleBeltCache(entity, cache, visited) {
|
||||
// Check for double visit
|
||||
if (visited.has(entity.uid)) {
|
||||
return;
|
||||
}
|
||||
visited.add(entity.uid);
|
||||
|
||||
const followUp = this.findFollowUpEntity(entity);
|
||||
if (followUp) {
|
||||
// Process followup first
|
||||
this.computeSingleBeltCache(followUp, cache, visited);
|
||||
}
|
||||
|
||||
cache.push({ entity, followUp });
|
||||
}
|
||||
|
||||
computeBeltCache() {
|
||||
logger.log("Updating belt cache");
|
||||
|
||||
let cache = [];
|
||||
let visited = new Set();
|
||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||
this.computeSingleBeltCache(this.allEntities[i], cache, visited);
|
||||
if (this.smallUpdateAreas.length <= 4) {
|
||||
for (let i = 0; i < this.smallUpdateAreas.length; ++i) {
|
||||
const area = this.smallUpdateAreas[i];
|
||||
for (let x = area.x; x < area.right(); ++x) {
|
||||
for (let y = area.y; y < area.bottom(); ++y) {
|
||||
const tile = this.root.map.getTileContentXY(x, y);
|
||||
if (tile && tile.components.Belt) {
|
||||
tile.components.Belt.followUpCache = this.findFollowUpEntity(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||
const entity = this.allEntities[i];
|
||||
entity.components.Belt.followUpCache = this.findFollowUpEntity(entity);
|
||||
}
|
||||
}
|
||||
assert(
|
||||
cache.length === this.allEntities.length,
|
||||
"Belt cache mismatch: Has " + cache.length + " entries but should have " + this.allEntities.length
|
||||
);
|
||||
|
||||
this.beltCache = cache;
|
||||
this.smallUpdateAreas = [];
|
||||
}
|
||||
|
||||
update() {
|
||||
@ -217,8 +207,8 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
beltSpeed *= 100;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.beltCache.length; ++i) {
|
||||
const { entity, followUp } = this.beltCache[i];
|
||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||
const entity = this.allEntities[i];
|
||||
|
||||
const beltComp = entity.components.Belt;
|
||||
const items = beltComp.sortedItems;
|
||||
@ -244,8 +234,8 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
maxProgress = 1 - globalConfig.itemSpacingOnBelts;
|
||||
} else {
|
||||
// Otherwise our progress depends on the follow up
|
||||
if (followUp) {
|
||||
const spacingOnBelt = followUp.components.Belt.getDistanceToFirstItemCenter();
|
||||
if (beltComp.followUpCache) {
|
||||
const spacingOnBelt = beltComp.followUpCache.components.Belt.getDistanceToFirstItemCenter();
|
||||
maxProgress = Math.min(2, 1 - globalConfig.itemSpacingOnBelts + spacingOnBelt);
|
||||
|
||||
// Useful check, but hurts performance
|
||||
@ -270,8 +260,8 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
progressAndItem[0] = Math.min(maxProgress, progressAndItem[0] + speedMultiplier * beltSpeed);
|
||||
|
||||
if (progressAndItem[0] >= 1.0) {
|
||||
if (followUp) {
|
||||
const followUpBelt = followUp.components.Belt;
|
||||
if (beltComp.followUpCache) {
|
||||
const followUpBelt = beltComp.followUpCache.components.Belt;
|
||||
if (followUpBelt.canAcceptItem()) {
|
||||
followUpBelt.takeItem(progressAndItem[1], progressAndItem[0] - 1.0);
|
||||
items.splice(itemIndex, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user