The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
draw_manager.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2007 - 2025
3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY.
11
12 See the COPYING file for more details.
13*/
14
15#pragma once
16
17#include "sdl/rect.hpp"
18
19#include <chrono>
20
21namespace gui2 { class top_level_drawable; }
22
23/**
24 * A global draw management interface.
25 *
26 * This interface governs drawing things to the screen in the correct order.
27 * Drawable objects must inherit from gui2::top_level_drawable, and may be
28 * referred to as "TLD"s.
29 *
30 * There is an absolute requirement that events happen in a certain order.
31 * This is mostly managed by this interface, which calls the TLD methods in
32 * order at most once every vsync.
33 *
34 * The order of events is:
35 * 1. General event processing. This is governed by events::pump()
36 * and is currently independent of this interface.
37 * 2. Layout and animation. TLDs should ensure their layout information
38 * is up-to-date inside gui2::top_level_drawable::layout(). After
39 * this call they should know where they are on the screen, and be
40 * ready to report it via gui2::top_level_drawable::screen_location().
41 * Animation can also be performed during this stage.
42 * 3. Offscreen rendering. TLDs should perform any offscreen rendering
43 * during gui2::top_level_drawable::render(). After this call, all
44 * internal drawing buffers should be in a state ready for display.
45 * 4. Drawing to the screen. Drawing to the screen should only ever happen
46 * inside gui2::top_level_drawable::expose(). Drawing to the screen at
47 * any other point is an error.
48 *
49 * The draw manager will call layout(), render() and expose() in the correct
50 * order to ensure all TLD objects are laid out correctly and drawn in the
51 * correct order.
52 *
53 * Drawing order of TLDs is initially set by creation time, but a TLD may
54 * be raised to the top of the drawing stack by calling
55 * draw_manager::raise_drawable() manually. register_drawable() and
56 * deregister_drawable() are called automatically by gui2::top_level_drawable
57 * in its constructor and destructor, and do not need to be manually managed.
58 *
59 * The drawing process happens inside draw_manager::sparkle(). In general,
60 * a game loop should perform two basic steps.
61 * 1. call events::pump() to process events. Anything other than drawing
62 * to the screen may happen during this step.
63 * 2. call draw_manager::sparkle() to draw the screen, if necessary.
64 *
65 * The main sparkle() function will also rate-limit, so callers do not need
66 * to add their own delay to their loops. If vsync is disabled, drawing will
67 * happen as frequently as possible. If vsync is enabled, this function will
68 * wait for the next screen refresh before drawing. In both cases, if nothing
69 * needs to be drawn the function will block for an appropriate length of
70 * time before returning.
71 *
72 * To ensure they are presented for drawing, any drawable object must call
73 * draw_manager::invalidate_region() to indicate that an area of the screen
74 * needs to be redrawn. This may be called during any phase other than the
75 * draw phase. Invalidating regions during the draw phase is an error and
76 * will throw an exception.
77 */
78namespace draw_manager
79{
80
81/**
82 * Mark a region of the screen as requiring redraw.
83 *
84 * This should be called any time an item changes in such a way as to
85 * require redrawing.
86 *
87 * This may only be called outside the Draw phase.
88 *
89 * Regions are combined to result in a minimal number of draw calls,
90 * so this may be called for every invalidation without much concern.
91 */
92void invalidate_region(const rect& region);
93
94/** Mark the entire screen as requiring redraw. */
95void invalidate_all();
96
97/**
98 * Request an extra render pass.
99 *
100 * This is used for blur effects, which need to first render what's
101 * underneath so that it can be blurred.
102 *
103 * There is not currently any limit to the number of extra render passes,
104 * but do try to keep it finite.
105 */
107
108/**
109 * Ensure that everything which needs to be drawn is drawn.
110 *
111 * This includes making sure window sizes and locations are up to date,
112 * updating animation frames, and drawing whatever regions of the screen
113 * need drawing or redrawing.
114 *
115 * If vsync is enabled, this function will block until the next vblank.
116 * If nothing is drawn, it will still block for an appropriate amount of
117 * time to simulate vsync, even if vsync is disabled.
118 */
119void sparkle();
120
121/**
122 * Returns the length of one display frame, in milliseconds.
123 *
124 * This will usually be determined by the active monitor's refresh rate.
125 */
126std::chrono::milliseconds get_frame_length();
127
128/** Register a top-level drawable.
129 *
130 * Registered drawables will be drawn in the order of registration,
131 * so the most recently-registered drawable will be "on top".
132 */
134
135/** Remove a top-level drawable from the drawing stack. */
137
138/** Raise a TLD to the top of the drawing stack. */
140
141} // namespace draw_manager
A top-level drawable item (TLD), such as a window.
A global draw management interface.
void invalidate_region(const rect &region)
Mark a region of the screen as requiring redraw.
void request_extra_render_pass()
Request an extra render pass.
void register_drawable(top_level_drawable *tld)
Register a top-level drawable.
void deregister_drawable(top_level_drawable *tld)
Remove a top-level drawable from the drawing stack.
void invalidate_all()
Mark the entire screen as requiring redraw.
void sparkle()
Ensure that everything which needs to be drawn is drawn.
std::chrono::milliseconds get_frame_length()
Returns the length of one display frame, in milliseconds.
void raise_drawable(top_level_drawable *tld)
Raise a TLD to the top of the drawing stack.
Generic file dialog.
Contains the SDL_Rect helper code.
An abstract description of a rectangle with integer coordinates.
Definition rect.hpp:49