Migrating followStates and followRoles from a const object to a type restricted to only the string values allowed.

This allows for more secure code (compilation checks) and simpler code too (we can pass strings instead of const values)
This commit is contained in:
David Négrier 2021-12-24 15:49:25 +01:00
parent 840f8626ad
commit d37165219c
5 changed files with 46 additions and 69 deletions

View file

@ -42,7 +42,7 @@
import AudioManager from "./AudioManager/AudioManager.svelte"; import AudioManager from "./AudioManager/AudioManager.svelte";
import { showReportScreenStore, userReportEmpty } from "../Stores/ShowReportScreenStore"; import { showReportScreenStore, userReportEmpty } from "../Stores/ShowReportScreenStore";
import ReportMenu from "./ReportMenu/ReportMenu.svelte"; import ReportMenu from "./ReportMenu/ReportMenu.svelte";
import { followStateStore, followStates } from "../Stores/FollowStore"; import { followStateStore } from "../Stores/FollowStore";
import { peerStore } from "../Stores/PeerStore"; import { peerStore } from "../Stores/PeerStore";
import FollowMenu from "./FollowMenu/FollowMenu.svelte"; import FollowMenu from "./FollowMenu/FollowMenu.svelte";
@ -104,7 +104,7 @@
<ReportMenu /> <ReportMenu />
</div> </div>
{/if} {/if}
{#if $followStateStore !== followStates.off || $peerStore.size > 0} {#if $followStateStore !== "off" || $peerStore.size > 0}
<div> <div>
<FollowMenu /> <FollowMenu />
</div> </div>

View file

@ -2,19 +2,10 @@
vim: ft=typescript vim: ft=typescript
--> -->
<script lang="ts"> <script lang="ts">
import { onDestroy, onMount } from "svelte";
import type { Unsubscriber } from "svelte/store";
import { get } from "svelte/store";
import { gameManager } from "../../Phaser/Game/GameManager"; import { gameManager } from "../../Phaser/Game/GameManager";
import followImg from "../images/follow.svg"; import followImg from "../images/follow.svg";
import { import { followStateStore, followRoleStore, followUsersStore } from "../../Stores/FollowStore";
followStateStore,
followRoleStore,
followUsersStore,
followRoles,
followStates,
} from "../../Stores/FollowStore";
const gameScene = gameManager.getCurrentGameScene(); const gameScene = gameManager.getCurrentGameScene();
@ -24,8 +15,8 @@ vim: ft=typescript
function sendFollowRequest() { function sendFollowRequest() {
gameScene.connection?.emitFollowRequest(); gameScene.connection?.emitFollowRequest();
followRoleStore.set(followRoles.leader); followRoleStore.set("leader");
followStateStore.set(followStates.active); followStateStore.set("active");
} }
function acceptFollowRequest() { function acceptFollowRequest() {
@ -34,7 +25,7 @@ vim: ft=typescript
} }
function abortEnding() { function abortEnding() {
followStateStore.set(followStates.active); followStateStore.set("active");
} }
function reset() { function reset() {
@ -51,9 +42,9 @@ vim: ft=typescript
<svelte:window on:keydown={onKeyDown} /> <svelte:window on:keydown={onKeyDown} />
{#if $followStateStore === followStates.requesting} {#if $followStateStore === "requesting"}
<div class="interact-menu nes-container is-rounded"> <div class="interact-menu nes-container is-rounded">
{#if $followRoleStore === followRoles.follower} {#if $followRoleStore === "follower"}
<section class="interact-menu-title"> <section class="interact-menu-title">
<h2>Do you want to follow {name($followUsersStore[0])}?</h2> <h2>Do you want to follow {name($followUsersStore[0])}?</h2>
</section> </section>
@ -63,7 +54,7 @@ vim: ft=typescript
> >
<button type="button" class="nes-btn is-error" on:click|preventDefault={reset}>No</button> <button type="button" class="nes-btn is-error" on:click|preventDefault={reset}>No</button>
</section> </section>
{:else if $followRoleStore === followRoles.leader} {:else if $followRoleStore === "leader"}
<section class="interact-menu-question"> <section class="interact-menu-question">
<p>Should never be displayed</p> <p>Should never be displayed</p>
</section> </section>
@ -71,16 +62,16 @@ vim: ft=typescript
</div> </div>
{/if} {/if}
{#if $followStateStore === followStates.ending} {#if $followStateStore === "ending"}
<div class="interact-menu nes-container is-rounded"> <div class="interact-menu nes-container is-rounded">
<section class="interact-menu-title"> <section class="interact-menu-title">
<h2>Interaction</h2> <h2>Interaction</h2>
</section> </section>
{#if $followRoleStore === followRoles.follower} {#if $followRoleStore === "follower"}
<section class="interact-menu-question"> <section class="interact-menu-question">
<p>Do you want to stop following {name($followUsersStore[0])}?</p> <p>Do you want to stop following {name($followUsersStore[0])}?</p>
</section> </section>
{:else if $followRoleStore === followRoles.leader} {:else if $followRoleStore === "leader"}
<section class="interact-menu-question"> <section class="interact-menu-question">
<p>Do you want to stop leading the way?</p> <p>Do you want to stop leading the way?</p>
</section> </section>
@ -92,10 +83,10 @@ vim: ft=typescript
</div> </div>
{/if} {/if}
{#if $followStateStore === followStates.active || $followStateStore === followStates.ending} {#if $followStateStore === "active" || $followStateStore === "ending"}
<div class="interact-status nes-container is-rounded"> <div class="interact-status nes-container is-rounded">
<section class="interact-status"> <section class="interact-status">
{#if $followRoleStore === followRoles.follower} {#if $followRoleStore === "follower"}
<p>Following {name($followUsersStore[0])}</p> <p>Following {name($followUsersStore[0])}</p>
{:else if $followUsersStore.length === 0} {:else if $followUsersStore.length === 0}
<p>Waiting for followers' confirmation</p> <p>Waiting for followers' confirmation</p>
@ -105,15 +96,16 @@ vim: ft=typescript
<p>{name($followUsersStore[0])} and {name($followUsersStore[1])} are following you</p> <p>{name($followUsersStore[0])} and {name($followUsersStore[1])} are following you</p>
{:else} {:else}
<p> <p>
{$followUsersStore.slice(0, -1).map(name).join(", ")} and {name($followUsersStore[$followUsersStore.length - 1])} are following {$followUsersStore.slice(0, -1).map(name).join(", ")} and {name(
you $followUsersStore[$followUsersStore.length - 1]
)} are following you
</p> </p>
{/if} {/if}
</section> </section>
</div> </div>
{/if} {/if}
{#if $followStateStore === followStates.off} {#if $followStateStore === "off"}
<button <button
type="button" type="button"
class="nes-btn is-primary follow-menu-button" class="nes-btn is-primary follow-menu-button"
@ -122,8 +114,8 @@ vim: ft=typescript
> >
{/if} {/if}
{#if $followStateStore === followStates.active || $followStateStore === followStates.ending} {#if $followStateStore === "active" || $followStateStore === "ending"}
{#if $followRoleStore === followRoles.follower} {#if $followRoleStore === "follower"}
<button <button
type="button" type="button"
class="nes-btn is-error follow-menu-button" class="nes-btn is-error follow-menu-button"

View file

@ -64,7 +64,7 @@ import { connectionManager } from "./ConnectionManager";
import { emoteEventStream } from "./EmoteEventStream"; import { emoteEventStream } from "./EmoteEventStream";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { warningContainerStore } from "../Stores/MenuStore"; import { warningContainerStore } from "../Stores/MenuStore";
import { followStateStore, followRoleStore, followUsersStore, followRoles, followStates } from "../Stores/FollowStore"; import { followStateStore, followRoleStore, followUsersStore } from "../Stores/FollowStore";
import { localUserStore } from "./LocalUserStore"; import { localUserStore } from "./LocalUserStore";
const manualPingDelay = 20000; const manualPingDelay = 20000;
@ -278,7 +278,7 @@ export class RoomConnection implements RoomConnection {
followUsersStore.addFollower(responseMessage.getFollower()); followUsersStore.addFollower(responseMessage.getFollower());
} else if (message.hasFollowabortmessage()) { } else if (message.hasFollowabortmessage()) {
const abortMessage = message.getFollowabortmessage() as FollowAbortMessage; const abortMessage = message.getFollowabortmessage() as FollowAbortMessage;
if (get(followRoleStore) === followRoles.follower) { if (get(followRoleStore) === "follower") {
followUsersStore.stopFollowing(); followUsersStore.stopFollowing();
} else { } else {
followUsersStore.removeFollower(abortMessage.getFollower()); followUsersStore.removeFollower(abortMessage.getFollower());
@ -791,7 +791,7 @@ export class RoomConnection implements RoomConnection {
} }
public emitFollowAbort(): void { public emitFollowAbort(): void {
const isLeader = get(followRoleStore) === followRoles.leader; const isLeader = get(followRoleStore) === "leader";
const hasFollowers = get(followUsersStore).length > 0; const hasFollowers = get(followUsersStore).length > 0;
if (!this.userId || (isLeader && !hasFollowers)) { if (!this.userId || (isLeader && !hasFollowers)) {
return; return;

View file

@ -6,13 +6,7 @@ import type { RemotePlayer } from "../Entity/RemotePlayer";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { userMovingStore } from "../../Stores/GameStore"; import { userMovingStore } from "../../Stores/GameStore";
import { import { followStateStore, followRoleStore, followUsersStore } from "../../Stores/FollowStore";
followStateStore,
followRoleStore,
followUsersStore,
followRoles,
followStates,
} from "../../Stores/FollowStore";
export const hasMovedEventName = "hasMoved"; export const hasMovedEventName = "hasMoved";
export const requestEmoteEventName = "requestEmote"; export const requestEmoteEventName = "requestEmote";
@ -51,7 +45,7 @@ export class Player extends Character {
} }
// Compute movement deltas // Compute movement deltas
const followMode = get(followStateStore) !== followStates.off; const followMode = get(followStateStore) !== "off";
const speedup = activeEvents.get(UserInputEvent.SpeedUp) && !followMode ? 25 : 9; const speedup = activeEvents.get(UserInputEvent.SpeedUp) && !followMode ? 25 : 9;
const moveAmount = speedup * 20; const moveAmount = speedup * 20;
x = x * moveAmount; x = x * moveAmount;
@ -90,7 +84,7 @@ export class Player extends Character {
const player = this.scene.MapPlayersByKey.get(get(followUsersStore)[0]); const player = this.scene.MapPlayersByKey.get(get(followUsersStore)[0]);
if (!player) { if (!player) {
this.scene.connection?.emitFollowAbort(); this.scene.connection?.emitFollowAbort();
followStateStore.set(followStates.off); followStateStore.set("off");
return [0, 0]; return [0, 0];
} }
@ -107,7 +101,7 @@ export class Player extends Character {
} }
public enableFollowing() { public enableFollowing() {
followStateStore.set(followStates.active); followStateStore.set("active");
} }
public moveUser(delta: number): void { public moveUser(delta: number): void {
@ -116,17 +110,17 @@ export class Player extends Character {
const role = get(followRoleStore); const role = get(followRoleStore);
if (activeEvents.get(UserInputEvent.Follow)) { if (activeEvents.get(UserInputEvent.Follow)) {
if (state === followStates.off && this.scene.groups.size > 0) { if (state === "off" && this.scene.groups.size > 0) {
followStateStore.set(followStates.requesting); followStateStore.set("requesting");
followRoleStore.set(followRoles.leader); followRoleStore.set("leader");
} else if (state === followStates.active) { } else if (state === "active") {
followStateStore.set(followStates.ending); followStateStore.set("ending");
} }
} }
let x = 0; let x = 0;
let y = 0; let y = 0;
if ((state === followStates.active || state === followStates.ending) && role === followRoles.follower) { if ((state === "active" || state === "ending") && role === "follower") {
[x, y] = this.computeFollowMovement(); [x, y] = this.computeFollowMovement();
} }
this.inputStep(activeEvents, x, y); this.inputStep(activeEvents, x, y);

View file

@ -2,20 +2,11 @@ import { derived, writable } from "svelte/store";
import { getColorRgbFromHue } from "../WebRtc/ColorGenerator"; import { getColorRgbFromHue } from "../WebRtc/ColorGenerator";
import { gameManager } from "../Phaser/Game/GameManager"; import { gameManager } from "../Phaser/Game/GameManager";
export const followStates = { type FollowState = "off" | "requesting" | "active" | "ending";
off: "off", type FollowRole = "leader" | "follower";
requesting: "requesting",
active: "active",
ending: "ending",
};
export const followRoles = { export const followStateStore = writable<FollowState>("off");
leader: "leader", export const followRoleStore = writable<FollowRole>("leader");
follower: "follower",
};
export const followStateStore = writable(followStates.off);
export const followRoleStore = writable(followRoles.leader);
function createFollowUsersStore() { function createFollowUsersStore() {
const { subscribe, update, set } = writable<number[]>([]); const { subscribe, update, set } = writable<number[]>([]);
@ -23,8 +14,8 @@ function createFollowUsersStore() {
return { return {
subscribe, subscribe,
addFollowRequest(leader: number): void { addFollowRequest(leader: number): void {
followStateStore.set(followStates.requesting); followStateStore.set("requesting");
followRoleStore.set(followRoles.follower); followRoleStore.set("follower");
set([leader]); set([leader]);
}, },
addFollower(user: number): void { addFollower(user: number): void {
@ -44,8 +35,8 @@ function createFollowUsersStore() {
followers = followers.filter((id) => id !== user); followers = followers.filter((id) => id !== user);
if (followers.length === 0 && oldFollowerCount > 0) { if (followers.length === 0 && oldFollowerCount > 0) {
followStateStore.set(followStates.off); followStateStore.set("off");
followRoleStore.set(followRoles.leader); followRoleStore.set("leader");
} }
return followers; return followers;
@ -53,8 +44,8 @@ function createFollowUsersStore() {
}, },
stopFollowing(): void { stopFollowing(): void {
set([]); set([]);
followStateStore.set(followStates.off); followStateStore.set("off");
followRoleStore.set(followRoles.leader); followRoleStore.set("leader");
}, },
}; };
} }
@ -68,7 +59,7 @@ export const followUsersColorStore = derived(
[followStateStore, followRoleStore, followUsersStore], [followStateStore, followRoleStore, followUsersStore],
([$followStateStore, $followRoleStore, $followUsersStore]) => { ([$followStateStore, $followRoleStore, $followUsersStore]) => {
console.log($followStateStore); console.log($followStateStore);
if ($followStateStore !== followStates.active) { if ($followStateStore !== "active") {
return undefined; return undefined;
} }
@ -77,7 +68,7 @@ export const followUsersColorStore = derived(
} }
let leaderId: number; let leaderId: number;
if ($followRoleStore === followRoles.leader) { if ($followRoleStore === "leader") {
// Let's get my ID by a quite complicated way.... // Let's get my ID by a quite complicated way....
leaderId = gameManager.getCurrentGameScene().connection?.getUserId() ?? 0; leaderId = gameManager.getCurrentGameScene().connection?.getUserId() ?? 0;
} else { } else {
@ -88,7 +79,7 @@ export const followUsersColorStore = derived(
const hue = ((leaderId * 197) % 255) / 255; const hue = ((leaderId * 197) % 255) / 255;
let { r, g, b } = getColorRgbFromHue(hue); let { r, g, b } = getColorRgbFromHue(hue);
if ($followRoleStore === followRoles.follower) { if ($followRoleStore === "follower") {
// Let's make the followers very slightly darker // Let's make the followers very slightly darker
r *= 0.9; r *= 0.9;
g *= 0.9; g *= 0.9;