feat: universe time
This commit is contained in:
parent
9de78bb35e
commit
883d231e26
|
@ -32,6 +32,7 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@avocado/resource": "^3.0.0",
|
||||
"@avocado/s13n": "^3.0.0",
|
||||
"@avocado/timing": "^3.0.0",
|
||||
"@avocado/traits": "^3.0.0",
|
||||
"@flecks/core": "^1.4.1",
|
||||
|
|
|
@ -6,6 +6,7 @@ export * from './state';
|
|||
|
||||
export default {
|
||||
[Hooks]: {
|
||||
'@avocado/resource.resources': Flecks.provide(require.context('./resources', false, /\.js$/)),
|
||||
'@avocado/traits.traits': Flecks.provide(require.context('./traits', false, /\.js$/)),
|
||||
'@flecks/core.config': () => ({
|
||||
resource: 'resource',
|
||||
|
|
10
packages/universe/src/packets/universe-update-time.js
Normal file
10
packages/universe/src/packets/universe-update-time.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
export default (flecks) => {
|
||||
const {Packet} = flecks.fleck('@flecks/socket');
|
||||
return class UniverseUpdateTime extends Packet {
|
||||
|
||||
static get data() {
|
||||
return 'float32';
|
||||
}
|
||||
|
||||
};
|
||||
};
|
70
packages/universe/src/resources/universe.js
Normal file
70
packages/universe/src/resources/universe.js
Normal file
|
@ -0,0 +1,70 @@
|
|||
import {JsonResource} from '@avocado/resource';
|
||||
import {Synchronized} from '@avocado/s13n';
|
||||
import {Ticker} from '@avocado/timing';
|
||||
import {compose, EventEmitter} from '@flecks/core';
|
||||
|
||||
const UPDATE_INTERVAL = 0.25;
|
||||
|
||||
export default (flecks) => {
|
||||
const decorate = compose(
|
||||
EventEmitter,
|
||||
Synchronized(flecks),
|
||||
);
|
||||
return class Universe extends decorate(JsonResource) {
|
||||
|
||||
isUpdating = false;
|
||||
|
||||
online = [];
|
||||
|
||||
time = 0;
|
||||
|
||||
updater = new Ticker(UPDATE_INTERVAL);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.updater.on('tick', this.update, this);
|
||||
}
|
||||
|
||||
acceptPacket(packet) {
|
||||
if ('UniverseUpdateTime' === packet.constructor.type) {
|
||||
this.time = packet.data;
|
||||
}
|
||||
}
|
||||
|
||||
async load(json) {
|
||||
await super.load(json);
|
||||
if (json.online) {
|
||||
this.online = json.online;
|
||||
}
|
||||
if (json.time) {
|
||||
this.time = json.time;
|
||||
}
|
||||
}
|
||||
|
||||
packetsFor() {
|
||||
const packets = [];
|
||||
if (this.isUpdating) {
|
||||
packets.push(['UniverseUpdateTime', this.time]);
|
||||
this.isUpdating = false;
|
||||
}
|
||||
return packets;
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
this.time += elapsed;
|
||||
this.updater.tick(elapsed);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
online: this.online,
|
||||
time: this.time,
|
||||
};
|
||||
}
|
||||
|
||||
update() {
|
||||
this.isUpdating = true;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
|
@ -61,6 +61,7 @@ export default class Universe {
|
|||
entity.startInformingAbout(room);
|
||||
}
|
||||
};
|
||||
entity.startInformingAbout(this.$$universe);
|
||||
entity.on('currentRoomChanged', onCurrentRoomChanged);
|
||||
player.once('removed', () => {
|
||||
entity.off('currentRoomChanged', onCurrentRoomChanged);
|
||||
|
@ -130,6 +131,7 @@ export default class Universe {
|
|||
await mkdir(path);
|
||||
}
|
||||
const universe = new this(flecks, path);
|
||||
await universe.loadOrCreateResource();
|
||||
const {Room} = flecks.get('$avocado/resource.resources');
|
||||
await Promise.all(
|
||||
(await pglob('**/*.room.json', {cwd: path}))
|
||||
|
@ -166,10 +168,32 @@ export default class Universe {
|
|||
}
|
||||
}
|
||||
|
||||
async loadOrCreateResource() {
|
||||
const uri = join(this.$$root, 'index.universe.json');
|
||||
try {
|
||||
const stats = await stat(uri);
|
||||
if (!stats.isFile()) {
|
||||
throw new Error(`universe resource ${uri} is not a file`);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
if ('ENOENT' !== error.code) {
|
||||
throw error;
|
||||
}
|
||||
debug("resource doesn't exist, creating...");
|
||||
await writeFile(uri, '{}');
|
||||
}
|
||||
const {Universe} = this.$$flecks.get('$avocado/resource.resources');
|
||||
const buffer = await readFile(uri);
|
||||
const json = JSON.parse(buffer.toString());
|
||||
this.$$universe = await Universe.load(json);
|
||||
}
|
||||
|
||||
removePlayer(player) {
|
||||
const {entity} = player;
|
||||
const room = this.room(entity.currentRoom);
|
||||
entity.stopInformingAbout(room);
|
||||
entity.stopInformingAbout(this.$$universe);
|
||||
room.removeEntity(entity);
|
||||
const index = this.$$players.indexOf(player);
|
||||
if (-1 !== index) {
|
||||
|
@ -215,6 +239,7 @@ export default class Universe {
|
|||
for (let i = 0; i < this.$$roomsFlat.length; i++) {
|
||||
this.$$roomsFlat[i].tick(elapsed);
|
||||
}
|
||||
this.$$universe.tick(elapsed);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user