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