Skip to content

Commit

Permalink
fix(Networking): Overhaul the networking layer to be more flexible fo…
Browse files Browse the repository at this point in the history
…r card and core development.
  • Loading branch information
alexanderson1993 committed May 24, 2022
1 parent 74871eb commit 339ce9c
Show file tree
Hide file tree
Showing 40 changed files with 344 additions and 502 deletions.
4 changes: 2 additions & 2 deletions client/src/cards/Login/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import Button from "@thorium/ui/Button";
import Input from "@thorium/ui/Input";
import {netSend} from "client/src/context/netSend";
import {useClientData} from "client/src/context/useCardData";
import {useNetRequest} from "client/src/context/useNetRequest";
import {useState} from "react";

const Login = () => {
const [loginName, setLoginName] = useState("");
// TODO: Support logging in with a ThoriumSim account
const {ship} = useClientData();
const ship = useNetRequest("ship");
const login = () => {
if (loginName.trim().length > 0) {
// TODO: Play a sound effect when the user logs in
Expand Down
10 changes: 6 additions & 4 deletions client/src/cards/OfficersLog/OfficersLog.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ import userEvent from "@testing-library/user-event";
import {act} from "react-dom/test-utils";

test("it should render without error", async () => {
const {findByText, queryByText, findByRole, netSendSpy} =
await render<"OfficersLog">(<OfficersLog />, {
cardData: {
const {findByText, queryByText, findByRole, netSendSpy} = await render(
<OfficersLog />,
{
netRequestData: {
officersLog: [
{
message: "This is a test log entry",
timestamp: 1639484836855,
},
],
},
});
}
);
const logEl = await findByText("@560.60");
expect(logEl).toBeInTheDocument();
userEvent.click(logEl);
Expand Down
8 changes: 6 additions & 2 deletions client/src/cards/OfficersLog/data.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import {DataContext} from "server/src/utils/DataContext";

export const subscriptions = {
officersLog(context: DataContext, publishParams: {clientId: string}) {
export const requests = {
officersLog(
context: DataContext,
params: {},
publishParams: {clientId: string}
) {
if (publishParams && context.clientId !== publishParams.clientId)
throw null;

Expand Down
6 changes: 3 additions & 3 deletions client/src/cards/OfficersLog/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import Button from "@thorium/ui/Button";
import {netSend} from "client/src/context/netSend";
import {toast} from "client/src/context/ToastContext";
import useCardData, {useClientData} from "client/src/context/useCardData";
import {useNetRequest} from "client/src/context/useNetRequest";
import {fromDate} from "dot-beat-time";
import * as React from "react";

export default function OfficersLog() {
const {client} = useClientData();
const {officersLog} = useCardData<"OfficersLog">();
const client = useNetRequest("client");
const officersLog = useNetRequest("officersLog");
const [stardate, setStardate] = React.useState(new Date());
const [logEntry, setLogEntry] = React.useState<string>("");
const [selectedEntry, setSelectedEntry] = React.useState<number | null>();
Expand Down
4 changes: 2 additions & 2 deletions client/src/cards/Offline/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useClientData} from "client/src/context/useCardData";
import {useNetRequest} from "client/src/context/useNetRequest";
import {Fragment} from "react";

// Messages go here
Expand Down Expand Up @@ -26,7 +26,7 @@ const messages: Record<string, {title: string; message: string}> = {
};

const Offline: React.FC = () => {
const {client} = useClientData();
const client = useNetRequest("client");

if (!client.offlineState) return null;
return (
Expand Down
17 changes: 13 additions & 4 deletions client/src/cards/Pilot/data.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import {getShipSystem} from "client/src/utils/getShipSystem";
import {DataContext} from "server/src/utils/DataContext";
import {Entity} from "server/src/utils/ecs";

export const subscriptions = {
ship(context: DataContext) {
return context.ship?.toJSON();
},
export const requests = {
impulseEngines(context: DataContext) {
return getShipSystem(context, "impulseEngines");
},
};

export function dataStream(
entity: Entity,
context: DataContext,
params: {systemId: number | null}
): boolean {
return Boolean(
entity.components.position &&
entity.components.position.parentId === params.systemId
);
}
10 changes: 7 additions & 3 deletions client/src/cards/Pilot/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import useCardData from "client/src/context/useCardData";
import {useDataStream} from "client/src/context/useDataStream";
import {useNetRequest} from "client/src/context/useNetRequest";

export function Pilot() {
const cardData = useCardData<"Pilot">();
const ship = useNetRequest("ship");
const impulseEngines = useNetRequest("impulseEngines");
useDataStream({systemId: null});

return (
<div className="flex flex-col justify-center items-center h-full">
<h1 className="text-6xl font-bold">Pilot</h1>
<pre className="flex-1 overflow-y-auto">
{JSON.stringify(cardData, null, 2)}
{JSON.stringify(ship, null, 2)}
{JSON.stringify(impulseEngines, null, 2)}
</pre>
</div>
);
Expand Down
47 changes: 32 additions & 15 deletions client/src/cards/clientData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {staticStations} from "server/src/classes/Station";

// This file is used for any subscriptions which all clients
// make, regardless of what cards they have.
export const subscriptions = {
export const requests = {
thorium: (context: DataContext) => {
const hasHost = Object.values(context.server.clients).some(
client => client.isHost && client.connected
Expand All @@ -16,8 +16,13 @@ export const subscriptions = {
hasHost,
};
},
client: (context: DataContext, params: {clientId: string}) => {
if (params && params.clientId !== context.clientId) throw null;
client: (
context: DataContext,
params: {},
publishParams: {clientId: string}
) => {
if (publishParams && publishParams.clientId !== context.clientId)
throw null;

const {id, name, connected, isHost} =
context.server.clients[context.clientId];
Expand All @@ -34,17 +39,32 @@ export const subscriptions = {
const {date, name, paused} = flight;
return {date, name, paused};
},
ship(context: DataContext, params: {shipId: number} | {clientId: string}) {
if (params) {
if ("shipId" in params && params.shipId !== context.flightClient?.shipId)
ship(
context: DataContext,
params: {},
publishParams: {shipId: number} | {clientId: string}
) {
if (publishParams) {
if (
"shipId" in publishParams &&
publishParams.shipId !== context.flightClient?.shipId
)
throw null;
if ("clientId" in params && params.clientId !== context.clientId)
if (
"clientId" in publishParams &&
publishParams.clientId !== context.clientId
)
throw null;
}
return context.ship?.toJSON() as Entity;
},
station(context: DataContext, params: {clientId: string}): Station {
if (params && params.clientId !== context.clientId) throw null;
station(
context: DataContext,
params: {},
publishParams: {clientId: string}
): Station {
if (publishParams && publishParams.clientId !== context.clientId)
throw null;
if (context.flightClient?.stationOverride)
return context.flightClient.stationOverride;
const station = staticStations
Expand All @@ -54,8 +74,9 @@ export const subscriptions = {
) as unknown as Station;
return station || null;
},
theme(context: DataContext, params: {clientId: string}) {
if (params && params.clientId !== context.clientId) throw null;
theme(context: DataContext, params: {}, publishParams: {clientId: string}) {
if (publishParams && publishParams.clientId !== context.clientId)
throw null;
const themeObj = context.server.plugins
.filter(plugin => context.flight?.pluginIds.includes(plugin.id))
.reduce((acc: null | ThemePlugin, plugin) => {
Expand All @@ -70,7 +91,3 @@ export const subscriptions = {
return themeObj;
},
};

export function dataStream(entity: Entity, context: DataContext): boolean {
return true; //!!(entity.components.position && entity.components.velocity);
}
2 changes: 1 addition & 1 deletion client/src/cards/timer/data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {DataContext} from "server/src/utils/DataContext";

export const subscriptions = {
export const requests = {
timer(context: DataContext) {
// TODO: fetch timer data
},
Expand Down
7 changes: 4 additions & 3 deletions client/src/components/ClientButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {useClientData} from "../context/useCardData";
import {usePrompt} from "@thorium/ui/AlertDialog";
import Button from "@thorium/ui/Button";
import {netSend} from "../context/netSend";
import {useNetRequest} from "../context/useNetRequest";

export function ClientButton() {
const clientData = useClientData();
const client = useNetRequest("client");

const prompt = usePrompt();
return (
<div className="flex items-center gap-4">
Expand All @@ -20,7 +21,7 @@ export function ClientButton() {
}
}}
>
{clientData?.client.name || ""}
{client.name || ""}
</Button>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export function CoreFlexLayoutDropdown() {
},
{
enabled: account?.user_id !== undefined,
suspense: false,
}
);

Expand Down
9 changes: 5 additions & 4 deletions client/src/components/FlightQuickStart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Button from "@thorium/ui/Button";
import Modal from "@thorium/ui/Modal";
import {netSend} from "client/src/context/netSend";
import {toast} from "client/src/context/ToastContext";
import {useClientData} from "client/src/context/useCardData";
import {useNetRequest} from "client/src/context/useNetRequest";
import {useMatch, useNavigate, Navigate, Outlet, Link} from "react-router-dom";
import {randomNameGenerator} from "server/src/utils/randomNameGenerator";
import {useFlightQuickStart} from "./FlightQuickStartContext";
Expand All @@ -11,7 +11,8 @@ function capitalize(val: string) {
return val.charAt(0).toUpperCase() + val.slice(1);
}
export default function FlightQuickStart() {
const clientData = useClientData();
const flight = useNetRequest("flight");
const client = useNetRequest("client");

const [state, dispatch] = useFlightQuickStart();

Expand All @@ -20,8 +21,8 @@ export default function FlightQuickStart() {
const match = useMatch("/flight/quick/:step");

if (!match) return <Navigate to="/flight/quick/crew" replace />;
if (clientData.flight) return <Navigate to="/flight" replace />;
if (!clientData.client.isHost) return <Navigate to="/" replace />;
if (flight) return <Navigate to="/flight" replace />;
if (!client.isHost) return <Navigate to="/" replace />;

const {step} = match.params;

Expand Down
9 changes: 5 additions & 4 deletions client/src/components/Station/CardArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import {ComponentType, Fragment, Suspense, useState} from "react";
import {ErrorBoundary} from "react-error-boundary";
import {Transition} from "@headlessui/react";
import {CardProps} from "./CardProps";
import {useClientData} from "client/src/context/useCardData";
import {LoadingSpinner} from "@thorium/ui/LoadingSpinner";
import CardProvider from "client/src/context/CardContext";
import {useNetRequest} from "client/src/context/useNetRequest";

const CardError = () => {
return (
Expand All @@ -33,9 +33,10 @@ const transitionProps = {
};

export const CardArea: React.FC<{
card: ReturnType<typeof useClientData>["station"]["cards"][0];
card: {component: string};
}> = ({card}) => {
const {client, station} = useClientData();
const client = useNetRequest("client");
const station = useNetRequest("station");
const CardComponents = station.cards.map(card => ({
...card,
CardComponent: Cards[card.component as keyof typeof Cards],
Expand Down Expand Up @@ -69,7 +70,7 @@ const CardRenderer = ({
id: string;
currentCardId: string;
}) => {
const {client} = useClientData();
const client = useNetRequest("client");
const allowCard = Boolean(client.loginName) && !client.offlineState;
const [cardLoaded, setCardLoaded] = useState(false);
const show = allowCard && currentCardId === id;
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/Station/CardSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {SVGImageLoader} from "@thorium/ui/SVGImageLoader";
import {useClientData} from "client/src/context/useCardData";
import {useNetRequest} from "client/src/context/useNetRequest";

const CardButton: React.FC<{
active: boolean;
Expand Down Expand Up @@ -28,7 +28,7 @@ export const CardSwitcher: React.FC<{
card: string;
changeCard: (id: string) => void;
}> = ({card, changeCard}) => {
const {station} = useClientData();
const station = useNetRequest("station");
return (
<div className="card-switcher-holder absolute right-0">
<div className="card-switcher">
Expand Down
11 changes: 7 additions & 4 deletions client/src/components/Station/StationLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import {SVGImageLoader} from "@thorium/ui/SVGImageLoader";
import {netSend} from "client/src/context/netSend";
import {useThoriumAccount} from "client/src/context/ThoriumAccountContext";
import {useClientData} from "client/src/context/useCardData";
import {useNetRequest} from "client/src/context/useNetRequest";
import {RiLogoutCircleRLine} from "react-icons/ri";
import {CardArea} from "./CardArea";
import {CardSwitcher} from "./CardSwitcher";
import {useManageCard} from "./useManageCard";
import {ClickWidget} from "./widgets";

const StationLayout = () => {
const {ship, client, station, theme} = useClientData();
const ship = useNetRequest("ship");
const client = useNetRequest("client");
const station = useNetRequest("station");
const theme = useNetRequest("theme");
const [card, changeCard] = useManageCard();

if (!ship) throw new Promise(() => {});
const {account} = useThoriumAccount();
if (!ship) return null;
// TODO November 29, 2021: Get the proper alert level and put it here.
// @ts-expect-error See above
const alertLevel = ship.alertLevel || "5";
const {account} = useThoriumAccount();
return (
<div id="theme-container" className="h-full w-full">
<div
Expand Down
6 changes: 3 additions & 3 deletions client/src/components/Station/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import {useClientData} from "client/src/context/useCardData";
import {Navigate} from "react-router-dom";
import {lazy, Suspense} from "react";
import {LoadingSpinner} from "@thorium/ui/LoadingSpinner";
import {useNetRequest} from "client/src/context/useNetRequest";

const FlightDirectorLayout = lazy(() => import("../FlightDirector"));
const StationLayout = lazy(() => import("./StationLayout"));
const Effects = lazy(() => import("./Effects"));

const StationWrapper = () => {
const {client, station} = useClientData();

const client = useNetRequest("client");
const station = useNetRequest("station");
// TODO November 29, 2021: Include sound player here
// TODO November 29, 2021: Include some kind of alert toast notification thing here
// The existing alerts won't be targeted by the theme, so we need to embed it here.
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/Station/useManageCard.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {useClientData} from "client/src/context/useCardData";
import {useNetRequest} from "client/src/context/useNetRequest";
import {useCallback, useRef, useState} from "react";

export function useManageCard() {
const {station} = useClientData();
const station = useNetRequest("station");
const [currentCard, setCurrentCard] = useState(
station.cards[0]?.component || ""
);
Expand Down
Loading

0 comments on commit 339ce9c

Please sign in to comment.