quitting working but suspiciously

This commit is contained in:
2025-08-26 19:13:09 -04:00
parent e5f432dc98
commit aeb7d9174b
3 changed files with 56 additions and 25 deletions

View File

@@ -40,6 +40,12 @@ export default () => {
</span>{" "} </span>{" "}
turn turn
</div> </div>
<button
class="button fixed tl m-4 p-1"
onClick={() => table.sendWs({ quit: true })}
>
Quit
</button>
</GameContext.Provider> </GameContext.Provider>
); );
}; };

View File

@@ -11,7 +11,7 @@ import {
} from "solid-js"; } from "solid-js";
import api, { fromWebsocket } from "~/api"; import api, { fromWebsocket } from "~/api";
import { createObservable, createObservableWithInit, cx } from "~/fn"; import { createObservable, createObservableWithInit, cx } from "~/fn";
import { me } from "~/profile"; import { me, mePromise } from "~/profile";
import Game from "./Game"; import Game from "./Game";
import Player from "./Player"; import Player from "./Player";
@@ -37,7 +37,7 @@ export default (props: { tableKey: string }) => {
onCleanup(() => wsPromise.then((ws) => ws.close())); onCleanup(() => wsPromise.then((ws) => ws.close()));
const presenceEvents = wsEvents.filter((evt) => evt.players != null); const presenceEvents = wsEvents.filter((evt) => evt.players != null);
const gameEvents = wsEvents.filter((evt) => evt.view != null); const gameEvents = wsEvents.filter((evt) => evt.view !== undefined);
const players = createObservableWithInit<string[]>( const players = createObservableWithInit<string[]>(
presenceEvents.map((evt) => evt.players!), presenceEvents.map((evt) => evt.players!),
@@ -45,6 +45,15 @@ export default (props: { tableKey: string }) => {
); );
const [ready, setReady] = createSignal(false); const [ready, setReady] = createSignal(false);
mePromise.then(
(me) =>
me &&
wsEvents
.filter((evt) => evt.playersReady !== undefined)
.map((evt) => evt.playersReady?.[me] ?? false)
.onValue(setReady)
);
createEffect(() => sendWs({ ready: ready() })); createEffect(() => sendWs({ ready: ready() }));
const view = createObservable(gameEvents.map((evt) => evt.view)); const view = createObservable(gameEvents.map((evt) => evt.view));

View File

@@ -12,7 +12,7 @@ import { transform } from "./kefir-extension";
export const WsOut = t.Object({ export const WsOut = t.Object({
players: t.Optional(t.Array(t.String())), players: t.Optional(t.Array(t.String())),
playersReady: t.Optional(t.Record(t.String(), t.Boolean())), playersReady: t.Optional(t.Nullable(t.Record(t.String(), t.Boolean()))),
view: t.Optional(t.Any()), view: t.Optional(t.Any()),
}); });
export type TWsOut = typeof WsOut.static; export type TWsOut = typeof WsOut.static;
@@ -31,15 +31,15 @@ type TablePayload<GameConfig, GameState, GameAction> = {
never never
>; >;
readys: TBus<Attributed & { ready: boolean }, never>; readys: TBus<Attributed & { ready: boolean }, any>;
actions: TBus<Attributed & GameAction, never>; actions: TBus<Attributed & GameAction, any>;
quits: TBus<Attributed, never>; quits: TBus<Attributed, any>;
}; };
outputs: { outputs: {
playersPresent: Property<string[], never>; playersPresent: Property<string[], any>;
playersReady: Property<{ [key: string]: boolean }, unknown>; playersReady: Property<{ [key: string]: boolean } | null, any>;
gameConfig: Property<GameConfig | null, never>; gameConfig: Property<GameConfig | null, any>;
gameState: Property<GameState | null, never>; gameState: Property<GameState | null, any>;
}; };
}; };
@@ -60,6 +60,7 @@ export const liveTable = <GameConfig, GameState, GameAction>(key: string) => {
quits: Bus(), quits: Bus(),
}; };
const { connectionChanges, readys, actions, quits } = inputs; const { connectionChanges, readys, actions, quits } = inputs;
quits.log("quits");
// ======= // =======
const playersPresent = connectionChanges const playersPresent = connectionChanges
@@ -78,34 +79,45 @@ export const liveTable = <GameConfig, GameState, GameAction>(key: string) => {
.map((counts) => Object.keys(counts)) .map((counts) => Object.keys(counts))
.toProperty(); .toProperty();
const gameEnds = quits.map((_) => null);
const gameStarts = pool<null, any>();
const playersReady = transform( const playersReady = transform(
{} as { [key: string]: boolean }, null as { [key: string]: boolean } | null,
[ [
playersPresent, playersPresent,
(prev, players: string[]) => (prev, players: string[]) =>
Object.fromEntries( Object.fromEntries(
players.map((p) => [p, prev[p] ?? false]) players.map((p) => [p, prev?.[p] ?? false])
), ),
], ],
[ [
readys, readys,
(prev, evt: { humanKey: string; ready: boolean }) => (prev, evt: { humanKey: string; ready: boolean }) =>
prev[evt.humanKey] != null prev?.[evt.humanKey] != null
? { ...prev, [evt.humanKey]: evt.ready } ? { ...prev, [evt.humanKey]: evt.ready }
: prev, : prev,
],
[gameStarts, () => null],
[
combine([gameEnds], [playersPresent], (_, players) => players),
(_, players: string[]) =>
Object.fromEntries(players.map((p) => [p, false])),
] ]
) )
.toProperty() .toProperty()
.log("playersReady"); .log("playersReady");
const gameStarts = playersReady gameStarts.plug(
.filter( playersReady
(pr) => .filter(
Object.values(pr).length > 0 && (pr) =>
Object.values(pr).every((ready) => ready) Object.values(pr ?? {}).length > 0 &&
) Object.values(pr!).every((ready) => ready)
.map((_) => null) )
.log("gameStarts"); .map((_) => null)
.log("gameStarts")
);
const gameConfigPool = pool< const gameConfigPool = pool<
{ {
@@ -144,8 +156,12 @@ export const liveTable = <GameConfig, GameState, GameAction>(key: string) => {
humanKey: evt.action.humanKey, humanKey: evt.action.humanKey,
}) })
: prev, : prev,
] ],
[quits, () => null]
).toProperty(); ).toProperty();
gameState
.map((state) => JSON.stringify(state).substring(0, 10))
.log("gameState");
const gameIsActive = gameState const gameIsActive = gameState
.map((gs) => gs != null) .map((gs) => gs != null)
@@ -166,9 +182,9 @@ export const liveTable = <GameConfig, GameState, GameAction>(key: string) => {
inputs, inputs,
outputs: { outputs: {
playersPresent, playersPresent,
playersReady, playersReady: playersReady.toProperty(),
gameConfig: gameConfig as Property<unknown, never>, gameConfig: gameConfig as Property<unknown, any>,
gameState: gameState as Property<unknown, never>, gameState: gameState as Property<unknown, any>,
}, },
}; };