Loading...
Searching...
No Matches
AppManager.h
Go to the documentation of this file.
1// Copyright (c) 2025 Dave R. Smith.
2// Malena Framework — Licensed under PolyForm Noncommercial 1.0.0; commercial use requires a paid license. See LICENSE.
3
4//
5// Created by Dave R. Smith on 3/5/25.
6//
7
8#ifndef MALENA_APPMANAGER_H
9#define MALENA_APPMANAGER_H
10
11#pragma once
12
16#include <SFML/Graphics.hpp>
17#include <functional>
18#include <optional>
19#include <string>
20#include <cstdint>
21
23
24namespace ml
25{
107 class MALENA_API AppManager : public Lifecycle, public CoreManager<Core>
108 {
109 public:
117 {
121 };
122
123 private:
124 sf::RenderWindow* window = nullptr;
125
126 Architecture _architecture;
127 sf::Color _clearColor { sf::Color::Black };
128 sf::Clock _clock;
129 bool _paused { false };
130
131 // Stored for window recreation (setWindowStyle)
132 sf::VideoMode _videoMode;
133 std::string _title;
134 std::uint32_t _windowStyle;
135 unsigned int _framerateLimit { 60 };
136
137 std::function<void()> _preRenderHook;
138 std::function<void()> _postRenderHook;
139 std::function<bool()> _closeHandler;
140 std::function<bool(const sf::Event&)> _eventHandler;
141 std::function<void(unsigned int, unsigned int)> _resizeHandler;
142
144 inline static bool _isDrawing = false;
145 inline static float _deltaTime = 0.f;
146 inline static AppManager* _instance = nullptr;
147 inline static Core* _exclusiveOwner = nullptr;
148 inline static Core* _activePopup = nullptr;
149 inline static std::vector<std::function<void()>> _deferredUnloads;
151
152 public:
169 AppManager(const sf::VideoMode& videoMode,
170 const std::string& title,
172 Architecture architecture = MVC,
173 std::uint32_t windowStyle = sf::Style::Default);
174
188 void run();
189
190 virtual ~AppManager() = default;
191
192 // ── Window appearance ─────────────────────────────────────────────────
193
200
206 void setTitle(const std::string& title);
207
213 void setIcon(const sf::Image& icon);
214
221 void setWindowPosition(int x, int y);
222
233 void setWindowStyle(std::uint32_t style);
234
235 // ── Timing ────────────────────────────────────────────────────────────
236
244 void setFramerateLimit(unsigned int limit);
245
251 void setVSync(bool enabled);
252
259 static float getDeltaTime() { return _deltaTime; }
260
261 // ── Pause / resume ────────────────────────────────────────────────────
262
270 void pause();
271
273 void resume();
274
276 bool isPaused() const { return _paused; }
277
278 // ── Lifecycle hooks ───────────────────────────────────────────────────
279
288 void onPreRender(std::function<void()> hook);
289
298 void onPostRender(std::function<void()> hook);
299
307 void onClose(std::function<bool()> handler);
308
320 void onEvent(std::function<bool(const sf::Event&)> handler);
321
327 void onResize(std::function<void(unsigned int, unsigned int)> handler);
328
329 // ── Architecture ──────────────────────────────────────────────────────
330
332 Architecture getArchitecture() const { return _architecture; }
333
334 // ── Exclusive interaction ─────────────────────────────────────────────
335
339 static void setExclusiveOwner(Core* owner);
340
342 static void clearExclusiveOwner();
343
345 static Core* exclusiveOwner() { return _exclusiveOwner; }
346
347 // ── Top popup layer ───────────────────────────────────────────────────
348
354 static void setActivePopup(Core* popup) { _activePopup = popup; }
355
357 static Core* activePopup() { return _activePopup; }
358
360 static void clearActivePopup() { _activePopup = nullptr; }
361
362 // ── Internal ──────────────────────────────────────────────────────────
363
365 static bool isDrawing() { return _isDrawing; }
366
367 static bool isUnderExclusiveOwner(Core* component);
368
369 static void deferUnload(std::function<void()> op)
370 {
371 _deferredUnloads.push_back(std::move(op));
372 }
373
381 static AppManager& get() { return *_instance; }
383
384 private:
385 void fireInputEvents(const std::optional<sf::Event>& event);
386 void fireUpdateEvents();
387 void draw();
388 void flushDeferredUnloads();
389 };
390
391} // namespace ml
392
393#endif // MALENA_APPMANAGER_H
void setVSync(bool enabled)
Enable or disable vertical synchronisation.
static Core * exclusiveOwner()
The current exclusive-interaction owner, or nullptr.
Definition AppManager.h:345
void onPostRender(std::function< void()> hook)
Register a callback invoked after all components are drawn and before display().
Architecture
Architectural style hint passed at construction.
Definition AppManager.h:117
@ EDA
Event-Driven Architecture.
Definition AppManager.h:119
@ ECS
Entity-Component-System.
Definition AppManager.h:120
@ MVC
Model-View-Controller.
Definition AppManager.h:118
void run()
Enter the main loop and run until the window is closed.
void onPreRender(std::function< void()> hook)
Register a callback invoked after clear() and before drawing components.
void setIcon(const sf::Image &icon)
Set the window icon from an sf::Image.
static float getDeltaTime()
Return the elapsed time of the previous frame in seconds.
Definition AppManager.h:259
bool isPaused() const
Return true if the application is currently paused.
Definition AppManager.h:276
void resume()
Resume update events after a pause().
void setBackgroundColor(sf::Color color)
Set the colour used to clear the window at the start of each frame.
void pause()
Suspend per-frame update events.
void onEvent(std::function< bool(const sf::Event &)> handler)
Intercept raw window events before they reach components.
static void setActivePopup(Core *popup)
Register a component to be drawn on top of everything else, after the whole component tree,...
Definition AppManager.h:354
static void clearExclusiveOwner()
Lift any active exclusive-owner restriction.
void onClose(std::function< bool()> handler)
Register a callback invoked when the OS close button is pressed.
void setFramerateLimit(unsigned int limit)
Cap the frame rate.
void setTitle(const std::string &title)
Change the window title at runtime.
Architecture getArchitecture() const
Return the architectural mode set at construction.
Definition AppManager.h:332
static Core * activePopup()
The component currently drawn as the top popup layer, or nullptr.
Definition AppManager.h:357
static void setExclusiveOwner(Core *owner)
Restrict click and hover dispatch to owner and its descendants. Any component outside that subtree si...
void setWindowPosition(int x, int y)
Move the window to a position on the desktop.
virtual ~AppManager()=default
void setWindowStyle(std::uint32_t style)
Recreate the window with new decoration-style flags.
AppManager(const sf::VideoMode &videoMode, const std::string &title, sf::RenderWindow &window=WindowManager::getWindow(), Architecture architecture=MVC, std::uint32_t windowStyle=sf::Style::Default)
Construct an AppManager and create the SFML window.
void onResize(std::function< void(unsigned int, unsigned int)> handler)
Register a callback invoked whenever the window is resized.
static void clearActivePopup()
Clear the top popup layer (equivalent to setActivePopup(nullptr)).
Definition AppManager.h:360
Virtual base class for all Malena framework objects.
Definition Core.h:97
Static, type-safe collection manager for Core-derived objects.
Definition CoreManager.h:56
Trait that adds one-time initialization lifecycle hooks to any class.
Definition Lifecycle.h:73
static const Color Black
sf::RenderWindow & getWindow()
Return the framework's shared sf::RenderWindow.
#define MALENA_API
Definition Animate.h:25