refactor: script in schema
This commit is contained in:
parent
01e085499a
commit
21fa00da85
|
@ -134,11 +134,22 @@ export default class Component {
|
||||||
$$entity = 0;
|
$$entity = 0;
|
||||||
destroy() {}
|
destroy() {}
|
||||||
initialize(values, defaults) {
|
initialize(values, defaults) {
|
||||||
|
const {properties} = concrete;
|
||||||
for (const key in values) {
|
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) {
|
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})
|
Component.ecs.markChange(this.entity, {[Component.constructor.componentName]: values})
|
||||||
}
|
}
|
||||||
|
@ -146,7 +157,12 @@ export default class Component {
|
||||||
const {properties} = concrete;
|
const {properties} = concrete;
|
||||||
const json = {};
|
const json = {};
|
||||||
for (const key in properties) {
|
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;
|
return json;
|
||||||
}
|
}
|
||||||
|
@ -160,9 +176,15 @@ export default class Component {
|
||||||
return this.toFullJSON();
|
return this.toFullJSON();
|
||||||
}
|
}
|
||||||
update(values) {
|
update(values) {
|
||||||
|
const {properties} = concrete;
|
||||||
for (const key in values) {
|
for (const key in values) {
|
||||||
if (concrete.properties[key]) {
|
if (properties[key]) {
|
||||||
this[`$$${key}`] = values[key];
|
if (properties[key]?.$.set) {
|
||||||
|
properties[key].$.set(Component, this, `$$${key}`, values[key]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this[`$$${key}`] = values[key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this[key] = values[key];
|
this[key] = values[key];
|
||||||
|
@ -186,7 +208,12 @@ export default class Component {
|
||||||
},
|
},
|
||||||
set: function set(value) {
|
set: function set(value) {
|
||||||
if (this[`$$${key}`] !== 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);
|
Component.markChange(this.entity, key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,8 +19,8 @@ export default class Alive extends Component {
|
||||||
this.$$dead = true;
|
this.$$dead = true;
|
||||||
const {Ticking} = ecs.get(this.entity);
|
const {Ticking} = ecs.get(this.entity);
|
||||||
if (Ticking) {
|
if (Ticking) {
|
||||||
this.$$death.locals.entity = ecs.get(this.entity);
|
this.deathScript.locals.entity = ecs.get(this.entity);
|
||||||
const ticker = this.$$death.ticker();
|
const ticker = this.deathScript.ticker();
|
||||||
ecs.addDestructionDependency(this.entity.id, Ticking.add(ticker));
|
ecs.addDestructionDependency(this.entity.id, Ticking.add(ticker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,21 +30,11 @@ export default class Alive extends Component {
|
||||||
if (0 === instance.maxHealth) {
|
if (0 === instance.maxHealth) {
|
||||||
instance.maxHealth = instance.health;
|
instance.maxHealth = instance.health;
|
||||||
}
|
}
|
||||||
// heavy handed...
|
|
||||||
if ('undefined' !== typeof window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.$$death = this.ecs.readScript(
|
|
||||||
instance.deathScript,
|
|
||||||
{
|
|
||||||
ecs: this.ecs,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
static properties = {
|
static properties = {
|
||||||
deathScript: {
|
deathScript: {
|
||||||
defaultValue: '/resources/misc/death-default.js',
|
defaultValue: '/resources/misc/death-default.js',
|
||||||
type: 'string',
|
type: 'script',
|
||||||
},
|
},
|
||||||
health: {type: 'uint32'},
|
health: {type: 'uint32'},
|
||||||
maxHealth: {type: 'uint32'},
|
maxHealth: {type: 'uint32'},
|
||||||
|
|
|
@ -16,10 +16,6 @@ export default class Behaving extends Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
load(instance) {
|
load(instance) {
|
||||||
// heavy handed...
|
|
||||||
if ('undefined' !== typeof window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (const key in instance.routines) {
|
for (const key in instance.routines) {
|
||||||
instance.$$routineInstances[key] = this.ecs.readScript(instance.routines[key]);
|
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() {
|
return class ColliderInstance extends super.instanceFromSchema() {
|
||||||
$$aabb = {x0: Infinity, x1: -Infinity, y0: Infinity, y1: -Infinity};
|
$$aabb = {x0: Infinity, x1: -Infinity, y0: Infinity, y1: -Infinity};
|
||||||
$$aabbs = [];
|
$$aabbs = [];
|
||||||
$$collisionStart;
|
|
||||||
$$collisionEnd;
|
|
||||||
$$intersections = new Map();
|
$$intersections = new Map();
|
||||||
get aabb() {
|
get aabb() {
|
||||||
const {Position: {x: px, y: py}} = ecs.get(this.entity);
|
const {Position: {x: px, y: py}} = ecs.get(this.entity);
|
||||||
|
@ -77,8 +75,8 @@ export default class Collider extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasMatchingIntersection) {
|
if (!hasMatchingIntersection) {
|
||||||
if (this.$$collisionStart) {
|
if (this.collisionStartScript) {
|
||||||
const script = this.$$collisionStart.clone();
|
const script = this.collisionStartScript.clone();
|
||||||
script.locals.entity = thisEntity;
|
script.locals.entity = thisEntity;
|
||||||
script.locals.other = otherEntity;
|
script.locals.other = otherEntity;
|
||||||
script.locals.pair = [body, otherBody];
|
script.locals.pair = [body, otherBody];
|
||||||
|
@ -87,8 +85,8 @@ export default class Collider extends Component {
|
||||||
ecs.addDestructionDependency(otherEntity.id, promise);
|
ecs.addDestructionDependency(otherEntity.id, promise);
|
||||||
ecs.addDestructionDependency(thisEntity.id, promise);
|
ecs.addDestructionDependency(thisEntity.id, promise);
|
||||||
}
|
}
|
||||||
if (other.$$collisionStart) {
|
if (other.collisionStartScript) {
|
||||||
const script = other.$$collisionStart.clone();
|
const script = other.collisionStartScript.clone();
|
||||||
script.locals.entity = otherEntity;
|
script.locals.entity = otherEntity;
|
||||||
script.locals.other = thisEntity;
|
script.locals.other = thisEntity;
|
||||||
script.locals.pair = [otherBody, body];
|
script.locals.pair = [otherBody, body];
|
||||||
|
@ -162,8 +160,8 @@ export default class Collider extends Component {
|
||||||
intersection.entity.bodies[intersection.i],
|
intersection.entity.bodies[intersection.i],
|
||||||
intersection.other.bodies[intersection.j],
|
intersection.other.bodies[intersection.j],
|
||||||
];
|
];
|
||||||
if (this.$$collisionEnd) {
|
if (this.collisionEndScript) {
|
||||||
const script = this.$$collisionEnd.clone();
|
const script = this.collisionEndScript.clone();
|
||||||
script.locals.other = otherEntity;
|
script.locals.other = otherEntity;
|
||||||
script.locals.pair = [body, otherBody];
|
script.locals.pair = [body, otherBody];
|
||||||
const ticker = script.ticker();
|
const ticker = script.ticker();
|
||||||
|
@ -171,8 +169,8 @@ export default class Collider extends Component {
|
||||||
ecs.addDestructionDependency(thisEntity.id, promise);
|
ecs.addDestructionDependency(thisEntity.id, promise);
|
||||||
ecs.addDestructionDependency(otherEntity.id, promise);
|
ecs.addDestructionDependency(otherEntity.id, promise);
|
||||||
}
|
}
|
||||||
if (other.$$collisionEnd) {
|
if (other.collisionEndScript) {
|
||||||
const script = other.$$collisionEnd.clone();
|
const script = other.collisionEndScript.clone();
|
||||||
script.locals.other = thisEntity;
|
script.locals.other = thisEntity;
|
||||||
script.locals.pair = [otherBody, body];
|
script.locals.pair = [otherBody, body];
|
||||||
const ticker = script.ticker();
|
const ticker = script.ticker();
|
||||||
|
@ -268,26 +266,6 @@ export default class Collider extends Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
instance.updateAabbs();
|
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 = {
|
static properties = {
|
||||||
bodies: {
|
bodies: {
|
||||||
|
@ -311,8 +289,8 @@ export default class Collider extends Component {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
collisionEndScript: {type: 'string'},
|
collisionEndScript: {type: 'script'},
|
||||||
collisionStartScript: {type: 'string'},
|
collisionStartScript: {type: 'script'},
|
||||||
isColliding: {defaultValue: 1, type: 'uint8'},
|
isColliding: {defaultValue: 1, type: 'uint8'},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,26 +6,14 @@ export default class Harmful extends Component {
|
||||||
return class HarmfulInstance extends super.instanceFromSchema() {
|
return class HarmfulInstance extends super.instanceFromSchema() {
|
||||||
harm(other) {
|
harm(other) {
|
||||||
const entity = ecs.get(this.entity);
|
const entity = ecs.get(this.entity);
|
||||||
const script = this.$$harm.clone();
|
const script = this.harmScript.clone();
|
||||||
script.locals.other = other;
|
script.locals.other = other;
|
||||||
script.locals.entity = entity;
|
script.locals.entity = entity;
|
||||||
entity.Ticking.add(script.ticker());
|
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 = {
|
static properties = {
|
||||||
harmScript: {type: 'string'},
|
harmScript: {type: 'script'},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,8 @@ export default class Interactive extends Component {
|
||||||
instanceFromSchema() {
|
instanceFromSchema() {
|
||||||
const {ecs} = this;
|
const {ecs} = this;
|
||||||
return class ControlledInstance extends super.instanceFromSchema() {
|
return class ControlledInstance extends super.instanceFromSchema() {
|
||||||
$$interact;
|
|
||||||
interact(initiator) {
|
interact(initiator) {
|
||||||
const script = this.$$interact.clone();
|
const script = this.interactScript.clone();
|
||||||
script.locals.initiator = initiator;
|
script.locals.initiator = initiator;
|
||||||
script.locals.subject = ecs.get(this.entity);
|
script.locals.subject = ecs.get(this.entity);
|
||||||
const {Ticking} = script.locals.subject;
|
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 = {
|
static properties = {
|
||||||
interacting: {type: 'uint8'},
|
interacting: {type: 'uint8'},
|
||||||
interactScript: {type: 'string'},
|
interactScript: {type: 'script'},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,44 +5,26 @@ export default class Plant extends Component {
|
||||||
const {ecs} = this;
|
const {ecs} = this;
|
||||||
const Instance = super.instanceFromSchema();
|
const Instance = super.instanceFromSchema();
|
||||||
return class PlantInstance extends Instance {
|
return class PlantInstance extends Instance {
|
||||||
$$grow;
|
|
||||||
$$mayGrow;
|
|
||||||
grow() {
|
grow() {
|
||||||
const {Ticking} = ecs.get(this.entity);
|
const {Ticking} = ecs.get(this.entity);
|
||||||
Ticking.add(this.$$grow.ticker());
|
Ticking.add(this.growScript.ticker());
|
||||||
}
|
}
|
||||||
mayGrow() {
|
mayGrow() {
|
||||||
return this.$$mayGrow.evaluate();
|
return this.mayGrowScript.evaluate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
load(instance) {
|
load(instance) {
|
||||||
// heavy handed...
|
instance.growScript.locals.plant = instance;
|
||||||
if ('undefined' !== typeof window) {
|
instance.mayGrowScript.locals.plant = instance;
|
||||||
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,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// heavy handed...
|
// heavy handed...
|
||||||
markChange() {}
|
markChange() {}
|
||||||
static properties = {
|
static properties = {
|
||||||
growScript: {type: 'string'},
|
growScript: {type: 'script'},
|
||||||
growth: {type: 'uint16'},
|
growth: {type: 'uint16'},
|
||||||
growthFactor: {defaultValue: 127, type: 'uint8'},
|
growthFactor: {defaultValue: 127, type: 'uint8'},
|
||||||
mayGrowScript: {type: 'string'},
|
mayGrowScript: {type: 'script'},
|
||||||
stage: {type: 'uint8'},
|
stage: {type: 'uint8'},
|
||||||
stages: {
|
stages: {
|
||||||
type: 'array',
|
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 = {};
|
static registered = {};
|
||||||
|
|
||||||
constructor(fn, locals) {
|
constructor(path, fn, locals) {
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
throw new TypeError('Script needs a function');
|
throw new TypeError('Script needs a function');
|
||||||
}
|
}
|
||||||
this.fn = fn;
|
this.fn = fn;
|
||||||
this.iterator = null;
|
this.iterator = null;
|
||||||
this.locals = locals;
|
this.locals = locals;
|
||||||
|
this.path = path;
|
||||||
this.$$ticker = null;
|
this.$$ticker = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
clone() {
|
clone() {
|
||||||
return new this.constructor(this.fn, this.locals);
|
return new this.constructor(this.path, this.fn, this.locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluate() {
|
evaluate() {
|
||||||
|
@ -27,7 +28,7 @@ export default class Script {
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
throw new Error(`no such script: ${path}`);
|
throw new Error(`no such script: ${path}`);
|
||||||
}
|
}
|
||||||
const script = new this(fn, locals);
|
const script = new this(path, fn, locals);
|
||||||
if (import.meta.hot) {
|
if (import.meta.hot) {
|
||||||
const hotRef = new WeakRef(script);
|
const hotRef = new WeakRef(script);
|
||||||
import.meta.hot.accept('./scripts.js', ({default: scripts}) => {
|
import.meta.hot.accept('./scripts.js', ({default: scripts}) => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user