Skip to content

Commit

Permalink
fix(state): emit load event when world loads, not just after creation
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Jun 4, 2021
1 parent 844663d commit 5191466
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 20 deletions.
3 changes: 3 additions & 0 deletions src/error/ActorRoomError.ts
@@ -0,0 +1,3 @@
import { BaseError } from 'noicejs';

export class ActorRoomError extends BaseError {}
16 changes: 12 additions & 4 deletions src/service/actor/PlayerActor.ts
Expand Up @@ -24,7 +24,7 @@ import {
import { Counter } from '../counter';
import { EventBus, LineEvent } from '../event';
import { LocaleContext, LocaleService } from '../locale';
import { StateOutputEvent } from '../state/events';
import { StateJoinEvent, StateOutputEvent } from '../state/events';
import { TokenizerService } from '../tokenizer';

export interface PlayerActorOptions extends BaseOptions {
Expand Down Expand Up @@ -81,9 +81,7 @@ export class PlayerActorService implements ActorService {
catchAndLog(this.onInput(event), this.logger, 'error during render output');
}, this);
this.event.on(EVENT_STATE_JOIN, (event) => {
if (this.pid === event.pid) {
this.actor = event.actor;
}
this.onJoin(event);
}, this);
this.event.on(EVENT_STATE_LOAD, (event) => {
this.event.emit(EVENT_ACTOR_JOIN, {
Expand Down Expand Up @@ -111,6 +109,16 @@ export class PlayerActorService implements ActorService {
return this.history[this.history.length - 1];
}

public onJoin(event: StateJoinEvent): void {
if (this.pid === event.pid) {
this.logger.debug({ event }, 'registering own actor');
this.actor = event.actor;
this.room = event.room;
} else {
this.logger.debug({ event }, 'actor joined state');
}
}

public async onInput(event: LineEvent): Promise<void> {
this.logger.debug({ event }, 'tokenizing input');

Expand Down
51 changes: 35 additions & 16 deletions src/service/state/TurnState.ts
Expand Up @@ -2,9 +2,11 @@ import { constructorName, doesExist, isNil, mustExist, mustFind, NotFoundError,
import { BaseOptions, Container, Inject, Logger } from 'noicejs';

import { CreateParams, StateService, StepResult } from '.';
import { ActorRoomError } from '../../error/ActorRoomError';
import { NotInitializedError } from '../../error/NotInitializedError';
import { Command } from '../../model/Command';
import { Actor, ActorType, ACTOR_TYPE, isActor } from '../../model/entity/Actor';
import { Actor, ACTOR_TYPE, ActorType, isActor } from '../../model/entity/Actor';
import { isRoom } from '../../model/entity/Room';
import { DataFile } from '../../model/file/Data';
import { WorldState } from '../../model/world/State';
import { WorldTemplate } from '../../model/world/Template';
Expand All @@ -27,6 +29,7 @@ import {
EVENT_STATE_LOAD,
EVENT_STATE_OUTPUT,
EVENT_STATE_ROOM,
EVENT_STATE_STEP,
META_CREATE,
META_DEBUG,
META_GRAPH,
Expand All @@ -40,7 +43,7 @@ import {
VERB_PREFIX,
VERB_WAIT,
} from '../../util/constants';
import { getVerbScripts, searchState } from '../../util/state';
import { findRoom, getVerbScripts, searchState } from '../../util/state';
import { debugState, graphState } from '../../util/state/debug';
import { StateEntityGenerator } from '../../util/state/EntityGenerator';
import { StateEntityTransfer } from '../../util/state/EntityTransfer';
Expand Down Expand Up @@ -206,9 +209,20 @@ export class LocalStateService implements StateService {
type: ACTOR_TYPE,
});
if (isActor(existingActor)) {
const [room] = findRoom(state, {
meta: {
id: existingActor.meta.id,
},
});

if (!isRoom(room)) {
throw new ActorRoomError('room cannot be found for existing actor');
}

this.event.emit(EVENT_STATE_JOIN, {
actor: existingActor,
pid: event.pid,
room,
});
return;
}
Expand All @@ -228,11 +242,6 @@ export class LocalStateService implements StateService {
const actor = await mustExist(this.generator).createActor(actorTemplate, ActorType.PLAYER);
actor.meta.id = event.pid;

this.event.emit(EVENT_STATE_JOIN, {
actor,
pid: event.pid,
});

const room = mustFind(state.rooms, (it) => it.meta.id === state.start.room);
room.actors.push(actor);

Expand All @@ -245,6 +254,12 @@ export class LocalStateService implements StateService {
actor,
room,
});

this.event.emit(EVENT_STATE_JOIN, {
actor,
pid: event.pid,
room,
});
}

public async onWorld(world: WorldTemplate): Promise<void> {
Expand All @@ -263,10 +278,6 @@ export class LocalStateService implements StateService {
command,
}, 'handling command event');

if (doesExist(actor)) {
this.commands.push(actor, command);
}

// handle meta commands
switch (command.verb) {
case META_CREATE:
Expand Down Expand Up @@ -294,14 +305,16 @@ export class LocalStateService implements StateService {
await this.doWorlds();
break;
default: {
await this.doStep(actor);
await this.doStep(event);
}
}
}

public async doStep(actor: Optional<Actor>): Promise<void> {
public async doStep(event: ActorCommandEvent): Promise<void> {
const { actor, command } = event;

// if there is no world state, there won't be an actor, but this error is more informative
if (isNil(this.state)) {
if (isNil(actor) || isNil(this.state)) {
this.event.emit(EVENT_STATE_OUTPUT, {
line: 'meta.step.none',
step: {
Expand All @@ -313,14 +326,16 @@ export class LocalStateService implements StateService {
return;
}

this.commands.push(actor, command);

// TODO: proper wait, don't assume player goes last
if (isNil(actor) || actor.actorType !== ActorType.PLAYER) {
if (actor.actorType !== ActorType.PLAYER) {
return;
}

// step world
const result = await this.step();
this.event.emit('state-step', result);
this.event.emit(EVENT_STATE_STEP, result);

}

Expand Down Expand Up @@ -479,6 +494,10 @@ export class LocalStateService implements StateService {
step: state.step,
volume: ShowVolume.WORLD,
});
this.event.emit(EVENT_STATE_LOAD, {
state: state.meta.name,
world: state.meta.template,
});
}

public async doQuit(): Promise<void> {
Expand Down
1 change: 1 addition & 0 deletions src/service/state/events.ts
Expand Up @@ -7,6 +7,7 @@ import { LocaleContext } from '../locale';
export interface StateJoinEvent {
actor: Actor;
pid: string;
room: Room;
}

export interface StateRoomEvent {
Expand Down

0 comments on commit 5191466

Please sign in to comment.