refactor: script in schema

This commit is contained in:
cha0s 2024-10-21 08:58:49 -05:00
parent 01e085499a
commit 21fa00da85
9 changed files with 82 additions and 111 deletions

View File

@ -134,11 +134,22 @@ export default class Component {
$$entity = 0;
destroy() {}
initialize(values, defaults) {
const {properties} = concrete;
for (const key in values) {
this[`$$${key}`] = values[key];
if (properties[key]?.$.set) {
properties[key].$.set(Component, this, `$$${key}`, values[key]);
}
else {
this[`$$${key}`] = values[key];
}
}
for (const key in defaults) {
this[`$$${key}`] = defaults[key];
if (properties[key]?.$.set) {
properties[key].$.set(Component, this, `$$${key}`, defaults[key]);
}
else {
this[`$$${key}`] = defaults[key];
}
}
Component.ecs.markChange(this.entity, {[Component.constructor.componentName]: values})
}
@ -146,7 +157,12 @@ export default class Component {
const {properties} = concrete;
const json = {};
for (const key in properties) {
json[key] = this[key];
if (properties[key]?.$.json) {
json[key] = properties[key].$.json(this[key]);
}
else {
json[key] = this[key];
}
}
return json;
}
@ -160,9 +176,15 @@ export default class Component {
return this.toFullJSON();
}
update(values) {
const {properties} = concrete;
for (const key in values) {
if (concrete.properties[key]) {
this[`$$${key}`] = values[key];
if (properties[key]) {
if (properties[key]?.$.set) {
properties[key].$.set(Component, this, `$$${key}`, values[key]);
}
else {
this[`$$${key}`] = values[key];
}
}
else {
this[key] = values[key];
@ -186,7 +208,12 @@ export default class Component {
},
set: function set(value) {
if (this[`$$${key}`] !== value) {
this[`$$${key}`] = value;
if (concrete.properties[key]?.$.set) {
concrete.properties[key].$.set(Component, this, `$$${key}`, value);
}
else {
this[`$$${key}`] = value;
}
Component.markChange(this.entity, key, value);
}
},

View File

@ -19,8 +19,8 @@ export default class Alive extends Component {
this.$$dead = true;
const {Ticking} = ecs.get(this.entity);
if (Ticking) {
this.$$death.locals.entity = ecs.get(this.entity);
const ticker = this.$$death.ticker();
this.deathScript.locals.entity = ecs.get(this.entity);
const ticker = this.deathScript.ticker();
ecs.addDestructionDependency(this.entity.id, Ticking.add(ticker));
}
}
@ -30,21 +30,11 @@ export default class Alive extends Component {
if (0 === instance.maxHealth) {
instance.maxHealth = instance.health;
}
// heavy handed...
if ('undefined' !== typeof window) {
return;
}
instance.$$death = this.ecs.readScript(
instance.deathScript,
{
ecs: this.ecs,
},
);
}
static properties = {
deathScript: {
defaultValue: '/resources/misc/death-default.js',
type: 'string',
type: 'script',
},
health: {type: 'uint32'},
maxHealth: {type: 'uint32'},

View File

@ -16,10 +16,6 @@ export default class Behaving extends Component {
};
}
load(instance) {
// heavy handed...
if ('undefined' !== typeof window) {
return;
}
for (const key in instance.routines) {
instance.$$routineInstances[key] = this.ecs.readScript(instance.routines[key]);
}

View File

@ -9,8 +9,6 @@ export default class Collider extends Component {
return class ColliderInstance extends super.instanceFromSchema() {
$$aabb = {x0: Infinity, x1: -Infinity, y0: Infinity, y1: -Infinity};
$$aabbs = [];
$$collisionStart;
$$collisionEnd;
$$intersections = new Map();
get aabb() {
const {Position: {x: px, y: py}} = ecs.get(this.entity);
@ -77,8 +75,8 @@ export default class Collider extends Component {
}
}
if (!hasMatchingIntersection) {
if (this.$$collisionStart) {
const script = this.$$collisionStart.clone();
if (this.collisionStartScript) {
const script = this.collisionStartScript.clone();
script.locals.entity = thisEntity;
script.locals.other = otherEntity;
script.locals.pair = [body, otherBody];
@ -87,8 +85,8 @@ export default class Collider extends Component {
ecs.addDestructionDependency(otherEntity.id, promise);
ecs.addDestructionDependency(thisEntity.id, promise);
}
if (other.$$collisionStart) {
const script = other.$$collisionStart.clone();
if (other.collisionStartScript) {
const script = other.collisionStartScript.clone();
script.locals.entity = otherEntity;
script.locals.other = thisEntity;
script.locals.pair = [otherBody, body];
@ -162,8 +160,8 @@ export default class Collider extends Component {
intersection.entity.bodies[intersection.i],
intersection.other.bodies[intersection.j],
];
if (this.$$collisionEnd) {
const script = this.$$collisionEnd.clone();
if (this.collisionEndScript) {
const script = this.collisionEndScript.clone();
script.locals.other = otherEntity;
script.locals.pair = [body, otherBody];
const ticker = script.ticker();
@ -171,8 +169,8 @@ export default class Collider extends Component {
ecs.addDestructionDependency(thisEntity.id, promise);
ecs.addDestructionDependency(otherEntity.id, promise);
}
if (other.$$collisionEnd) {
const script = other.$$collisionEnd.clone();
if (other.collisionEndScript) {
const script = other.collisionEndScript.clone();
script.locals.other = thisEntity;
script.locals.pair = [otherBody, body];
const ticker = script.ticker();
@ -268,26 +266,6 @@ export default class Collider extends Component {
};
}
instance.updateAabbs();
// heavy handed...
if ('undefined' !== typeof window) {
return;
}
if (instance.collisionEndScript) {
instance.$$collisionEnd = this.ecs.readScript(
instance.collisionEndScript,
{
ecs: this.ecs,
},
);
}
if (instance.collisionStartScript) {
instance.$$collisionStart = this.ecs.readScript(
instance.collisionStartScript,
{
ecs: this.ecs,
},
);
}
}
static properties = {
bodies: {
@ -311,8 +289,8 @@ export default class Collider extends Component {
},
},
},
collisionEndScript: {type: 'string'},
collisionStartScript: {type: 'string'},
collisionEndScript: {type: 'script'},
collisionStartScript: {type: 'script'},
isColliding: {defaultValue: 1, type: 'uint8'},
};
}

View File

@ -6,26 +6,14 @@ export default class Harmful extends Component {
return class HarmfulInstance extends super.instanceFromSchema() {
harm(other) {
const entity = ecs.get(this.entity);
const script = this.$$harm.clone();
const script = this.harmScript.clone();
script.locals.other = other;
script.locals.entity = entity;
entity.Ticking.add(script.ticker());
}
}
}
load(instance) {
// heavy handed...
if ('undefined' !== typeof window) {
return;
}
instance.$$harm = this.ecs.readScript(
instance.harmScript,
{
ecs: this.ecs,
},
);
}
static properties = {
harmScript: {type: 'string'},
harmScript: {type: 'script'},
};
}

View File

@ -4,9 +4,8 @@ export default class Interactive extends Component {
instanceFromSchema() {
const {ecs} = this;
return class ControlledInstance extends super.instanceFromSchema() {
$$interact;
interact(initiator) {
const script = this.$$interact.clone();
const script = this.interactScript.clone();
script.locals.initiator = initiator;
script.locals.subject = ecs.get(this.entity);
const {Ticking} = script.locals.subject;
@ -20,20 +19,8 @@ export default class Interactive extends Component {
}
}
}
load(instance) {
// heavy handed...
if ('undefined' !== typeof window) {
return;
}
instance.$$interact = this.ecs.readScript(
instance.interactScript,
{
ecs: this.ecs,
},
);
}
static properties = {
interacting: {type: 'uint8'},
interactScript: {type: 'string'},
interactScript: {type: 'script'},
};
}

View File

@ -5,44 +5,26 @@ export default class Plant extends Component {
const {ecs} = this;
const Instance = super.instanceFromSchema();
return class PlantInstance extends Instance {
$$grow;
$$mayGrow;
grow() {
const {Ticking} = ecs.get(this.entity);
Ticking.add(this.$$grow.ticker());
Ticking.add(this.growScript.ticker());
}
mayGrow() {
return this.$$mayGrow.evaluate();
return this.mayGrowScript.evaluate();
}
};
}
load(instance) {
// heavy handed...
if ('undefined' !== typeof window) {
return;
}
instance.$$grow = this.ecs.readScript(
instance.growScript,
{
ecs: this.ecs,
plant: instance,
},
);
instance.$$mayGrow = this.ecs.readScript(
instance.mayGrowScript,
{
ecs: this.ecs,
plant: instance,
},
);
instance.growScript.locals.plant = instance;
instance.mayGrowScript.locals.plant = instance;
}
// heavy handed...
markChange() {}
static properties = {
growScript: {type: 'string'},
growScript: {type: 'script'},
growth: {type: 'uint16'},
growthFactor: {defaultValue: 127, type: 'uint8'},
mayGrowScript: {type: 'string'},
mayGrowScript: {type: 'script'},
stage: {type: 'uint8'},
stages: {
type: 'array',

View File

@ -0,0 +1,22 @@
import string from './string.js';
export default function () {
const spec = string();
return {
...spec,
json: (value) => {
return value ? value.path : '';
},
set: (Component, receiver, key, value) => {
if (!value) {
return;
}
receiver[key] = Component.ecs.readScript(
value,
{
ecs: Component.ecs,
},
);
},
};
}

View File

@ -4,18 +4,19 @@ export default class Script {
static registered = {};
constructor(fn, locals) {
constructor(path, fn, locals) {
if (!fn) {
throw new TypeError('Script needs a function');
}
this.fn = fn;
this.iterator = null;
this.locals = locals;
this.path = path;
this.$$ticker = null;
}
clone() {
return new this.constructor(this.fn, this.locals);
return new this.constructor(this.path, this.fn, this.locals);
}
evaluate() {
@ -27,7 +28,7 @@ export default class Script {
if (!fn) {
throw new Error(`no such script: ${path}`);
}
const script = new this(fn, locals);
const script = new this(path, fn, locals);
if (import.meta.hot) {
const hotRef = new WeakRef(script);
import.meta.hot.accept('./scripts.js', ({default: scripts}) => {