one big container ready

This commit is contained in:
Olivier Gagnon 2021-09-17 02:31:19 -04:00
parent 4a3658ea13
commit 1883bea906
8 changed files with 82 additions and 122 deletions

@ -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 () {

@ -25,9 +25,9 @@ export function ProgramsRoot(props: IProps): React.ReactElement {
<div>
<Box>
<Typography>
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.
</Typography>
</Box>
<ButtonGroup>
@ -36,15 +36,15 @@ export function ProgramsRoot(props: IProps): React.ReactElement {
if (create === null) return <></>;
return (
<Tooltip title={create.tooltip}>
<Tooltip key={program.name} title={create.tooltip}>
<Button onClick={() => props.player.startCreateProgramWork(program.name, create.time, create.level)}>
{program.name}
{program.name}
</Button>
</Tooltip>
)
);
})}
</ButtonGroup>
</div>
</>
)
);
}

@ -21,7 +21,6 @@ import { dialogBoxCreate } from "../../utils/DialogBox";
import * as React from "react";
export interface IProcessOrderRefs {
rerenderFn: () => void;
stockMarket: IStockMarket;
symbolToStockMap: IMap<Stock>;
}
@ -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;
}
}

@ -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<any> = {}; // 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<Stock> = {}; // 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(
<StockMarketRoot
buyStockLong={buyStock}
buyStockShort={shortStock}
cancelOrder={cancelOrder}
eventEmitterForReset={eventEmitterForUiReset}
initStockMarket={initStockMarketFnForReact}
p={Player}
placeOrder={placeOrder}
sellStockLong={sellStock}
sellStockShort={sellShort}
stockMarket={castedStockMarket}
/>,
stockMarketContainer,
);
}
}
export const eventEmitterForUiReset = new EventEmitter();

@ -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<IProps, IState> {
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 (
<div className="stock-market-container">
<InfoAndPurchases initStockMarket={this.props.initStockMarket} p={this.props.p} rerender={this.rerender} />
{this.props.p.hasWseAccount && (
<StockTickers
buyStockLong={this.props.buyStockLong}
buyStockShort={this.props.buyStockShort}
cancelOrder={this.props.cancelOrder}
eventEmitterForReset={this.props.eventEmitterForReset}
p={this.props.p}
placeOrder={this.props.placeOrder}
sellStockLong={this.props.sellStockLong}
sellStockShort={this.props.sellStockShort}
stockMarket={this.props.stockMarket}
/>
)}
</div>
);
}
useEffect(() => {
const id = setInterval(rerender, 200);
return () => clearInterval(id);
}, []);
return (
<div className="stock-market-container">
<InfoAndPurchases initStockMarket={props.initStockMarket} p={props.p} rerender={rerender} />
{props.p.hasWseAccount && (
<StockTickers
buyStockLong={props.buyStockLong}
buyStockShort={props.buyStockShort}
cancelOrder={props.cancelOrder}
eventEmitterForReset={props.eventEmitterForReset}
p={props.p}
placeOrder={props.placeOrder}
sellStockLong={props.sellStockLong}
sellStockShort={props.sellStockShort}
stockMarket={props.stockMarket}
/>
)}
</div>
);
}

@ -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 () {

@ -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
<ResleeveRoot player={player} />
) : page === Page.Travel ? (
<TravelAgencyRoot p={player} router={router} />
) : page === Page.City ? (
<LocationRoot initiallyInCity={true} engine={engine} p={player} router={router} />
) : page === Page.StockMarket ? (
<StockMarketRoot
buyStockLong={buyStock}
@ -150,12 +159,16 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
cancelOrder={cancelOrder}
eventEmitterForReset={eventEmitterForUiReset}
initStockMarket={initStockMarketFnForReact}
p={Player}
p={player}
placeOrder={placeOrder}
sellStockLong={sellStock}
sellStockShort={sellShort}
stockMarket={castedStockMarket}
stockMarket={StockMarket}
/>
) : page === Page.City ? (
<LocationRoot initiallyInCity={true} engine={engine} p={player} router={router} />
) : page === Page.Job ? (
<LocationRoot initiallyInCity={false} engine={engine} p={player} router={router} />
) : page === Page.Options ? (
<GameOptionsRoot
player={player}

@ -1141,7 +1141,6 @@ describe("Stock Market Tests", function () {
Player.setMoney(100e9);
processOrdersRefs = {
rerenderFn: () => undefined,
stockMarket: StockMarket as IStockMarket,
symbolToStockMap: SymbolToStockMap,
};