From 1883bea906d54009cdf372afe397ef4fa573eb3d Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 17 Sep 2021 02:31:19 -0400 Subject: [PATCH] one big container ready --- src/NetscriptFunctions.js | 26 ++-------- src/Programs/ui/ProgramsRoot.tsx | 14 +++--- src/StockMarket/OrderProcessing.tsx | 3 -- src/StockMarket/StockMarket.tsx | 62 ++++++++--------------- src/StockMarket/ui/StockMarketRoot.tsx | 69 ++++++++++---------------- src/engine.jsx | 4 +- src/ui/GameRoot.tsx | 25 +++++++--- test/StockMarket.test.ts | 1 - 8 files changed, 82 insertions(+), 122 deletions(-) diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index add4e2693..1d3447c88 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -119,13 +119,7 @@ import { SpecialServerIps } from "./Server/SpecialServerIps"; import { SourceFileFlags } from "./SourceFile/SourceFileFlags"; import { buyStock, sellStock, shortStock, sellShort } from "./StockMarket/BuyingAndSelling"; import { influenceStockThroughServerHack, influenceStockThroughServerGrow } from "./StockMarket/PlayerInfluencing"; -import { - StockMarket, - SymbolToStockMap, - placeOrder, - cancelOrder, - displayStockMarketContent, -} from "./StockMarket/StockMarket"; +import { StockMarket, SymbolToStockMap, placeOrder, cancelOrder } from "./StockMarket/StockMarket"; import { getBuyTransactionCost, getSellTransactionGain } from "./StockMarket/StockMarketHelpers"; import { OrderTypes } from "./StockMarket/data/OrderTypes"; import { PositionTypes } from "./StockMarket/data/PositionTypes"; @@ -1964,18 +1958,14 @@ function NetscriptFunctions(workerScript) { updateDynamicRam("buyStock", getRamCost("buyStock")); checkTixApiAccess("buyStock"); const stock = getStockFromSymbol(symbol, "buyStock"); - const res = buyStock(stock, shares, workerScript, { - rerenderFn: displayStockMarketContent, - }); + const res = buyStock(stock, shares, workerScript, {}); return res ? stock.price : 0; }, sellStock: function (symbol, shares) { updateDynamicRam("sellStock", getRamCost("sellStock")); checkTixApiAccess("sellStock"); const stock = getStockFromSymbol(symbol, "sellStock"); - const res = sellStock(stock, shares, workerScript, { - rerenderFn: displayStockMarketContent, - }); + const res = sellStock(stock, shares, workerScript, {}); return res ? stock.price : 0; }, @@ -1991,9 +1981,7 @@ function NetscriptFunctions(workerScript) { } } const stock = getStockFromSymbol(symbol, "shortStock"); - const res = shortStock(stock, shares, workerScript, { - rerenderFn: displayStockMarketContent, - }); + const res = shortStock(stock, shares, workerScript, {}); return res ? stock.price : 0; }, @@ -2009,9 +1997,7 @@ function NetscriptFunctions(workerScript) { } } const stock = getStockFromSymbol(symbol, "sellShort"); - const res = sellShort(stock, shares, workerScript, { - rerenderFn: displayStockMarketContent, - }); + const res = sellShort(stock, shares, workerScript, {}); return res ? stock.price : 0; }, @@ -2168,7 +2154,6 @@ function NetscriptFunctions(workerScript) { Player.has4SData = true; Player.loseMoney(getStockMarket4SDataCost()); workerScript.log("purchase4SMarketData", "Purchased 4S Market Data"); - displayStockMarketContent(); return true; }, purchase4SMarketDataTixApi: function () { @@ -2188,7 +2173,6 @@ function NetscriptFunctions(workerScript) { Player.has4SDataTixApi = true; Player.loseMoney(getStockMarket4STixApiCost()); workerScript.log("purchase4SMarketDataTixApi", "Purchased 4S Market Data TIX API"); - displayStockMarketContent(); return true; }, getPurchasedServerLimit: function () { diff --git a/src/Programs/ui/ProgramsRoot.tsx b/src/Programs/ui/ProgramsRoot.tsx index 3b82d5387..2d274ac86 100644 --- a/src/Programs/ui/ProgramsRoot.tsx +++ b/src/Programs/ui/ProgramsRoot.tsx @@ -25,9 +25,9 @@ export function ProgramsRoot(props: IProps): React.ReactElement {
- This page displays any programs that you are able to create. Writing the code for a program takes time, which - can vary based on how complex the program is. If you are working on creating a program you can cancel at any - time. Your progress will be saved and you can continue later. + This page displays any programs that you are able to create. Writing the code for a program takes time, + which can vary based on how complex the program is. If you are working on creating a program you can cancel + at any time. Your progress will be saved and you can continue later. @@ -36,15 +36,15 @@ export function ProgramsRoot(props: IProps): React.ReactElement { if (create === null) return <>; return ( - + - ) + ); })}
- ) + ); } diff --git a/src/StockMarket/OrderProcessing.tsx b/src/StockMarket/OrderProcessing.tsx index d6a6c8cf4..e22024a40 100644 --- a/src/StockMarket/OrderProcessing.tsx +++ b/src/StockMarket/OrderProcessing.tsx @@ -21,7 +21,6 @@ import { dialogBoxCreate } from "../../utils/DialogBox"; import * as React from "react"; export interface IProcessOrderRefs { - rerenderFn: () => void; stockMarket: IStockMarket; symbolToStockMap: IMap; } @@ -116,7 +115,6 @@ function executeOrder(order: Order, refs: IProcessOrderRefs): void { // When orders are executed, the buying and selling functions shouldn't // emit popup dialog boxes. This options object configures the functions for that const opts = { - rerenderFn: refs.rerenderFn, suppressDialog: true, }; @@ -158,7 +156,6 @@ function executeOrder(order: Order, refs: IProcessOrderRefs): void { {numeralWrapper.formatShares(Math.round(order.shares))} shares) , ); - refs.rerenderFn(); return; } } diff --git a/src/StockMarket/StockMarket.tsx b/src/StockMarket/StockMarket.tsx index dbb62e2e7..d33de36f1 100644 --- a/src/StockMarket/StockMarket.tsx +++ b/src/StockMarket/StockMarket.tsx @@ -26,7 +26,12 @@ import { Reviver } from "../../utils/JSONReviver"; import * as React from "react"; import * as ReactDOM from "react-dom"; -export let StockMarket: IStockMarket | IMap = {}; // Maps full stock name -> Stock object +export let StockMarket: IStockMarket = { + lastUpdate: 0, + Orders: {}, + storedCycles: 0, + ticksUntilCycle: 0, +} as IStockMarket; // Maps full stock name -> Stock object export const SymbolToStockMap: IMap = {}; // Maps symbol -> Stock object export function placeOrder( @@ -70,12 +75,10 @@ export function placeOrder( // Process to see if it should be executed immediately const processOrderRefs = { - rerenderFn: displayStockMarketContent, stockMarket: StockMarket as IStockMarket, symbolToStockMap: SymbolToStockMap, }; processOrders(stock, order.type, order.pos, processOrderRefs); - displayStockMarketContent(); return true; } @@ -100,7 +103,6 @@ export function cancelOrder(params: ICancelOrderParams, workerScript: WorkerScri for (let i = 0; i < stockOrders.length; ++i) { if (order == stockOrders[i]) { stockOrders.splice(i, 1); - displayStockMarketContent(); return true; } } @@ -125,7 +127,6 @@ export function cancelOrder(params: ICancelOrderParams, workerScript: WorkerScri params.pos === order.pos ) { stockOrders.splice(i, 1); - displayStockMarketContent(); if (workerScript) { workerScript.scriptRef.log("Successfully cancelled order: " + orderTxt); } @@ -142,14 +143,25 @@ export function cancelOrder(params: ICancelOrderParams, workerScript: WorkerScri export function loadStockMarket(saveString: string): void { if (saveString === "") { - StockMarket = {}; + StockMarket = { + lastUpdate: 0, + Orders: {}, + storedCycles: 0, + ticksUntilCycle: 0, + } as IStockMarket; } else { + console.log(JSON.parse(saveString, Reviver)); StockMarket = JSON.parse(saveString, Reviver); } } export function deleteStockMarket(): void { - StockMarket = {}; + StockMarket = { + lastUpdate: 0, + Orders: {}, + storedCycles: 0, + ticksUntilCycle: 0, + } as IStockMarket; } export function initStockMarket(): void { @@ -269,8 +281,7 @@ export function processStockPrices(numCycles = 1): void { const c = Math.random(); const processOrderRefs = { - rerenderFn: displayStockMarketContent, - stockMarket: StockMarket as IStockMarket, + stockMarket: StockMarket, symbolToStockMap: SymbolToStockMap, }; if (c < chc) { @@ -301,8 +312,6 @@ export function processStockPrices(numCycles = 1): void { // Shares required for price movement gradually approaches max over time stock.shareTxUntilMovement = Math.min(stock.shareTxUntilMovement + 10, stock.shareTxForMovement); } - - displayStockMarketContent(); } let stockMarketContainer: HTMLElement | null = null; @@ -313,36 +322,9 @@ function setStockMarketContainer(): void { document.addEventListener("DOMContentLoaded", setStockMarketContainer); -function initStockMarketFnForReact(): void { +export function initStockMarketFnForReact(): void { initStockMarket(); initSymbolToStockMap(); } -const eventEmitterForUiReset = new EventEmitter(); - -export function displayStockMarketContent(): void { - if (!routing.isOn(Page.StockMarket)) { - return; - } - - eventEmitterForUiReset.emitEvent(); - - if (stockMarketContainer instanceof HTMLElement) { - const castedStockMarket = StockMarket as IStockMarket; - ReactDOM.render( - , - stockMarketContainer, - ); - } -} +export const eventEmitterForUiReset = new EventEmitter(); diff --git a/src/StockMarket/ui/StockMarketRoot.tsx b/src/StockMarket/ui/StockMarketRoot.tsx index 6effdfa11..e7cfecf73 100644 --- a/src/StockMarket/ui/StockMarketRoot.tsx +++ b/src/StockMarket/ui/StockMarketRoot.tsx @@ -1,7 +1,7 @@ /** * Root React component for the Stock Market UI */ -import * as React from "react"; +import React, { useState, useEffect } from "react"; import { InfoAndPurchases } from "./InfoAndPurchases"; import { StockTickers } from "./StockTickers"; @@ -36,47 +36,32 @@ type IProps = { stockMarket: IStockMarket; }; -type IState = { - rerenderFlag: boolean; -}; - -export class StockMarketRoot extends React.Component { - constructor(props: IProps) { - super(props); - - this.state = { - rerenderFlag: false, - }; - - this.rerender = this.rerender.bind(this); +export function StockMarketRoot(props: IProps) { + const setRerender = useState(false)[1]; + function rerender(): void { + setRerender((old) => !old); } - rerender(): void { - this.setState((prevState) => { - return { - rerenderFlag: !prevState.rerenderFlag, - }; - }); - } - - render(): React.ReactNode { - return ( -
- - {this.props.p.hasWseAccount && ( - - )} -
- ); - } + useEffect(() => { + const id = setInterval(rerender, 200); + return () => clearInterval(id); + }, []); + return ( +
+ + {props.p.hasWseAccount && ( + + )} +
+ ); } diff --git a/src/engine.jsx b/src/engine.jsx index ec3856841..d68172824 100644 --- a/src/engine.jsx +++ b/src/engine.jsx @@ -53,7 +53,7 @@ import { initForeignServers, AllServers } from "./Server/AllServers"; import { Settings } from "./Settings/Settings"; import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags"; import { initSpecialServerIps } from "./Server/SpecialServerIps"; -import { initSymbolToStockMap, processStockPrices, displayStockMarketContent } from "./StockMarket/StockMarket"; +import { initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket"; import { MilestonesRoot } from "./Milestones/ui/MilestonesRoot"; import { TerminalRoot } from "./Terminal/ui/TerminalRoot"; import { Terminal } from "./Terminal"; @@ -308,7 +308,7 @@ const Engine = { Engine.Display.content.style.display = "block"; routing.navigateTo(Page.StockMarket); MainMenuLinks.StockMarket.classList.add("active"); - displayStockMarketContent(); + //displayStockMarketContent(); }, loadGangContent: function () { diff --git a/src/ui/GameRoot.tsx b/src/ui/GameRoot.tsx index b8c27ca85..5fa9cb350 100644 --- a/src/ui/GameRoot.tsx +++ b/src/ui/GameRoot.tsx @@ -12,6 +12,14 @@ import { Faction } from "../Faction/Faction"; import { prestigeAugmentation } from "../Prestige"; import { dialogBoxCreate } from "../../utils/DialogBox"; import { AllServers } from "../Server/AllServers"; +import { buyStock, sellStock, shortStock, sellShort } from "../StockMarket/BuyingAndSelling"; +import { + cancelOrder, + eventEmitterForUiReset, + initStockMarketFnForReact, + placeOrder, + StockMarket, +} from "../StockMarket/StockMarket"; import { Theme } from "@mui/material/styles"; import makeStyles from "@mui/styles/makeStyles"; @@ -41,7 +49,7 @@ import { FactionsRoot } from "../Faction/ui/FactionsRoot"; import { FactionRoot } from "../Faction/ui/FactionRoot"; import { CharacterInfo } from "./CharacterInfo"; import { TravelAgencyRoot } from "../Locations/ui/TravelAgencyRoot"; -import { StockMarketRoot } from "../Locations/ui/StockMarketRoot"; +import { StockMarketRoot } from "../StockMarket/ui/StockMarketRoot"; import { workerScripts } from "../Netscript/WorkerScripts"; import { startHackingMission } from "../Faction/FactionHelpers"; @@ -90,7 +98,10 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme toStockMarket: () => setPage(Page.StockMarket), toTerminal: () => setPage(Page.Terminal), toTutorial: () => setPage(Page.Tutorial), - toJob: () => setPage(Page.Job), + toJob: () => { + player.gotoLocation(player.companyName as LocationName); + setPage(Page.Job); + }, toCity: () => { // TODO This is bad. player.gotoLocation(player.city as unknown as LocationName); @@ -141,8 +152,6 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme ) : page === Page.Travel ? ( - ) : page === Page.City ? ( - ) : page === Page.StockMarket ? ( + ) : page === Page.City ? ( + + ) : page === Page.Job ? ( + ) : page === Page.Options ? ( undefined, stockMarket: StockMarket as IStockMarket, symbolToStockMap: SymbolToStockMap, };