mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
MISC: Refactor implementation of ports (#2396)
This moves the implementation entirely into the PortHandle class, which makes the code a bit more streamlined and will allow for other port implementations in the future.
This commit is contained in:
@@ -26,7 +26,7 @@ import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions
|
||||
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { influenceStockThroughServerHack } from "../StockMarket/PlayerInfluencing";
|
||||
import { PortNumber } from "../NetscriptPort";
|
||||
import { type PortNumber, PortHandle } from "../NetscriptPort";
|
||||
import { FormulaGang } from "../Gang/formulas/formulas";
|
||||
import { GangMember } from "../Gang/GangMember";
|
||||
import { GangMemberTask } from "../Gang/GangMemberTask";
|
||||
@@ -88,7 +88,7 @@ export const helpers = {
|
||||
getServer,
|
||||
scriptIdentifier,
|
||||
hack,
|
||||
portNumber,
|
||||
portHandle,
|
||||
person,
|
||||
server,
|
||||
gang,
|
||||
@@ -611,7 +611,7 @@ function hack(ctx: NetscriptContext, hostname: string, manual: boolean, opts: un
|
||||
});
|
||||
}
|
||||
|
||||
function portNumber(ctx: NetscriptContext, _n: unknown): PortNumber {
|
||||
function portHandle(ctx: NetscriptContext, _n: unknown): PortHandle {
|
||||
const n = positiveInteger(ctx, "portNumber", _n);
|
||||
if (n > CONSTANTS.NumNetscriptPorts) {
|
||||
throw errorMessage(
|
||||
@@ -619,7 +619,7 @@ function portNumber(ctx: NetscriptContext, _n: unknown): PortNumber {
|
||||
`Trying to use an invalid port: ${n}. Must be less or equal to ${CONSTANTS.NumNetscriptPorts}.`,
|
||||
);
|
||||
}
|
||||
return n as PortNumber;
|
||||
return new PortHandle(n as PortNumber);
|
||||
}
|
||||
|
||||
function person(ctx: NetscriptContext, p: unknown): IPerson {
|
||||
|
||||
@@ -91,7 +91,6 @@ import { ScriptDeath } from "./Netscript/ScriptDeath";
|
||||
import { getBitNodeMultipliers } from "./BitNode/BitNode";
|
||||
import { assert, assertArray, assertString, assertObject } from "./utils/TypeAssertion";
|
||||
import { escapeRegExp } from "lodash";
|
||||
import { clearPort, peekPort, portHandle, readPort, tryWritePort, writePort, nextPortWrite } from "./NetscriptPort";
|
||||
import { FilePath, resolveFilePath } from "./Paths/FilePath";
|
||||
import { hasScriptExtension } from "./Paths/ScriptFilePath";
|
||||
import { hasTextExtension } from "./Paths/TextFilePath";
|
||||
@@ -1039,8 +1038,8 @@ export const ns: InternalAPI<NSFull> = {
|
||||
return helpers.getRunningScript(ctx, ident) !== null;
|
||||
},
|
||||
writePort: (ctx) => (_portNumber, data) => {
|
||||
const portNumber = helpers.portNumber(ctx, _portNumber);
|
||||
return writePort(portNumber, data);
|
||||
const portHandle = helpers.portHandle(ctx, _portNumber);
|
||||
return portHandle.write(data);
|
||||
},
|
||||
write: (ctx) => (_filename, _data, _mode) => {
|
||||
const filepath = helpers.filePath(ctx, "filename", _filename);
|
||||
@@ -1071,16 +1070,16 @@ export const ns: InternalAPI<NSFull> = {
|
||||
server.writeToTextFile(filepath, mode === "w" ? data : existingText + data);
|
||||
},
|
||||
tryWritePort: (ctx) => (_portNumber, data) => {
|
||||
const portNumber = helpers.portNumber(ctx, _portNumber);
|
||||
return tryWritePort(portNumber, data);
|
||||
const portHandle = helpers.portHandle(ctx, _portNumber);
|
||||
return portHandle.tryWrite(data);
|
||||
},
|
||||
nextPortWrite: (ctx) => (_portNumber) => {
|
||||
const portNumber = helpers.portNumber(ctx, _portNumber);
|
||||
return nextPortWrite(portNumber);
|
||||
const portHandle = helpers.portHandle(ctx, _portNumber);
|
||||
return portHandle.nextWrite();
|
||||
},
|
||||
readPort: (ctx) => (_portNumber) => {
|
||||
const portNumber = helpers.portNumber(ctx, _portNumber);
|
||||
return readPort(portNumber);
|
||||
const portHandle = helpers.portHandle(ctx, _portNumber);
|
||||
return portHandle.read();
|
||||
},
|
||||
read: (ctx) => (_filename) => {
|
||||
const path = helpers.filePath(ctx, "filename", _filename);
|
||||
@@ -1101,8 +1100,8 @@ export const ns: InternalAPI<NSFull> = {
|
||||
return contentFile.metadata.plain();
|
||||
},
|
||||
peek: (ctx) => (_portNumber) => {
|
||||
const portNumber = helpers.portNumber(ctx, _portNumber);
|
||||
return peekPort(portNumber);
|
||||
const portHandle = helpers.portHandle(ctx, _portNumber);
|
||||
return portHandle.peek();
|
||||
},
|
||||
clear: (ctx) => (_file) => {
|
||||
const path = helpers.filePath(ctx, "file", _file);
|
||||
@@ -1116,12 +1115,12 @@ export const ns: InternalAPI<NSFull> = {
|
||||
file.content = "";
|
||||
},
|
||||
clearPort: (ctx) => (_portNumber) => {
|
||||
const portNumber = helpers.portNumber(ctx, _portNumber);
|
||||
return clearPort(portNumber);
|
||||
const portHandle = helpers.portHandle(ctx, _portNumber);
|
||||
return portHandle.clear();
|
||||
},
|
||||
getPortHandle: (ctx) => (_portNumber) => {
|
||||
const portNumber = helpers.portNumber(ctx, _portNumber);
|
||||
return portHandle(portNumber);
|
||||
const portHandle = helpers.portHandle(ctx, _portNumber);
|
||||
return portHandle;
|
||||
},
|
||||
rm: (ctx) => (_fn, _host) => {
|
||||
const filepath = helpers.filePath(ctx, "fn", _fn);
|
||||
|
||||
@@ -23,10 +23,10 @@ export function getPort(n: PortNumber) {
|
||||
}
|
||||
|
||||
export class Port {
|
||||
data: any[] = [];
|
||||
data: unknown[] = [];
|
||||
resolver: Resolver | null = null;
|
||||
promise: Promise<void> | null = null;
|
||||
add(data: any) {
|
||||
add(data: unknown) {
|
||||
this.data.push(data);
|
||||
if (!this.resolver) return;
|
||||
this.resolver();
|
||||
@@ -35,71 +35,66 @@ export class Port {
|
||||
}
|
||||
}
|
||||
|
||||
export function portHandle(n: PortNumber): NetscriptPort {
|
||||
return {
|
||||
write: (value: unknown) => writePort(n, value),
|
||||
tryWrite: (value: unknown) => tryWritePort(n, value),
|
||||
read: () => readPort(n),
|
||||
peek: () => peekPort(n),
|
||||
nextWrite: () => nextPortWrite(n),
|
||||
full: () => isFullPort(n),
|
||||
empty: () => isEmptyPort(n),
|
||||
clear: () => clearPort(n),
|
||||
};
|
||||
}
|
||||
export class PortHandle implements NetscriptPort {
|
||||
n: PortNumber;
|
||||
|
||||
export function writePort(n: PortNumber, value: unknown): unknown {
|
||||
const port = getPort(n);
|
||||
// Primitives don't need to be cloned.
|
||||
port.add(isObjectLike(value) ? structuredClone(value) : value);
|
||||
if (port.data.length > Settings.MaxPortCapacity) return port.data.shift();
|
||||
return null;
|
||||
}
|
||||
constructor(n: PortNumber) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
export function tryWritePort(n: PortNumber, value: unknown): boolean {
|
||||
const port = getPort(n);
|
||||
if (port.data.length >= Settings.MaxPortCapacity) return false;
|
||||
// Primitives don't need to be cloned.
|
||||
port.add(isObjectLike(value) ? structuredClone(value) : value);
|
||||
return true;
|
||||
}
|
||||
write(value: unknown): unknown {
|
||||
const port = getPort(this.n);
|
||||
// Primitives don't need to be cloned.
|
||||
port.add(isObjectLike(value) ? structuredClone(value) : value);
|
||||
if (port.data.length > Settings.MaxPortCapacity) return port.data.shift();
|
||||
return null;
|
||||
}
|
||||
|
||||
export function readPort(n: PortNumber): unknown {
|
||||
const port = NetscriptPorts.get(n);
|
||||
if (!port || !port.data.length) return emptyPortData;
|
||||
const returnVal: unknown = port.data.shift();
|
||||
if (!port.data.length && !port.resolver) NetscriptPorts.delete(n);
|
||||
return returnVal;
|
||||
}
|
||||
tryWrite(value: unknown): boolean {
|
||||
const port = getPort(this.n);
|
||||
if (port.data.length >= Settings.MaxPortCapacity) return false;
|
||||
// Primitives don't need to be cloned.
|
||||
port.add(isObjectLike(value) ? structuredClone(value) : value);
|
||||
return true;
|
||||
}
|
||||
|
||||
export function peekPort(n: PortNumber): unknown {
|
||||
const port = NetscriptPorts.get(n);
|
||||
if (!port || !port.data.length) return emptyPortData;
|
||||
// Needed to avoid exposing internal objects.
|
||||
return isObjectLike(port.data[0]) ? structuredClone(port.data[0]) : port.data[0];
|
||||
}
|
||||
read(): unknown {
|
||||
const port = NetscriptPorts.get(this.n);
|
||||
if (!port || !port.data.length) return emptyPortData;
|
||||
const returnVal: unknown = port.data.shift();
|
||||
if (!port.data.length && !port.resolver) NetscriptPorts.delete(this.n);
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
export function nextPortWrite(n: PortNumber) {
|
||||
const port = getPort(n);
|
||||
if (!port.promise) port.promise = new Promise<void>((res) => (port.resolver = res));
|
||||
return port.promise;
|
||||
}
|
||||
peek(): unknown {
|
||||
const port = NetscriptPorts.get(this.n);
|
||||
if (!port || !port.data.length) return emptyPortData;
|
||||
// Needed to avoid exposing internal objects.
|
||||
return isObjectLike(port.data[0]) ? structuredClone(port.data[0]) : port.data[0];
|
||||
}
|
||||
|
||||
function isFullPort(n: PortNumber) {
|
||||
const port = NetscriptPorts.get(n);
|
||||
if (!port) return false;
|
||||
return port.data.length >= Settings.MaxPortCapacity;
|
||||
}
|
||||
nextWrite(): Promise<void> {
|
||||
const port = getPort(this.n);
|
||||
if (!port.promise) port.promise = new Promise<void>((res) => (port.resolver = res));
|
||||
return port.promise;
|
||||
}
|
||||
|
||||
function isEmptyPort(n: PortNumber) {
|
||||
const port = NetscriptPorts.get(n);
|
||||
if (!port) return true;
|
||||
return port.data.length === 0;
|
||||
}
|
||||
full(): boolean {
|
||||
const port = NetscriptPorts.get(this.n);
|
||||
if (!port) return false;
|
||||
return port.data.length >= Settings.MaxPortCapacity;
|
||||
}
|
||||
|
||||
export function clearPort(n: PortNumber) {
|
||||
const port = NetscriptPorts.get(n);
|
||||
if (!port) return;
|
||||
if (!port.resolver) NetscriptPorts.delete(n);
|
||||
port.data.length = 0;
|
||||
empty(): boolean {
|
||||
const port = NetscriptPorts.get(this.n);
|
||||
if (!port) return true;
|
||||
return port.data.length === 0;
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
const port = NetscriptPorts.get(this.n);
|
||||
if (!port) return;
|
||||
if (!port.resolver) NetscriptPorts.delete(this.n);
|
||||
port.data.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user