diff --git a/Source/Features/Common/InWorldPanels.h b/Source/Features/Common/InWorldPanels.h index 0fefe3215a8..7c96d7a6c69 100644 --- a/Source/Features/Common/InWorldPanels.h +++ b/Source/Features/Common/InWorldPanels.h @@ -20,11 +20,19 @@ class InWorldPanels { { } + void updateState() const noexcept + { + if (!containerPanelExists()) { + hookContext.template make().clear(); + state().reset(); + } + } + [[nodiscard]] decltype(auto) getNextPlayerInfoPanel() const noexcept { if (auto&& existingPanel = getNextExistingPanel(state().playerInfoPanelListHead, perHookState().lastUsedPlayerInfoPanelIndex)) return existingPanel.template as(hookContext.template make().nextEntry()); - auto&& newPanel = createPlayerInfoPanel(containerPanel()); + auto&& newPanel = createPlayerInfoPanel(getOrCreateContainerPanel()); registerNewPanel(state().playerInfoPanelListHead, perHookState().lastUsedPlayerInfoPanelIndex); hookContext.template make().allocateNewEntry(); return newPanel.template as(hookContext.template make().nextEntry()); @@ -35,7 +43,7 @@ class InWorldPanels { { if (auto&& existingPanel = getNextExistingPanel(state().soundVisualizationPanelListHeads[SoundVisualizationPanelTypes::indexOf()], perHookState().lastUsedSoundVisualizationPanelIndexes[SoundVisualizationPanelTypes::indexOf()])) return utils::lvalue(existingPanel); - auto&& newPanel = createSoundVisualizationPanel(containerPanel()); + auto&& newPanel = createSoundVisualizationPanel(getOrCreateContainerPanel()); registerNewPanel(state().soundVisualizationPanelListHeads[SoundVisualizationPanelTypes::indexOf()], perHookState().lastUsedSoundVisualizationPanelIndexes[SoundVisualizationPanelTypes::indexOf()]); return utils::lvalue(newPanel); } @@ -68,7 +76,7 @@ class InWorldPanels { for (auto index = firstIndex; index.isValid(); index = state().panelList[index.value].indexOfNextPanelOfSameType()) { if (state().panelList[index.value].isPanelActive()) { state().panelList[index.value].markPanelInactive(); - deactivatePanel(containerPanel().children()[index.value]); + deactivatePanel(getContainerPanel().children()[index.value]); } } } @@ -107,7 +115,7 @@ class InWorldPanels { if (nextIndex.isValid()) { lastUsedPanelIndex = nextIndex; auto& nextPanelEntry = state().panelList[nextIndex.value]; - auto&& panel = containerPanel().children()[nextIndex.value]; + auto&& panel = getContainerPanel().children()[nextIndex.value]; if (!nextPanelEntry.isPanelActive()) { activatePanel(panel); nextPanelEntry.markPanelActive(); @@ -137,20 +145,29 @@ class InWorldPanels { return hookContext.inWorldPanelsState(); } - [[nodiscard]] auto containerPanel() const noexcept + [[nodiscard]] decltype(auto) getOrCreateContainerPanel() const noexcept + { + return containerPanelHandle().getOrInit(createContainerPanel()); + } + + [[nodiscard]] decltype(auto) getContainerPanel() const noexcept { - return handle().getOrInit(createContainerPanel()); + return containerPanelHandle().get(); } - [[nodiscard]] decltype(auto) handle() const noexcept + [[nodiscard]] decltype(auto) containerPanelHandle() const noexcept { return hookContext.template make(state().containerPanelHandle); } + [[nodiscard]] bool containerPanelExists() const noexcept + { + return containerPanelHandle().panelExists(); + } + [[nodiscard]] auto createContainerPanel() const noexcept { return [this] { - state().onContainerPanelCreation(); auto&& panel = hookContext.panelFactory().createPanel(hookContext.hud().getHudReticle()).uiPanel(); panel.fitParent(); return panel; diff --git a/Source/Features/Common/InWorldPanelsState.h b/Source/Features/Common/InWorldPanelsState.h index e15cfa6f086..0c5c279655e 100644 --- a/Source/Features/Common/InWorldPanelsState.h +++ b/Source/Features/Common/InWorldPanelsState.h @@ -13,8 +13,9 @@ struct InWorldPanelsState { InWorldPanelIndex playerInfoPanelListHead{}; std::array soundVisualizationPanelListHeads{}; - void onContainerPanelCreation() noexcept + void reset() noexcept { + containerPanelHandle = {}; panelList.clear(); playerInfoPanelListHead = {}; soundVisualizationPanelListHeads = {}; diff --git a/Source/GameClasses/PanelHandle.h b/Source/GameClasses/PanelHandle.h index 537fd3c3aac..24f67f0013a 100644 --- a/Source/GameClasses/PanelHandle.h +++ b/Source/GameClasses/PanelHandle.h @@ -13,10 +13,15 @@ struct PanelHandle { { } + [[nodiscard]] decltype(auto) get() noexcept + { + return hookContext.template make().getPanelFromHandle(std::as_const(handle)); + } + template [[nodiscard]] decltype(auto) getOrInit(F&& f) noexcept { - if (auto&& panel = hookContext.template make().getPanelFromHandle(std::as_const(handle))) + if (auto&& panel = get()) return utils::lvalue(panel); auto&& panel = std::forward(f)(); @@ -24,6 +29,11 @@ struct PanelHandle { return utils::lvalue(panel); } + [[nodiscard]] bool panelExists() noexcept + { + return handle.isValid() && static_cast(get()); + } + private: HookContext& hookContext; cs2::PanelHandle& handle; diff --git a/Source/GlobalContext/GlobalContext.h b/Source/GlobalContext/GlobalContext.h index ab6598c24e5..82b7b22f445 100644 --- a/Source/GlobalContext/GlobalContext.h +++ b/Source/GlobalContext/GlobalContext.h @@ -98,6 +98,7 @@ class GlobalContext { { HookDependencies dependencies{fullContext()}; fullContext().hooks.viewRenderHook.getOriginalOnRenderStart()(viewRender); + dependencies.make().updateState(); SoundWatcher soundWatcher{fullContext().soundWatcherState, dependencies}; soundWatcher.update(); fullContext().features(dependencies).soundFeatures().runOnViewMatrixUpdate();