refactor: script in schema
This commit is contained in:
parent
01e085499a
commit
21fa00da85
|
@ -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);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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'},
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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'},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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'},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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'},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
22
app/ecs/schema-types/script.js
Normal file
22
app/ecs/schema-types/script.js
Normal 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,
|
||||
},
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
|
@ -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}) => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user