Classes
Classes are TypeScript's, declared inside the program or at the top of any of the script's files. A method is a function that is handed the instance, so everything on Functions holds for methods too.
program(() => {
class Wave {
static made = 0;
left: number;
constructor(public unit: UnitType, public count: number) { this.left = count; Wave.made++; }
spawn(at: Location) { if (this.left > 0) { createUnit(P2, this.unit, 1, at); this.left--; } }
get done() { return this.left == 0; }
}
class Boss extends Wave {
constructor(unit: UnitType) { super(unit, 1); }
spawn(at: Location) { super.spawn(at); displayText("The boss is here"); }
}
const waves = [new Wave(units.ZergZergling, 12), new Wave(units.ZergHydralisk, 6)];
const boss = new Boss(units.ZergUltralisk);
while (!waves.every((w) => w.done)) {
for (const w of waves) w.spawn(locations.Gate);
sleep(seconds(1));
}
boss.spawn(locations.Gate);
});
Fields with their first values, constructors and constructor(public x: number), methods,
get and set, static, readonly, private, protected and #x, extends with
super, abstract, implements and type parameters all work. A field holds what a
record's does, and also another instance (pos = new Vec(0, 0)). this.members = []
starts an array over.
How an instance is kept#
The compiler keeps an instance one of two ways:
- As its fields' variables, when the build knows which instance each name holds.
Nothing of the class is left in the map: the right method is found by what the instance
is,
x instanceof Bossis answered by the compiler, and the branch that is false is not built. This costs nothing beyond the fields. - By reference, when the program needs it: an array or a variable that may hold
several classes, or none (
let target: Enemy | null); a variable given another instance; an instance in aMap. These instances are rows of one table of 1 023 rows. A field read through none is 0, and a write through none does nothing, where JavaScript would throw. A row that nothing holds any more is given back at the next wait.
class Enemy {
constructor(public hp: number) {}
worth() { return 1; }
}
class Boss extends Enemy {
worth() { return 10; }
}
program(() => {
const foes: Enemy[] = [new Enemy(5), new Boss(50), new Enemy(5)];
let target: Enemy | null = null;
let score = 0;
for (const f of foes) {
score += f.worth();
if (!target || f.hp > target.hp) target = f;
}
print(`${score} ${target?.hp ?? 0}`); // 12 50
});
Two limits:
- A function may give back an instance when every
returngives the same one:return this, so thatv.add(w).scale(2)chains;return new Wave(n, 10); or one it was handed.pick(a, b)that returns one or the other is refused. For that, keep the instances in an array and return the place. - No static blocks. Give a static field its value where it is declared.