From 4cc6437408c939c8e45b126b86004de2ca9c6d6e Mon Sep 17 00:00:00 2001 From: danielyxie Date: Wed, 19 Jun 2019 01:51:25 -0700 Subject: [PATCH] Updated WorkerScript-related code for the workerScripts array->map change --- src/Netscript/killWorkerScript.ts | 121 +++++++++++----------- src/NetscriptFunctions.js | 6 +- src/NetscriptWorker.js | 22 ++-- src/ui/ActiveScripts/Root.tsx | 2 +- src/ui/ActiveScripts/ScriptProduction.tsx | 6 +- src/ui/ActiveScripts/ServerAccordions.tsx | 4 +- 6 files changed, 83 insertions(+), 78 deletions(-) diff --git a/src/Netscript/killWorkerScript.ts b/src/Netscript/killWorkerScript.ts index 59abd4e93..d97775842 100644 --- a/src/Netscript/killWorkerScript.ts +++ b/src/Netscript/killWorkerScript.ts @@ -14,26 +14,31 @@ import { roundToTwo } from "../../utils/helpers/roundToTwo"; export function killWorkerScript(runningScriptObj: RunningScript, serverIp: string): boolean; export function killWorkerScript(workerScript: WorkerScript): boolean; -export function killWorkerScript(script: RunningScript | WorkerScript, serverIp?: string): boolean { +export function killWorkerScript(pid: number): boolean; +export function killWorkerScript(script: RunningScript | WorkerScript | number, serverIp?: string): boolean { if (script instanceof WorkerScript) { - script.env.stopFlag = true; - killNetscriptDelay(script); - removeWorkerScript(script); + stopAndCleanUpWorkerScript(script); return true; } else if (script instanceof RunningScript && typeof serverIp === "string") { - for (let i = 0; i < workerScripts.length; i++) { - if (workerScripts[i].name == script.filename && workerScripts[i].serverIp == serverIp && - compareArrays(workerScripts[i].args, script.args)) { - workerScripts[i].env.stopFlag = true; - killNetscriptDelay(workerScripts[i]); - removeWorkerScript(workerScripts[i]); + // Try to kill by PID + const res = killWorkerScriptByPid(script.pid); + if (res) { return res; } + + // If for some reason that doesn't work, we'll try the old way + for (const ws of workerScripts.values()) { + if (ws.name == script.filename && ws.serverIp == serverIp && + compareArrays(ws.args, script.args)) { + + stopAndCleanUpWorkerScript(ws); return true; } - } + } return false; + } else if (typeof script === "number") { + return killWorkerScriptByPid(script); } else { console.error(`killWorkerScript() called with invalid argument:`); console.error(script); @@ -41,6 +46,23 @@ export function killWorkerScript(script: RunningScript | WorkerScript, serverIp? } } +function stopAndCleanUpWorkerScript(workerScript: WorkerScript): void { + workerScript.env.stopFlag = true; + killNetscriptDelay(workerScript); + removeWorkerScript(workerScript); +} + +function killWorkerScriptByPid(pid: number): boolean { + const ws = workerScripts.get(pid); + if (ws instanceof WorkerScript) { + stopAndCleanUpWorkerScript(ws); + + return true; + } + + return false; +} + /** * Helper function that removes the script being killed from the global pool. * Also handles other cleanup-time operations @@ -48,66 +70,47 @@ export function killWorkerScript(script: RunningScript | WorkerScript, serverIp? * @param {WorkerScript | number} - Identifier for WorkerScript. Either the object itself, or * its index in the global workerScripts array */ -function removeWorkerScript(id: WorkerScript | number): void { - // Get a reference to the WorkerScript and its index in the global pool - let workerScript: WorkerScript; - let index: number | null = null; +function removeWorkerScript(workerScript: WorkerScript): void { + if (workerScript instanceof WorkerScript) { + const ip = workerScript.serverIp; + const name = workerScript.name; - if (typeof id === "number") { - if (id < 0 || id >= workerScripts.length) { - console.error(`Too high of an index passed into removeWorkerScript(): ${id}`); + // Get the server on which the script runs + const server = AllServers[ip]; + if (server == null) { + console.error(`Could not find server on which this script is running: ${ip}`); return; } - workerScript = workerScripts[id]; - index = id; - } else if (id instanceof WorkerScript) { - workerScript = id; - for (let i = 0; i < workerScripts.length; ++i) { - if (workerScripts[i] == id) { - index = i; + // Recalculate ram used on that server + server.ramUsed = roundToTwo(server.ramUsed - workerScript.ramUsage); + if (server.ramUsed < 0) { + console.warn(`Server RAM usage went negative (if it's due to floating pt imprecision, it's okay): ${server.ramUsed}`); + server.ramUsed = 0; + } + + // Delete the RunningScript object from that server + for (let i = 0; i < server.runningScripts.length; ++i) { + const runningScript = server.runningScripts[i]; + if (runningScript.filename === name && compareArrays(runningScript.args, workerScript.args)) { + server.runningScripts.splice(i, 1); break; } } - if (index == null) { - console.error(`Could not find WorkerScript in global pool:`); - console.error(workerScript); + // Delete script from global pool (workerScripts) + const res = workerScripts.delete(workerScript.pid); + if (!res) { + console.warn(`removeWorkerScript() called with WorkerScript that wasn't in the global map:`); + console.warn(workerScript); } + + WorkerScriptStartStopEventEmitter.emitEvent(); } else { - console.error(`Invalid argument passed into removeWorkerScript(): ${id}`); + console.error(`Invalid argument passed into removeWorkerScript():`); + console.error(workerScript); return; } - - const ip = workerScript.serverIp; - const name = workerScript.name; - - // Get the server on which the script runs - const server = AllServers[ip]; - if (server == null) { - console.error(`Could not find server on which this script is running: ${ip}`); - return; - } - - // Recalculate ram used on that server - server.ramUsed = roundToTwo(server.ramUsed - workerScript.ramUsage); - if (server.ramUsed < 0) { - console.warn(`Server RAM usage went negative (if it's due to floating pt imprecision, it's okay): ${server.ramUsed}`); - server.ramUsed = 0; - } - - // Delete the RunningScript object from that server - for (let i = 0; i < server.runningScripts.length; ++i) { - const runningScript = server.runningScripts[i]; - if (runningScript.filename === name && compareArrays(runningScript.args, workerScript.args)) { - server.runningScripts.splice(i, 1); - break; - } - } - - // Delete script from global pool (workerScripts) - workerScripts.splice(index, 1); - WorkerScriptStartStopEventEmitter.emitEvent(); } /** diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index cb751f9ae..28bba6eb1 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -2178,7 +2178,7 @@ function NetscriptFunctions(workerScript) { // First element is total income of all currently running scripts let total = 0; - for (const script of workerScripts) { + for (const script of workerScripts.values()) { total += (script.scriptRef.onlineMoneyMade / script.scriptRef.onlineRunningTime); } res.push(total); @@ -2209,8 +2209,8 @@ function NetscriptFunctions(workerScript) { updateDynamicRam("getScriptExpGain", getRamCost("getScriptExpGain")); if (arguments.length === 0) { var total = 0; - for (var i = 0; i < workerScripts.length; ++i) { - total += (workerScripts[i].scriptRef.onlineExpGained / workerScripts[i].scriptRef.onlineRunningTime); + for (const ws of workerScripts.values()) { + total += (ws.scriptRef.onlineExpGained / ws.scriptRef.onlineRunningTime); } return total; } else { diff --git a/src/NetscriptWorker.js b/src/NetscriptWorker.js index cb8a355ae..0d69234d2 100644 --- a/src/NetscriptWorker.js +++ b/src/NetscriptWorker.js @@ -46,11 +46,12 @@ for (var i = 0; i < CONSTANTS.NumNetscriptPorts; ++i) { } export function prestigeWorkerScripts() { - for (var i = 0; i < workerScripts.length; ++i) { - // TODO Signal event emitter - workerScripts[i].env.stopFlag = true; + for (const ws of workerScripts.values()) { + ws.env.stopFlag = true; } - workerScripts.length = 0; + + WorkerScriptStartStopEventEmitter.emitEvent(); + workerScripts.clear(); } // JS script promises need a little massaging to have the same guarantees as netscript @@ -475,7 +476,7 @@ export function addWorkerScript(runningScriptObj, server) { server.ramUsed = roundToTwo(server.ramUsed + ramUsage); // Get the pid - const pid = getNextPid(); + const pid = generateNextPid(); if (pid === -1) { throw new Error( `Failed to start script because could not find available PID. This is most ` + @@ -483,7 +484,8 @@ export function addWorkerScript(runningScriptObj, server) { ); } - // Create the WorkerScript + // Create the WorkerScript. NOTE: WorkerScript ctor will set the underlying + // RunningScript's PID as well const s = new WorkerScript(runningScriptObj, pid, NetscriptFunctions); s.ramUsage = ramUsage; @@ -547,7 +549,7 @@ export function addWorkerScript(runningScriptObj, server) { }); // Add the WorkerScript to the global pool - workerScripts.push(s); + workerScripts.set(pid, s); WorkerScriptStartStopEventEmitter.emitEvent(); return; } @@ -557,9 +559,9 @@ export function addWorkerScript(runningScriptObj, server) { */ export function updateOnlineScriptTimes(numCycles = 1) { var time = (numCycles * Engine._idleSpeed) / 1000; //seconds - for (var i = 0; i < workerScripts.length; ++i) { - workerScripts[i].scriptRef.onlineRunningTime += time; - } + for (const ws of workerScripts.values()) { + ws.scriptRef.onlineRunningTime += time; + } } /** diff --git a/src/ui/ActiveScripts/Root.tsx b/src/ui/ActiveScripts/Root.tsx index 2dd6e78d0..00ac8bbbb 100644 --- a/src/ui/ActiveScripts/Root.tsx +++ b/src/ui/ActiveScripts/Root.tsx @@ -12,7 +12,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer"; type IProps = { p: IPlayer; - workerScripts: WorkerScript[]; + workerScripts: Map; } export class ActiveScriptsRoot extends React.Component { diff --git a/src/ui/ActiveScripts/ScriptProduction.tsx b/src/ui/ActiveScripts/ScriptProduction.tsx index 66da02a01..faa6d0686 100644 --- a/src/ui/ActiveScripts/ScriptProduction.tsx +++ b/src/ui/ActiveScripts/ScriptProduction.tsx @@ -11,14 +11,14 @@ import { IPlayer } from "../../PersonObjects/IPlayer"; type IProps = { p: IPlayer; - workerScripts: WorkerScript[]; + workerScripts: Map; } export function ScriptProduction(props: IProps): React.ReactElement { const prodRateSinceLastAug = props.p.scriptProdSinceLastAug / (props.p.playtimeSinceLastAug / 1000); let onlineProduction = 0; - for (const ws of props.workerScripts) { + for (const ws of props.workerScripts.values()) { onlineProduction += (ws.scriptRef.onlineMoneyMade / ws.scriptRef.onlineRunningTime); } @@ -35,7 +35,7 @@ export function ScriptProduction(props: IProps): React.ReactElement { {numeralWrapper.formatMoney(props.p.scriptProdSinceLastAug)} - + ( {numeralWrapper.formatMoney(prodRateSinceLastAug)} diff --git a/src/ui/ActiveScripts/ServerAccordions.tsx b/src/ui/ActiveScripts/ServerAccordions.tsx index 554d69317..acd279870 100644 --- a/src/ui/ActiveScripts/ServerAccordions.tsx +++ b/src/ui/ActiveScripts/ServerAccordions.tsx @@ -22,7 +22,7 @@ interface IServerToScriptsMap { } type IProps = { - workerScripts: WorkerScript[]; + workerScripts: Map; }; type IState = { @@ -61,7 +61,7 @@ export class ServerAccordions extends React.Component { updateServerToScriptsMap(): void { const map: IServerToScriptsMap = {}; - for (const ws of this.props.workerScripts) { + for (const ws of this.props.workerScripts.values()) { const server = getServer(ws.serverIp); if (server == null) { console.warn(`WorkerScript has invalid IP address: ${ws.serverIp}`);