diff --git a/client/svelte-client/src/components/NetworkSessionWrapper.svelte b/client/svelte-client/src/components/NetworkSessionWrapper.svelte
index e7db3e3..2e40482 100644
--- a/client/svelte-client/src/components/NetworkSessionWrapper.svelte
+++ b/client/svelte-client/src/components/NetworkSessionWrapper.svelte
@@ -5,31 +5,36 @@
import {SessionState, SessionType} from "../store/model/session";
import CopyToClipboard from "./CopyToClipboard.svelte";
import api from "../api/session";
- import {playerKeyboardInputs} from "../store/input";
+ import type {Readable} from "svelte/store";
+ import type {Input} from "../store/model/input";
+ import {getPlayerKeyboardInputs} from "../store/input";
export let session: NetworkSession;
let joinLink;
let cachedSessionId;
- let relevantKeyboardEvents;
- $: relevantKeyboardEvents = $playerKeyboardInputs.filter(({player}) => player === session.you.nr);
+ let relevantKeyboardEvents: Readable;
+ $: if (!cachedSessionId && session) {
+ }
$: if(!cachedSessionId && session) {
cachedSessionId = session.session_id;
console.log("NetworkSessionWrapper ready, now setting up sessionEvents")
joinLink = api.createJoinLink(session.session_id);
+
+ relevantKeyboardEvents = getPlayerKeyboardInputs(session.you.nr);
}
- $: if(session) {
+ $: if(session && session.state === SessionState.RUNNING) {
switch(session.type) {
case SessionType.HOST:
console.debug("sending host snapshot")
- networkEvents.produce({inputs: relevantKeyboardEvents, session_id: session.session_id, objects: [], player_id: session.you.id, ts: Date.now()})
+ networkEvents.produce({inputs: $relevantKeyboardEvents, session_id: session.session_id, objects: [], player_id: session.you.id, ts: Date.now()})
break;
case SessionType.PEER:
console.debug("sending peer snapshot")
- networkEvents.produce({inputs: relevantKeyboardEvents, session_id: session.session_id, player_id: session.you.id, ts: Date.now()})
+ networkEvents.produce({inputs: $relevantKeyboardEvents, session_id: session.session_id, player_id: session.you.id, ts: Date.now()})
break;
default:
// noop
diff --git a/client/svelte-client/src/store/input.ts b/client/svelte-client/src/store/input.ts
index e025830..67f00da 100644
--- a/client/svelte-client/src/store/input.ts
+++ b/client/svelte-client/src/store/input.ts
@@ -19,8 +19,8 @@ export const playerKeyboardInputs = derived(keysPressed, $keysPressed => {
}).filter(it => !!it);
})
-export const getPlayerKeyboardInputs = (player_nr: number) => readable([], set => {
+export const getPlayerKeyboardInputs = (player_nr: number) => readable([], set => {
return playerKeyboardInputs.subscribe(inputs => {
- return inputs.filter(({player}) => player === player_nr);
+ set(inputs.filter(({player}) => player === player_nr));
})
})
diff --git a/client/svelte-client/src/store/session.ts b/client/svelte-client/src/store/session.ts
index a1c9627..a00b5e1 100644
--- a/client/svelte-client/src/store/session.ts
+++ b/client/svelte-client/src/store/session.ts
@@ -1,13 +1,14 @@
-import {derived, get, readable, writable} from "svelte/store";
+import {derived, get, Readable, readable, Unsubscriber, writable} from "svelte/store";
import {keysPressed} from "./io";
import api from "../api/session";
import session from "../api/session";
-import type {LocalSession, Message, NetworkSession, Session, SessionSnapshot} from "./model/session";
+import type {Heartbeat, LocalSession, Message, NetworkSession, Session, SessionSnapshot} from "./model/session";
import {isLocalSession, isNetworkSession, MessageType, SessionState, SessionType} from "./model/session";
import type {NetworkStore} from "./network";
import type {GameEventWrapper, InputEventPayload, InputEventWrapper, SessionEventPayload} from "./model/event";
import {isInputEvent} from "./model/event";
import {getPlayerKeyboardInputs, playerKeyboardInputs} from "./input";
+import type {Subscriber} from "svelte/types/runtime/store";
const sessionStore = writable(null)
@@ -16,6 +17,7 @@ function createNetworkEvents() {
const websocket = writable(null);
const sessionId = writable(null);
+ const playerId = writable(null);
const lastSnapshot = writable(null);
const unsubscribeSession = sessionStore.subscribe(session => {
@@ -26,6 +28,7 @@ function createNetworkEvents() {
return;
}
sessionId.set(session.session_id);
+ playerId.set(session.you.id);
console.log("creating ws to receive/send websocket events for session: ", JSON.stringify(session))
api.createEventWebsocket(session).then(ws => {
console.log("ws successfully established: ", ws)
@@ -54,15 +57,13 @@ function createNetworkEvents() {
const interval = setInterval(() => {
const last = get(lastSnapshot);
- if (last === null) {
- return;
- }
const now = Date.now();
- if (now - last.ts < 1_000) {
+ if (last && now - last.ts < 1_000) {
return
}
console.debug("sending heartbeat")
- sendMessage({msg_type: MessageType.Heartbeat, payload: {session_id: last.session_id, player_id: last.player_id, ts: now}});
+ const heartbeat: Message = {msg_type: MessageType.Heartbeat, payload: {session_id: get(sessionId), player_id: get(playerId), ts: now}};
+ sendMessage(heartbeat);
}, 1_000)
function sendMessage(message: Message) {
@@ -80,14 +81,26 @@ function createNetworkEvents() {
sendMessage({msg_type: MessageType.Snapshot, payload: snapshot});
}
- // TODO: Handle unsubscribe
+ const customSubscribe = (run: Subscriber, invalidate): Unsubscriber => {
+ const unsubscribe = subscribe(run, invalidate);
+ return () => {
+ unsubscribeSession();
+ clearInterval(interval);
+ unsubscribe();
+ }
+ }
+
return {
- subscribe,
+ subscribe: customSubscribe,
produce
}
}
-export const networkEvents = createNetworkEvents();
+export type NetworkEventStore = Readable & {
+ produce: (snapshot: SessionSnapshot) => void
+}
+
+export const networkEvents: NetworkEventStore = createNetworkEvents();
export const networkSessionStateEvents = derived(networkEvents, $sessionEvents => {
const sessionEvents = $sessionEvents.filter(({topic}) => topic === 'session').map(({event}) => event);