mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2025-01-11 07:47:33 +01:00
Improve event emitter
This commit is contained in:
parent
4b6a6300f5
commit
61e3959a25
@ -3,4 +3,4 @@
|
|||||||
*/
|
*/
|
||||||
import { EventEmitter } from "../utils/EventEmitter";
|
import { EventEmitter } from "../utils/EventEmitter";
|
||||||
|
|
||||||
export const WorkerScriptStartStopEventEmitter = new EventEmitter();
|
export const WorkerScriptStartStopEventEmitter = new EventEmitter<[]>();
|
||||||
|
@ -116,7 +116,7 @@ function removeWorkerScript(workerScript: WorkerScript, rerenderUi = true): void
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rerenderUi) {
|
if (rerenderUi) {
|
||||||
WorkerScriptStartStopEventEmitter.emitEvent();
|
WorkerScriptStartStopEventEmitter.emit();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error(`Invalid argument passed into removeWorkerScript():`);
|
console.error(`Invalid argument passed into removeWorkerScript():`);
|
||||||
|
@ -1359,7 +1359,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
for (let i = server.runningScripts.length - 1; i >= 0; --i) {
|
for (let i = server.runningScripts.length - 1; i >= 0; --i) {
|
||||||
killWorkerScript(server.runningScripts[i], server.ip, false);
|
killWorkerScript(server.runningScripts[i], server.ip, false);
|
||||||
}
|
}
|
||||||
WorkerScriptStartStopEventEmitter.emitEvent();
|
WorkerScriptStartStopEventEmitter.emit();
|
||||||
workerScript.log(
|
workerScript.log(
|
||||||
"killall",
|
"killall",
|
||||||
`Killing all scripts on '${server.hostname}'. May take a few minutes for the scripts to die.`,
|
`Killing all scripts on '${server.hostname}'. May take a few minutes for the scripts to die.`,
|
||||||
|
@ -45,7 +45,7 @@ export function prestigeWorkerScripts() {
|
|||||||
killWorkerScript(ws);
|
killWorkerScript(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkerScriptStartStopEventEmitter.emitEvent();
|
WorkerScriptStartStopEventEmitter.emit();
|
||||||
workerScripts.clear();
|
workerScripts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,7 +501,7 @@ export function createAndAddWorkerScript(runningScriptObj, server, parent) {
|
|||||||
|
|
||||||
// Add the WorkerScript to the global pool
|
// Add the WorkerScript to the global pool
|
||||||
workerScripts.set(pid, s);
|
workerScripts.set(pid, s);
|
||||||
WorkerScriptStartStopEventEmitter.emitEvent();
|
WorkerScriptStartStopEventEmitter.emit();
|
||||||
|
|
||||||
// Start the script's execution
|
// Start the script's execution
|
||||||
let p = null; // Script's resulting promise
|
let p = null; // Script's resulting promise
|
||||||
|
@ -311,4 +311,4 @@ export function initStockMarketFnForReact(): void {
|
|||||||
initSymbolToStockMap();
|
initSymbolToStockMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
export const eventEmitterForUiReset = new EventEmitter();
|
export const eventEmitterForUiReset = new EventEmitter<[]>();
|
||||||
|
@ -27,7 +27,7 @@ type IProps = {
|
|||||||
buyStockLong: txFn;
|
buyStockLong: txFn;
|
||||||
buyStockShort: txFn;
|
buyStockShort: txFn;
|
||||||
cancelOrder: (params: any) => void;
|
cancelOrder: (params: any) => void;
|
||||||
eventEmitterForReset?: EventEmitter;
|
eventEmitterForReset?: EventEmitter<[]>;
|
||||||
initStockMarket: () => void;
|
initStockMarket: () => void;
|
||||||
p: IPlayer;
|
p: IPlayer;
|
||||||
placeOrder: placeOrderFn;
|
placeOrder: placeOrderFn;
|
||||||
|
@ -31,7 +31,7 @@ type IProps = {
|
|||||||
buyStockLong: txFn;
|
buyStockLong: txFn;
|
||||||
buyStockShort: txFn;
|
buyStockShort: txFn;
|
||||||
cancelOrder: (params: any) => void;
|
cancelOrder: (params: any) => void;
|
||||||
eventEmitterForReset?: EventEmitter;
|
eventEmitterForReset?: EventEmitter<[]>;
|
||||||
p: IPlayer;
|
p: IPlayer;
|
||||||
placeOrder: placeOrderFn;
|
placeOrder: placeOrderFn;
|
||||||
sellStockLong: txFn;
|
sellStockLong: txFn;
|
||||||
|
@ -73,7 +73,6 @@ export interface ITerminal {
|
|||||||
executeCommand(router: IRouter, player: IPlayer, command: string): void;
|
executeCommand(router: IRouter, player: IPlayer, command: string): void;
|
||||||
executeCommands(router: IRouter, player: IPlayer, commands: string): void;
|
executeCommands(router: IRouter, player: IPlayer, commands: string): void;
|
||||||
// If there was any changes, will return true, once.
|
// If there was any changes, will return true, once.
|
||||||
pollChanges(): boolean;
|
|
||||||
process(router: IRouter, player: IPlayer, cycles: number): void;
|
process(router: IRouter, player: IPlayer, cycles: number): void;
|
||||||
prestige(): void;
|
prestige(): void;
|
||||||
getProgressText(): string;
|
getProgressText(): string;
|
||||||
|
@ -5,6 +5,7 @@ import { HacknetServer } from "../Hacknet/HacknetServer";
|
|||||||
import { BaseServer } from "../Server/BaseServer";
|
import { BaseServer } from "../Server/BaseServer";
|
||||||
import { Programs } from "../Programs/Programs";
|
import { Programs } from "../Programs/Programs";
|
||||||
import { CodingContractResult } from "../CodingContracts";
|
import { CodingContractResult } from "../CodingContracts";
|
||||||
|
import { TerminalEvents } from "./TerminalEvents";
|
||||||
|
|
||||||
import { TextFile } from "../TextFile";
|
import { TextFile } from "../TextFile";
|
||||||
import { Script } from "../Script/Script";
|
import { Script } from "../Script/Script";
|
||||||
@ -69,7 +70,6 @@ import { unalias } from "./commands/unalias";
|
|||||||
import { wget } from "./commands/wget";
|
import { wget } from "./commands/wget";
|
||||||
|
|
||||||
export class Terminal implements ITerminal {
|
export class Terminal implements ITerminal {
|
||||||
hasChanges = false;
|
|
||||||
// Flags to determine whether the player is currently running a hack or an analyze
|
// Flags to determine whether the player is currently running a hack or an analyze
|
||||||
action: TTimer | null = null;
|
action: TTimer | null = null;
|
||||||
|
|
||||||
@ -88,18 +88,10 @@ export class Terminal implements ITerminal {
|
|||||||
process(router: IRouter, player: IPlayer, cycles: number): void {
|
process(router: IRouter, player: IPlayer, cycles: number): void {
|
||||||
if (this.action === null) return;
|
if (this.action === null) return;
|
||||||
this.action.timeLeft -= (CONSTANTS._idleSpeed * cycles) / 1000;
|
this.action.timeLeft -= (CONSTANTS._idleSpeed * cycles) / 1000;
|
||||||
this.hasChanges = true;
|
TerminalEvents.emit();
|
||||||
if (this.action.timeLeft < 0) this.finishAction(router, player, false);
|
if (this.action.timeLeft < 0) this.finishAction(router, player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pollChanges(): boolean {
|
|
||||||
if (this.hasChanges) {
|
|
||||||
this.hasChanges = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
append(item: Output | Link): void {
|
append(item: Output | Link): void {
|
||||||
this.outputHistory.push(item);
|
this.outputHistory.push(item);
|
||||||
if (this.outputHistory.length > Settings.MaxTerminalCapacity) {
|
if (this.outputHistory.length > Settings.MaxTerminalCapacity) {
|
||||||
@ -109,12 +101,12 @@ export class Terminal implements ITerminal {
|
|||||||
|
|
||||||
print(s: string): void {
|
print(s: string): void {
|
||||||
this.append(new Output(s, "primary"));
|
this.append(new Output(s, "primary"));
|
||||||
this.hasChanges = true;
|
TerminalEvents.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
error(s: string): void {
|
error(s: string): void {
|
||||||
this.append(new Output(s, "error"));
|
this.append(new Output(s, "error"));
|
||||||
this.hasChanges = true;
|
TerminalEvents.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
startHack(player: IPlayer): void {
|
startHack(player: IPlayer): void {
|
||||||
@ -327,7 +319,7 @@ export class Terminal implements ITerminal {
|
|||||||
|
|
||||||
setcwd(dir: string): void {
|
setcwd(dir: string): void {
|
||||||
this.currDir = dir;
|
this.currDir = dir;
|
||||||
this.hasChanges = true;
|
TerminalEvents.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
async runContract(player: IPlayer, contractName: string): Promise<void> {
|
async runContract(player: IPlayer, contractName: string): Promise<void> {
|
||||||
@ -490,7 +482,7 @@ export class Terminal implements ITerminal {
|
|||||||
clear(): void {
|
clear(): void {
|
||||||
// TODO: remove this once we figure out the height issue.
|
// TODO: remove this once we figure out the height issue.
|
||||||
this.outputHistory = [new Output(`Bitburner v${CONSTANTS.Version}`, "primary")];
|
this.outputHistory = [new Output(`Bitburner v${CONSTANTS.Version}`, "primary")];
|
||||||
this.hasChanges = true;
|
TerminalEvents.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
prestige(): void {
|
prestige(): void {
|
||||||
|
2
src/Terminal/TerminalEvents.ts
Normal file
2
src/Terminal/TerminalEvents.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import { EventEmitter } from "../utils/EventEmitter";
|
||||||
|
export const TerminalEvents = new EventEmitter<[]>();
|
@ -9,6 +9,6 @@ export function killall(terminal: ITerminal, router: IRouter, player: IPlayer, s
|
|||||||
for (let i = server.runningScripts.length - 1; i >= 0; --i) {
|
for (let i = server.runningScripts.length - 1; i >= 0; --i) {
|
||||||
killWorkerScript(server.runningScripts[i], server.ip, false);
|
killWorkerScript(server.runningScripts[i], server.ip, false);
|
||||||
}
|
}
|
||||||
WorkerScriptStartStopEventEmitter.emitEvent();
|
WorkerScriptStartStopEventEmitter.emit();
|
||||||
terminal.print("Killing all running scripts");
|
terminal.print("Killing all running scripts");
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import { ITerminal, Output, Link } from "../ITerminal";
|
|||||||
import { IRouter } from "../../ui/Router";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { TerminalInput } from "./TerminalInput";
|
import { TerminalInput } from "./TerminalInput";
|
||||||
|
import { TerminalEvents } from "../TerminalEvents";
|
||||||
|
|
||||||
interface IActionTimerProps {
|
interface IActionTimerProps {
|
||||||
terminal: ITerminal;
|
terminal: ITerminal;
|
||||||
@ -55,10 +56,7 @@ export function TerminalRoot({ terminal, router, player }: IProps): React.ReactE
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const id = setInterval(() => {
|
return TerminalEvents.subscribe(rerender);
|
||||||
if (terminal.pollChanges()) rerender();
|
|
||||||
}, 100);
|
|
||||||
return () => clearInterval(id);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
function doScroll(): void {
|
function doScroll(): void {
|
||||||
|
@ -49,11 +49,7 @@ export function ServerAccordions(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
WorkerScriptStartStopEventEmitter.addSubscriber({
|
return WorkerScriptStartStopEventEmitter.subscribe(rerender);
|
||||||
cb: rerender,
|
|
||||||
id: subscriberId,
|
|
||||||
});
|
|
||||||
return () => WorkerScriptStartStopEventEmitter.removeSubscriber(subscriberId);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleChangePage = (event: unknown, newPage: number) => {
|
const handleChangePage = (event: unknown, newPage: number) => {
|
||||||
|
@ -7,7 +7,7 @@ import * as React from "react";
|
|||||||
import { EventEmitter } from "../../utils/EventEmitter";
|
import { EventEmitter } from "../../utils/EventEmitter";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
eventEmitterForReset?: EventEmitter;
|
eventEmitterForReset?: EventEmitter<[]>;
|
||||||
id?: string;
|
id?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ const styleMarkup = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class ErrorBoundary extends React.Component<IProps, IState> {
|
export class ErrorBoundary extends React.Component<IProps, IState> {
|
||||||
|
unsubscribe: (() => void) | null = null;
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
@ -50,16 +51,13 @@ export class ErrorBoundary extends React.Component<IProps, IState> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (this.hasEventEmitter()) {
|
if (this.hasEventEmitter()) {
|
||||||
(this.props.eventEmitterForReset as EventEmitter).addSubscriber({
|
this.unsubscribe = (this.props.eventEmitterForReset as EventEmitter<[]>).subscribe(cb);
|
||||||
cb: cb,
|
|
||||||
id: this.props.id as string,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount(): void {
|
componentWillUnmount(): void {
|
||||||
if (this.hasEventEmitter()) {
|
if (this.unsubscribe !== null) {
|
||||||
(this.props.eventEmitterForReset as EventEmitter).removeSubscriber(this.props.id as string);
|
this.unsubscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,33 +17,33 @@ export interface ISubscriber {
|
|||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EventEmitter {
|
function uuidv4(): string {
|
||||||
/**
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
||||||
* Map of Subscriber name -> Callback function
|
var r = (Math.random() * 16) | 0,
|
||||||
*/
|
v = c == "x" ? r : (r & 0x3) | 0x8;
|
||||||
subscribers: IMap<cbFn> = {};
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
constructor(subs?: ISubscriber[]) {
|
export class EventEmitter<T extends any[]> {
|
||||||
if (Array.isArray(subs)) {
|
subscribers: { [key: string]: (...args: [...T]) => void | undefined } = {};
|
||||||
for (const s of subs) {
|
|
||||||
this.addSubscriber(s);
|
subscribe(s: (...args: [...T]) => void): () => void {
|
||||||
}
|
let uuid = uuidv4();
|
||||||
}
|
while (this.subscribers[uuid] !== undefined) uuid = uuidv4();
|
||||||
|
this.subscribers[uuid] = s;
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
delete this.subscribers[uuid];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
addSubscriber(s: ISubscriber): void {
|
emit(...args: [...T]): void {
|
||||||
this.subscribers[s.id] = s.cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
emitEvent(...args: any[]): void {
|
|
||||||
for (const s in this.subscribers) {
|
for (const s in this.subscribers) {
|
||||||
const sub = this.subscribers[s];
|
const sub = this.subscribers[s];
|
||||||
|
if (sub === undefined) continue;
|
||||||
|
|
||||||
sub(args);
|
sub(...args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeSubscriber(id: string): void {
|
|
||||||
delete this.subscribers[id];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user