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