mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-09 17:23:53 +01:00
API: make ns.atExit add the callback to an array instead of setting it (#1059)
This commit is contained in:
parent
4f4c6fe7e5
commit
4aaf845fca
@ -9,7 +9,7 @@ Add callback function when the script dies
|
|||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
atExit(f: () => void): void;
|
atExit(f: () => void, id?: string): void;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -17,6 +17,7 @@ atExit(f: () => void): void;
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| f | () => void | |
|
| f | () => void | |
|
||||||
|
| id | string | _(Optional)_ |
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ export async function main(ns) {
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| [alert(msg)](./bitburner.ns.alert.md) | Open up a message box. |
|
| [alert(msg)](./bitburner.ns.alert.md) | Open up a message box. |
|
||||||
| [asleep(millis)](./bitburner.ns.asleep.md) | Suspends the script for n milliseconds. Doesn't block with concurrent calls. |
|
| [asleep(millis)](./bitburner.ns.asleep.md) | Suspends the script for n milliseconds. Doesn't block with concurrent calls. |
|
||||||
| [atExit(f)](./bitburner.ns.atexit.md) | Add callback function when the script dies |
|
| [atExit(f, id)](./bitburner.ns.atexit.md) | Add callback function when the script dies |
|
||||||
| [brutessh(host)](./bitburner.ns.brutessh.md) | Runs BruteSSH.exe on a server. |
|
| [brutessh(host)](./bitburner.ns.brutessh.md) | Runs BruteSSH.exe on a server. |
|
||||||
| [clear(handle)](./bitburner.ns.clear.md) | Clear data from a file. |
|
| [clear(handle)](./bitburner.ns.clear.md) | Clear data from a file. |
|
||||||
| [clearLog()](./bitburner.ns.clearlog.md) | Clears the script’s logs. |
|
| [clearLog()](./bitburner.ns.clearlog.md) | Clears the script’s logs. |
|
||||||
|
@ -78,8 +78,8 @@ export class WorkerScript {
|
|||||||
/** hostname on which this script is running */
|
/** hostname on which this script is running */
|
||||||
hostname: string;
|
hostname: string;
|
||||||
|
|
||||||
/** Function called when the script ends. */
|
/**Map of functions called when the script ends. */
|
||||||
atExit: (() => void) | undefined = undefined;
|
atExit: Map<string, () => void> = new Map();
|
||||||
|
|
||||||
constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => NSFull) {
|
constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => NSFull) {
|
||||||
this.name = runningScriptObj.filename;
|
this.name = runningScriptObj.filename;
|
||||||
|
@ -42,20 +42,25 @@ function stopAndCleanUpWorkerScript(ws: WorkerScript): void {
|
|||||||
if (ws.delay) clearTimeout(ws.delay);
|
if (ws.delay) clearTimeout(ws.delay);
|
||||||
ws.delayReject?.(new ScriptDeath(ws));
|
ws.delayReject?.(new ScriptDeath(ws));
|
||||||
ws.env.runningFn = "";
|
ws.env.runningFn = "";
|
||||||
|
|
||||||
if (typeof ws.atExit === "function") {
|
|
||||||
try {
|
|
||||||
const atExit = ws.atExit;
|
const atExit = ws.atExit;
|
||||||
ws.atExit = undefined;
|
//Calling ns.exit inside ns.atExit can lead to recursion
|
||||||
atExit();
|
//so the map must be cleared before looping
|
||||||
|
ws.atExit = new Map();
|
||||||
|
|
||||||
|
for (const key of atExit.keys()) {
|
||||||
|
try {
|
||||||
|
const callback = atExit.get(key);
|
||||||
|
if (typeof callback == "function") callback();
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
handleUnknownError(e, ws, "Error running atExit function.\n\n");
|
handleUnknownError(e, ws, "Error running atExit function.\n\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ws.env.stopFlag) {
|
if (ws.env.stopFlag) {
|
||||||
// If atExit() kills the script, we'll already be stopped, don't stop again.
|
// If atExit() kills the script, we'll already be stopped, don't stop again.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ws.env.stopFlag = true;
|
ws.env.stopFlag = true;
|
||||||
removeWorkerScript(ws);
|
removeWorkerScript(ws);
|
||||||
}
|
}
|
||||||
|
@ -1708,13 +1708,20 @@ export const ns: InternalAPI<NSFull> = {
|
|||||||
sinceInstall: Object.assign({}, Player.moneySourceA),
|
sinceInstall: Object.assign({}, Player.moneySourceA),
|
||||||
sinceStart: Object.assign({}, Player.moneySourceB),
|
sinceStart: Object.assign({}, Player.moneySourceB),
|
||||||
}),
|
}),
|
||||||
atExit: (ctx) => (f) => {
|
atExit:
|
||||||
|
(ctx) =>
|
||||||
|
(f, id = "default") => {
|
||||||
if (typeof f !== "function") {
|
if (typeof f !== "function") {
|
||||||
throw helpers.errorMessage(ctx, "argument should be function");
|
throw helpers.errorMessage(ctx, "argument should be function");
|
||||||
}
|
}
|
||||||
ctx.workerScript.atExit = () => {
|
|
||||||
|
if (typeof id !== "string") {
|
||||||
|
throw helpers.errorMessage(ctx, "id should be a string");
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.workerScript.atExit.set(id, () => {
|
||||||
f();
|
f();
|
||||||
}; // Wrap the user function to prevent WorkerScript leaking as 'this'
|
}); // Wrap the user function to prevent WorkerScript leaking as 'this'
|
||||||
},
|
},
|
||||||
mv: (ctx) => (_host, _source, _destination) => {
|
mv: (ctx) => (_host, _source, _destination) => {
|
||||||
const hostname = helpers.string(ctx, "host", _host);
|
const hostname = helpers.string(ctx, "host", _host);
|
||||||
|
2
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
2
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -7246,7 +7246,7 @@ export interface NS {
|
|||||||
*
|
*
|
||||||
* Add callback to be executed when the script dies.
|
* Add callback to be executed when the script dies.
|
||||||
*/
|
*/
|
||||||
atExit(f: () => void): void;
|
atExit(f: () => void, id?: string): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move a file on the target server.
|
* Move a file on the target server.
|
||||||
|
@ -105,7 +105,10 @@ test.each([
|
|||||||
// await script death.
|
// await script death.
|
||||||
const ws = workerScripts.get(pid);
|
const ws = workerScripts.get(pid);
|
||||||
expect(ws).toBeDefined();
|
expect(ws).toBeDefined();
|
||||||
const result = await Promise.race([alerted, new Promise((resolve) => (ws.atExit = resolve))]);
|
const result = await Promise.race([
|
||||||
|
alerted,
|
||||||
|
new Promise<void>((resolve) => (ws!.atExit = new Map([["default", resolve]]))),
|
||||||
|
]);
|
||||||
// If an error alert was thrown, we catch it here.
|
// If an error alert was thrown, we catch it here.
|
||||||
expect(result).not.toBeDefined();
|
expect(result).not.toBeDefined();
|
||||||
expect(runningScript.logs).toEqual(expectedLog);
|
expect(runningScript.logs).toEqual(expectedLog);
|
||||||
|
Loading…
Reference in New Issue
Block a user