sync overview updates

Using EventEmitter. Also get rid of ShownContext as it is no longer needed with this event based rerender.
This commit is contained in:
omuretsu 2023-01-02 08:54:18 -05:00
parent 90fc82b86f
commit d00ed1f4ee

@ -1,5 +1,5 @@
// Root React Component for the Corporation UI
import React, { useMemo, useState, useEffect, createContext, useContext } from "react";
import React, { useMemo, useState, useEffect } from "react";
import { Theme, useTheme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
@ -40,10 +40,11 @@ import { ActionIdentifier } from "../../Bladeburner/ActionIdentifier";
import { Bladeburner } from "../../Bladeburner/Bladeburner";
import { Skills } from "../../PersonObjects/Skills";
import { calculateSkillProgress } from "../../PersonObjects/formulas/skill";
import { EventEmitter } from "../../utils/EventEmitter";
type SkillRowName = "Hack" | "Str" | "Def" | "Dex" | "Agi" | "Cha" | "Int";
type RowName = SkillRowName | "HP" | "Money";
const ShownContext = createContext(true); //Context for whether to update components
const OverviewEventEmitter = new EventEmitter();
// These values aren't displayed, they're just used for comparison to check if state has changed
const valUpdaters: Record<RowName, () => any> = {
@ -97,17 +98,15 @@ interface SkillBarProps {
color?: string;
}
function SkillBar({ name, color }: SkillBarProps): React.ReactElement {
const shown = useContext(ShownContext);
const [mult, setMult] = useState(skillMultUpdaters[name]?.());
const [progress, setProgress] = useState(calculateSkillProgress(Player.exp[skillNameMap[name]], mult));
useEffect(() => {
if (!shown) return;
const interval = setInterval(() => {
const clearSubscription = OverviewEventEmitter.subscribe(() => {
setMult(skillMultUpdaters[name]());
setProgress(calculateSkillProgress(Player.exp[skillNameMap[name] as keyof Skills], mult));
}, 600);
return () => clearInterval(interval);
}, [shown]);
});
return clearSubscription;
}, []);
return (
<TableRow>
<StatsProgressOverviewCell progress={progress} color={color} />
@ -122,12 +121,10 @@ interface ValProps {
export function Val({ name, color }: ValProps): React.ReactElement {
//val isn't actually used here, the update of val just forces a refresh of the formattedVal that gets shown
const setVal = useState(valUpdaters[name]())[1];
const shown = useContext(ShownContext);
useEffect(() => {
if (!shown) return;
const interval = setInterval(() => setVal(valUpdaters[name]()), 600);
return () => clearInterval(interval);
}, [shown]);
const clearSubscription = OverviewEventEmitter.subscribe(() => setVal(valUpdaters[name]()));
return clearSubscription;
}, []);
return <Typography color={color}>{formattedVals[name]()}</Typography>;
}
@ -172,17 +169,18 @@ export function CharacterOverview({ parentOpen, save, killScripts }: OverviewPro
const [hasIntelligence, setHasIntelligence] = useState(Player.skills.intelligence > 0);
const [showBars, setShowBars] = useState(!Settings.DisableOverviewProgressBars);
useEffect(() => {
if (!parentOpen) return; // No rerendering if overview is hidden, for performance
const interval = setInterval(() => {
//Todo: Consider making these event-based instead of requiring interval polling?
setHasIntelligence(Player.skills.intelligence > 0);
setShowBars(!Settings.DisableOverviewProgressBars);
}, 1000);
OverviewEventEmitter.emit(); // Tell every other updating component to update as well
}, 600);
return () => clearInterval(interval);
}, []);
}, [parentOpen]);
const classes = useStyles();
const theme = useTheme();
return (
<ShownContext.Provider value={parentOpen}>
<>
<Table sx={{ display: "block", m: 1 }}>
<TableBody>
<DataRow name="HP" showBar={false} color={theme.colors.hp} cellType={"cellNone"} />
@ -236,7 +234,7 @@ export function CharacterOverview({ parentOpen, save, killScripts }: OverviewPro
</Box>
</Box>
<KillScriptsModal open={killOpen} onClose={() => setKillOpen(false)} killScripts={killScripts} />
</ShownContext.Provider>
</>
);
}
@ -251,14 +249,12 @@ function ActionText(props: { action: ActionIdentifier }): React.ReactElement {
}
function BladeburnerText(): React.ReactElement {
const shown = useContext(ShownContext);
const classes = useStyles();
const setRerender = useState(false)[1];
useEffect(() => {
if (!shown) return;
const interval = setInterval(() => setRerender((old) => !old), 600);
return () => clearInterval(interval);
}, [shown]);
const clearSubscription = OverviewEventEmitter.subscribe(() => setRerender((old) => !old));
return clearSubscription;
}, []);
const action = Player.bladeburner?.action;
return useMemo(
@ -330,13 +326,11 @@ function WorkInProgressOverview({ tooltip, children, header }: WorkInProgressOve
}
function Work(): React.ReactElement {
const shown = useContext(ShownContext);
const setRerender = useState(false)[1];
useEffect(() => {
if (!shown) return;
const interval = setInterval(() => setRerender((old) => !old), 600);
return () => clearInterval(interval);
}, [shown]);
const clearSubscription = OverviewEventEmitter.subscribe(() => setRerender((old) => !old));
return clearSubscription;
}, []);
if (Player.currentWork === null || Player.focus) return <></>;