#pragma once #include #include #include #include #include #include #include #include namespace blitz { namespace client { class AbstractState : public Nz::State, public std::enable_shared_from_this { public: AbstractState(std::shared_ptr stateData); ~AbstractState(); protected: template void ConnectSignal(T& signal, Args&&... args) { m_CleanupFunctions.emplace_back( [connection = signal.Connect(std::forward(args)...)]() mutable { connection.Disconnect(); }); } template T* CreateWidget(Args&&... args) { T* widget = m_StateData->m_Canvas->Add(std::forward(args)...); auto& entry = m_Widgets.emplace_back(); entry.m_Widget = widget; if (!m_IsVisible) entry.m_Widget->Hide(); return widget; } void DestroyWidget(Nz::BaseWidget* widget); StateData& GetStateData() { return *m_StateData; } const StateData& GetStateData() const { return *m_StateData; } const std::shared_ptr& GetStateDataPtr() { return m_StateData; } void Enter(Nz::StateMachine& fsm) override; void Leave(Nz::StateMachine& fsm) override; bool Update(Nz::StateMachine& fsm, Nz::Time elapsedTime) override; virtual void LayoutWidgets() {} private: NazaraSlot(Nz::RenderTarget, OnRenderTargetSizeChange, m_OnTargetChangeSizeSlot); struct WidgetEntry { Nz::BaseWidget* m_Widget; bool m_WasVisible = true; }; std::shared_ptr m_StateData; std::vector> m_CleanupFunctions; std::vector m_Widgets; bool m_IsVisible; }; } // namespace client } // namespace blitz