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 { Vector, enumDirection } from "../../core/vector";
|
||||||
import { Math_PI, Math_sin, Math_cos } from "../../core/builtins";
|
import { Math_PI, Math_sin, Math_cos } from "../../core/builtins";
|
||||||
import { globalConfig } from "../../core/config";
|
import { globalConfig } from "../../core/config";
|
||||||
|
import { Entity } from "../entity";
|
||||||
|
|
||||||
export class BeltComponent extends Component {
|
export class BeltComponent extends Component {
|
||||||
static getId() {
|
static getId() {
|
||||||
@ -12,6 +13,7 @@ export class BeltComponent extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static getSchema() {
|
static getSchema() {
|
||||||
|
// The followUpCache field is not serialized.
|
||||||
return {
|
return {
|
||||||
direction: types.string,
|
direction: types.string,
|
||||||
sortedItems: types.array(types.pair(types.float, types.obj(gItemRegistry))),
|
sortedItems: types.array(types.pair(types.float, types.obj(gItemRegistry))),
|
||||||
@ -34,6 +36,9 @@ export class BeltComponent extends Component {
|
|||||||
|
|
||||||
/** @type {Array<[number, BaseItem]>} */
|
/** @type {Array<[number, BaseItem]>} */
|
||||||
this.sortedItems = [];
|
this.sortedItems = [];
|
||||||
|
|
||||||
|
/** @type {Entity} */
|
||||||
|
this.followUpCache = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,14 +13,13 @@ import { MetaBeltBaseBuilding } from "../buildings/belt_base";
|
|||||||
import { defaultBuildingVariant } from "../meta_building";
|
import { defaultBuildingVariant } from "../meta_building";
|
||||||
import { GameRoot } from "../root";
|
import { GameRoot } from "../root";
|
||||||
import { createLogger } from "../../core/logging";
|
import { createLogger } from "../../core/logging";
|
||||||
|
import { Rectangle } from "../../core/rectangle";
|
||||||
|
|
||||||
const BELT_ANIM_COUNT = 6;
|
const BELT_ANIM_COUNT = 6;
|
||||||
const SQRT_2 = Math_sqrt(2);
|
const SQRT_2 = Math_sqrt(2);
|
||||||
|
|
||||||
const logger = createLogger("belt");
|
const logger = createLogger("belt");
|
||||||
|
|
||||||
/** @typedef {Array<{ entity: Entity, followUp: Entity }>} BeltCache */
|
|
||||||
|
|
||||||
export class BeltSystem extends GameSystemWithFilter {
|
export class BeltSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
super(root, [BeltComponent]);
|
super(root, [BeltComponent]);
|
||||||
@ -66,9 +65,8 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
this.root.signals.entityDestroyed.add(this.updateSurroundingBeltPlacement, this);
|
this.root.signals.entityDestroyed.add(this.updateSurroundingBeltPlacement, this);
|
||||||
|
|
||||||
this.cacheNeedsUpdate = true;
|
this.cacheNeedsUpdate = true;
|
||||||
|
/** @type {Rectangle[]} */
|
||||||
/** @type {BeltCache} */
|
this.smallUpdateAreas = [];
|
||||||
this.beltCache = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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) {
|
draw(parameters) {
|
||||||
@ -163,42 +167,28 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
return null;
|
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() {
|
computeBeltCache() {
|
||||||
logger.log("Updating belt cache");
|
logger.log("Updating belt cache");
|
||||||
|
|
||||||
let cache = [];
|
if (this.smallUpdateAreas.length <= 4) {
|
||||||
let visited = new Set();
|
for (let i = 0; i < this.smallUpdateAreas.length; ++i) {
|
||||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
const area = this.smallUpdateAreas[i];
|
||||||
this.computeSingleBeltCache(this.allEntities[i], cache, visited);
|
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(
|
this.smallUpdateAreas = [];
|
||||||
cache.length === this.allEntities.length,
|
|
||||||
"Belt cache mismatch: Has " + cache.length + " entries but should have " + this.allEntities.length
|
|
||||||
);
|
|
||||||
|
|
||||||
this.beltCache = cache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
@ -217,8 +207,8 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
beltSpeed *= 100;
|
beltSpeed *= 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this.beltCache.length; ++i) {
|
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||||
const { entity, followUp } = this.beltCache[i];
|
const entity = this.allEntities[i];
|
||||||
|
|
||||||
const beltComp = entity.components.Belt;
|
const beltComp = entity.components.Belt;
|
||||||
const items = beltComp.sortedItems;
|
const items = beltComp.sortedItems;
|
||||||
@ -244,8 +234,8 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
maxProgress = 1 - globalConfig.itemSpacingOnBelts;
|
maxProgress = 1 - globalConfig.itemSpacingOnBelts;
|
||||||
} else {
|
} else {
|
||||||
// Otherwise our progress depends on the follow up
|
// Otherwise our progress depends on the follow up
|
||||||
if (followUp) {
|
if (beltComp.followUpCache) {
|
||||||
const spacingOnBelt = followUp.components.Belt.getDistanceToFirstItemCenter();
|
const spacingOnBelt = beltComp.followUpCache.components.Belt.getDistanceToFirstItemCenter();
|
||||||
maxProgress = Math.min(2, 1 - globalConfig.itemSpacingOnBelts + spacingOnBelt);
|
maxProgress = Math.min(2, 1 - globalConfig.itemSpacingOnBelts + spacingOnBelt);
|
||||||
|
|
||||||
// Useful check, but hurts performance
|
// Useful check, but hurts performance
|
||||||
@ -270,8 +260,8 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
progressAndItem[0] = Math.min(maxProgress, progressAndItem[0] + speedMultiplier * beltSpeed);
|
progressAndItem[0] = Math.min(maxProgress, progressAndItem[0] + speedMultiplier * beltSpeed);
|
||||||
|
|
||||||
if (progressAndItem[0] >= 1.0) {
|
if (progressAndItem[0] >= 1.0) {
|
||||||
if (followUp) {
|
if (beltComp.followUpCache) {
|
||||||
const followUpBelt = followUp.components.Belt;
|
const followUpBelt = beltComp.followUpCache.components.Belt;
|
||||||
if (followUpBelt.canAcceptItem()) {
|
if (followUpBelt.canAcceptItem()) {
|
||||||
followUpBelt.takeItem(progressAndItem[1], progressAndItem[0] - 1.0);
|
followUpBelt.takeItem(progressAndItem[1], progressAndItem[0] - 1.0);
|
||||||
items.splice(itemIndex, 1);
|
items.splice(itemIndex, 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user