diff --git a/markdown/bitburner.basichgwoptions.md b/markdown/bitburner.basichgwoptions.md index 3e96423ec..b7f2f0e2c 100644 --- a/markdown/bitburner.basichgwoptions.md +++ b/markdown/bitburner.basichgwoptions.md @@ -18,5 +18,5 @@ interface BasicHGWOptions | --- | --- | --- | --- | | [additionalMsec?](./bitburner.basichgwoptions.additionalmsec.md) | | number | _(Optional)_ Number of additional milliseconds that will be spent waiting between the start of the function and when it completes. | | [stock?](./bitburner.basichgwoptions.stock.md) | | boolean | _(Optional)_ Set to true this action will affect the stock market. | -| [threads?](./bitburner.basichgwoptions.threads.md) | | number | _(Optional)_ Number of threads to use for this function. Must be less than or equal to the number of threads the script is running with. | +| [threads?](./bitburner.basichgwoptions.threads.md) | | number | _(Optional)_ Number of threads to use for this function. Must be less than or equal to the number of threads the script is running with. Accepts positive non integer values. | diff --git a/markdown/bitburner.basichgwoptions.threads.md b/markdown/bitburner.basichgwoptions.threads.md index 930148b66..46a37760c 100644 --- a/markdown/bitburner.basichgwoptions.threads.md +++ b/markdown/bitburner.basichgwoptions.threads.md @@ -4,7 +4,7 @@ ## BasicHGWOptions.threads property -Number of threads to use for this function. Must be less than or equal to the number of threads the script is running with. +Number of threads to use for this function. Must be less than or equal to the number of threads the script is running with. Accepts positive non integer values. **Signature:** diff --git a/src/Netscript/NetscriptHelpers.tsx b/src/Netscript/NetscriptHelpers.tsx index 652fc3f25..b20f5a6b6 100644 --- a/src/Netscript/NetscriptHelpers.tsx +++ b/src/Netscript/NetscriptHelpers.tsx @@ -33,7 +33,7 @@ import { HacknetServer } from "../Hacknet/HacknetServer"; import { BaseServer } from "../Server/BaseServer"; import { dialogBoxCreate } from "../ui/React/DialogBox"; import { RamCostConstants } from "./RamCostGenerator"; -import { isPositiveInteger, PositiveInteger, Unknownify } from "../types"; +import { isPositiveInteger, PositiveInteger, Unknownify, isPositiveNumber, PositiveNumber } from "../types"; import { Engine } from "../engine"; import { resolveFilePath, FilePath } from "../Paths/FilePath"; import { hasScriptExtension, ScriptFilePath } from "../Paths/ScriptFilePath"; @@ -87,7 +87,7 @@ export interface CompleteSpawnOptions extends CompleteRunOptions { } /** HGWOptions with non-optional, type-validated members, for passing between internal functions. */ export interface CompleteHGWOptions { - threads: PositiveInteger; + threads: PositiveNumber; stock: boolean; additionalMsec: number; } @@ -146,7 +146,14 @@ function positiveInteger(ctx: NetscriptContext, argName: string, v: unknown): Po } return n; } - +/** Convert provided value v for argument argName to a positive number, throwing if it looks like something else. */ +function positiveNumber(ctx: NetscriptContext, argName: string, v: unknown): PositiveNumber { + const n = number(ctx, argName, v); + if (!isPositiveNumber(n)) { + throw makeRuntimeErrorMsg(ctx, `${argName} should be a positive number, was ${n}`, "TYPE"); + } + return n; +} /** Returns args back if it is a ScriptArg[]. Throws an error if it is not. */ function scriptArgs(ctx: NetscriptContext, args: unknown) { if (!isScriptArgs(args)) throw makeRuntimeErrorMsg(ctx, "'args' is not an array of script args", "TYPE"); @@ -322,7 +329,7 @@ function validateHGWOptions(ctx: NetscriptContext, opts: unknown): CompleteHGWOp if (!requestedThreads) { result.threads = (isNaN(threads) || threads < 1 ? 1 : threads) as PositiveInteger; } else { - const positiveThreads = positiveInteger(ctx, "opts.threads", requestedThreads); + const positiveThreads = positiveNumber(ctx, "opts.threads", requestedThreads); if (positiveThreads > threads) { throw makeRuntimeErrorMsg( ctx, diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 3387c9757..99c2692a3 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -345,7 +345,9 @@ interface CrimeStats { */ interface BasicHGWOptions { /** Number of threads to use for this function. - * Must be less than or equal to the number of threads the script is running with. */ + * Must be less than or equal to the number of threads the script is running with. + * Accepts positive non integer values. + */ threads?: number; /** Set to true this action will affect the stock market. */ stock?: boolean; diff --git a/src/types.ts b/src/types.ts index 78b5192c1..e6d60d170 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,12 +1,17 @@ // The object properties on these numeric types are for typechecking only and do not exist at runtime. They're just a way to require a typechecking function. export type Integer = number & { __Integer: true }; +export type SafeInteger = Integer & { __isSafe: true }; export type PositiveNumber = number & { __Positive: true }; export type PositiveInteger = Integer & PositiveNumber; +export type PositiveSafeInteger = PositiveInteger & SafeInteger; // Numeric typechecking functions - these should be moved somewhere else +export const isNumber = (n: unknown): n is number => !Number.isNaN(Number(n)); export const isInteger = (n: unknown): n is Integer => Number.isInteger(n); +export const isSafeInteger = (n: unknown): n is SafeInteger => Number.isSafeInteger(n); export const isPositiveInteger = (n: unknown): n is PositiveInteger => isInteger(n) && n > 0; - +export const isPositiveNumber = (n: unknown): n is PositiveNumber => isNumber(n) && n > 0; +export const isPositiveSafeInteger = (n: unknown): n is PositiveSafeInteger => isSafeInteger(n) && isPositiveInteger(n); /** Utility type for typechecking objects. Makes all keys optional and sets values to unknown, * making it safe to assert a shape for the variable once it's known to be a non-null object */ export type Unknownify = {