mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-04-10 12:39:53 +00:00
ecs: temp vars
This commit is contained in:
parent
01056c66a8
commit
bc7cd6f1a3
@ -66,16 +66,26 @@ export class Bin {
|
||||
return result;
|
||||
}
|
||||
fits(b: Box) {
|
||||
if (!boxesIntersect(this.binbounds, b)) return false;
|
||||
if (this.getBoxes(b, 1).length > 0) return false;
|
||||
if (!boxesIntersect(this.binbounds, b)) {
|
||||
if (debug) console.log('out of bounds!', b.left,b.top,b.right,b.bottom);
|
||||
return false;
|
||||
}
|
||||
if (this.getBoxes(b, 1).length > 0) {
|
||||
if (debug) console.log('intersect!', b.left,b.top,b.right,b.bottom);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bestFit(b: Box) : Box | null {
|
||||
bestFit(b: BoxConstraints) : Box | null {
|
||||
let bestscore = 0;
|
||||
let best = null;
|
||||
for (let f of this.free) {
|
||||
let dx = (f.right - f.left) - (b.right - b.left);
|
||||
let dy = (f.bottom - f.top) - (b.bottom - b.top);
|
||||
if (b.left != null && b.left < f.left) continue;
|
||||
if (b.left != null && b.left + b.width > f.right) continue;
|
||||
if (b.top != null && b.top < f.top) continue;
|
||||
if (b.top != null && b.top + b.height > f.bottom) continue;
|
||||
let dx = (f.right - f.left) - b.width;
|
||||
let dy = (f.bottom - f.top) - b.height;
|
||||
if (dx >= 0 && dy >= 0) {
|
||||
let score = 1 / (1 + dx + dy);
|
||||
if (score > bestscore) {
|
||||
@ -85,8 +95,26 @@ export class Bin {
|
||||
}
|
||||
return best;
|
||||
}
|
||||
anyFit(b: BoxConstraints) : Box | null {
|
||||
let bestscore = 0;
|
||||
let best = null;
|
||||
for (let f of this.free) {
|
||||
let box : Box = {
|
||||
left: b.left != null ? b.left : f.left,
|
||||
right: f.left + b.width,
|
||||
top: b.top != null ? b.top : f.top,
|
||||
bottom: f.top + b.height };
|
||||
if (this.fits(box)) {
|
||||
let score = 1 / (1 + box.left + box.top);
|
||||
if (score > bestscore) {
|
||||
best = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
add(b: PlacedBox) {
|
||||
if (debug) console.log('added',b.left,b.top,b.right,b.bottom);
|
||||
if (debug) console.log('added', b.left,b.top,b.right,b.bottom);
|
||||
if (!this.fits(b)) {
|
||||
//console.log('collided with', this.getBoxes(b, 1));
|
||||
throw new Error(`bad fit ${b.left} ${b.top} ${b.right} ${b.bottom}`)
|
||||
@ -141,19 +169,29 @@ export class Packer {
|
||||
return true;
|
||||
}
|
||||
bestPlacement(b: BoxConstraints) : PlacedBox | null {
|
||||
let left = b.left != null ? b.left : 0;
|
||||
let top = b.top != null ? b.top : 0;
|
||||
let right = left + b.width;
|
||||
let bottom = top + b.height;
|
||||
for (let bin of this.bins) {
|
||||
let place : BoxPlacement = BoxPlacement.TopLeft; //TODO
|
||||
let box = { left, top, right, bottom };
|
||||
let parent = bin.bestFit(box);
|
||||
let parent = bin.bestFit(b);
|
||||
if (!parent) {
|
||||
parent = bin.anyFit(b);
|
||||
if (debug) console.log('anyfit',parent?.left,parent?.top);
|
||||
}
|
||||
if (parent) {
|
||||
box.left = parent.left;
|
||||
box.top = parent.top;
|
||||
box.right = parent.left + b.width;
|
||||
box.bottom = parent.top + b.height;
|
||||
let box = {
|
||||
left: parent.left,
|
||||
top: parent.top,
|
||||
right: parent.left + b.width,
|
||||
bottom: parent.top + b.height
|
||||
};
|
||||
if (b.left != null) {
|
||||
box.left = b.left;
|
||||
box.right = b.left + b.width;
|
||||
}
|
||||
if (b.top != null) {
|
||||
box.top = b.top;
|
||||
box.bottom = b.top + b.height;
|
||||
}
|
||||
if (debug) console.log('place',box.left,box.top,box.right,box.bottom,parent?.left,parent?.top);
|
||||
/*
|
||||
if (place == BoxPlacement.BottomLeft || place == BoxPlacement.BottomRight) {
|
||||
box.top = parent.bottom - (box.bottom - box.top);
|
||||
@ -165,6 +203,7 @@ export class Packer {
|
||||
return { parent, place, bin, ...box };
|
||||
}
|
||||
}
|
||||
if (debug) console.log('cannot place!', b.left,b.top,b.width,b.height);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ how to avoid cycle crossing for critical code and data?
|
||||
*/
|
||||
|
||||
import { SourceLocated, SourceLocation } from "../workertypes";
|
||||
import { Bin, Packer } from "./binpack";
|
||||
|
||||
export class ECSError extends Error {
|
||||
$loc: SourceLocation;
|
||||
@ -1150,6 +1151,29 @@ export class EntityScope implements SourceLocated {
|
||||
this.resources.add(symbol);
|
||||
return symbol;
|
||||
}
|
||||
allocateTempVars() {
|
||||
let pack = new Packer();
|
||||
let maxTempBytes = 128; // TODO
|
||||
pack.bins.push(new Bin({ left:0, top:0, bottom: this.eventSeq+1, right: maxTempBytes }));
|
||||
for (let sys of this.systems) {
|
||||
let stats = this.getSystemStats(sys);
|
||||
if (sys.tempbytes && stats.tempstartseq && stats.tempendseq) {
|
||||
let v = {
|
||||
sys,
|
||||
top: stats.tempstartseq,
|
||||
bottom: stats.tempendseq+1,
|
||||
width: sys.tempbytes,
|
||||
height: stats.tempendseq - stats.tempstartseq + 1,
|
||||
};
|
||||
pack.boxes.push(v);
|
||||
}
|
||||
}
|
||||
if (!pack.pack()) console.log('cannot pack temporary local vars'); // TODO
|
||||
console.log('tempvars', pack);
|
||||
for (let b of pack.boxes) {
|
||||
console.log((b as any).sys.name, b.box);
|
||||
}
|
||||
}
|
||||
analyzeEntities() {
|
||||
this.buildSegments();
|
||||
this.allocateSegment(this.bss, false);
|
||||
@ -1173,6 +1197,7 @@ export class EntityScope implements SourceLocated {
|
||||
this.code.addCodeFragment(code);
|
||||
}
|
||||
//this.showStats();
|
||||
this.allocateTempVars();
|
||||
}
|
||||
showStats() {
|
||||
for (let sys of this.systems) {
|
||||
|
@ -2,7 +2,7 @@ import assert from "assert";
|
||||
import { execFileSync, spawnSync } from "child_process";
|
||||
import { readdirSync, readFileSync, writeFileSync } from "fs";
|
||||
import { describe } from "mocha";
|
||||
import { Bin, Packer } from "../common/ecs/binpack";
|
||||
import { Bin, BoxConstraints, Packer } from "../common/ecs/binpack";
|
||||
import { ECSCompiler } from "../common/ecs/compiler";
|
||||
import { Dialect_CA65, EntityManager, SourceFileExport } from "../common/ecs/ecs";
|
||||
|
||||
@ -396,18 +396,37 @@ describe('Compiler', function() {
|
||||
});
|
||||
});
|
||||
|
||||
function testPack(bins: Bin[], boxes: BoxConstraints[]) {
|
||||
let packer = new Packer();
|
||||
for (let bin of bins) packer.bins.push(bin);
|
||||
for (let bc of boxes) packer.boxes.push(bc);
|
||||
if (!packer.pack()) throw new Error('cannot pack')
|
||||
console.log(packer.boxes);
|
||||
console.log(packer.bins[0].free)
|
||||
}
|
||||
|
||||
describe('Box Packer', function() {
|
||||
it('Should pack boxes', function() {
|
||||
let packer = new Packer();
|
||||
let bin1 = new Bin({ left:0, top:0, right:10, bottom:10 });
|
||||
packer.bins.push(bin1);
|
||||
packer.boxes.push({ width: 5, height: 5 });
|
||||
packer.boxes.push({ width: 5, height: 5 });
|
||||
packer.boxes.push({ width: 5, height: 5 });
|
||||
packer.boxes.push({ width: 5, height: 5 });
|
||||
if (!packer.pack()) throw new Error('cannot pack')
|
||||
console.log(packer.boxes);
|
||||
console.log(packer.bins[0].free)
|
||||
testPack(
|
||||
[
|
||||
new Bin({ left:0, top:0, right:10, bottom:10 })
|
||||
], [
|
||||
{ width: 5, height: 5 },
|
||||
{ width: 5, height: 5 },
|
||||
{ width: 5, height: 5 },
|
||||
{ width: 5, height: 5 },
|
||||
]
|
||||
);
|
||||
});
|
||||
it('Should pack temp vars', function() {
|
||||
testPack(
|
||||
[
|
||||
new Bin({ left:0, top:0, right:10, bottom:10 })
|
||||
], [
|
||||
{ width: 3, height: 7, top: 0 },
|
||||
{ width: 3, height: 7, top: 1 },
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user