Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
GUIManager.h
Go to the documentation of this file.
1/* Copyright (C) 2024 Wildfire Games.
2 * This file is part of 0 A.D.
3 *
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef INCLUDED_GUIMANAGER
19#define INCLUDED_GUIMANAGER
20
22#include "lib/input.h"
23#include "ps/CStr.h"
24#include "ps/TemplateLoader.h"
26
27#include <deque>
28#include <string>
29#include <unordered_set>
30
31class CCanvas2D;
32class CGUI;
33
34/**
35 * External interface to the GUI system.
36 *
37 * The GUI consists of a set of pages. Each page is constructed from a
38 * series of XML files, and is independent from any other page.
39 * Only one page is active at a time. All events and render requests etc
40 * will go to the active page. This lets the GUI switch between pre-game menu
41 * and in-game UI.
42 */
44{
46public:
47 CGUIManager(ScriptContext& scriptContext, ScriptInterface& scriptInterface);
49
51 {
52 return m_ScriptInterface;
53 }
55 std::shared_ptr<CGUI> GetActiveGUI() { return top(); }
56
57 /**
58 * Returns the number of currently open GUI pages.
59 */
60 size_t GetPageCount() const;
61
62 /**
63 * Load a new GUI page and make it active. All current pages will be destroyed.
64 */
65 void SwitchPage(const CStrW& name, const ScriptInterface* srcScriptInterface, JS::HandleValue initData);
66
67 /**
68 * Load a new GUI page and make it active. All current pages will be retained,
69 * and will still be drawn and receive tick events, but will not receive
70 * user inputs.
71 * The returned promise will be fulfilled once the pushed page is closed.
72 */
73 JS::Value PushPage(const CStrW& pageName, Script::StructuredClone initData);
74
75 /**
76 * Unload the currently active GUI page, and make the previous page active.
77 * (There must be at least two pages when you call this.)
78 */
80
81 /**
82 * Called when a file has been modified, to hotload changes.
83 */
84 Status ReloadChangedFile(const VfsPath& path);
85
86 /**
87 * Called when we should reload all pages (e.g. translation hotloading update).
88 */
90
91 /**
92 * Pass input events to the currently active GUI page.
93 */
95
96 /**
97 * See CGUI::SendEventToAll; applies to the currently active page.
98 */
99 void SendEventToAll(const CStr& eventName) const;
100 void SendEventToAll(const CStr& eventName, JS::HandleValueArray paramData) const;
101
102 /**
103 * See CGUI::TickObjects; applies to @em all loaded pages.
104 */
105 void TickObjects();
106
107 /**
108 * See CGUI::Draw; applies to @em all loaded pages.
109 */
110 void Draw(CCanvas2D& canvas) const;
111
112 /**
113 * See CGUI::UpdateResolution; applies to @em all loaded pages.
114 */
115 void UpdateResolution();
116
117 /**
118 * Check if a template with this name exists
119 */
120 bool TemplateExists(const std::string& templateName) const;
121
122 /**
123 * Retrieve the requested template, used for displaying faction specificities.
124 */
125 const CParamNode& GetTemplate(const std::string& templateName);
126
127 /**
128 * Display progress / description in loading screen.
129 */
130 void DisplayLoadProgress(int percent, const wchar_t* pending_task);
131
132private:
133 struct SGUIPage
134 {
135 // COPYABLE, because event handlers may invalidate page stack iterators by open or close pages,
136 // and event handlers need to be called for the entire stack.
137
138 /**
139 * Initializes the data that will be used to create the CGUI page one or multiple times (hotloading).
140 */
141 SGUIPage(const CStrW& pageName, const Script::StructuredClone initData);
142
143 /**
144 * Create the CGUI with it's own ScriptInterface. Deletes the previous CGUI if it existed.
145 */
146 void LoadPage(ScriptContext& scriptContext);
147
148 /**
149 * A new promise gets set. A reference to that promise is returned. The promise will settle when
150 * the page is closed.
151 */
152 JS::Value ReplacePromise(ScriptInterface& scriptInterface);
153
154 /**
155 * Execute the stored callback function with the given arguments.
156 */
158
159 std::wstring m_Name;
160 std::unordered_set<VfsPath> inputs; // for hotloading
161 Script::StructuredClone initData; // data to be passed to the init() function
162 std::shared_ptr<CGUI> gui; // the actual GUI page
163
164 /**
165 * Function executed by this parent GUI page when the child GUI page it pushed is popped.
166 * Notice that storing it in the SGUIPage instead of CGUI means that it will survive the hotloading CGUI reset.
167 */
168 std::shared_ptr<JS::PersistentRootedObject> callbackFunction;
169 };
170
171 std::shared_ptr<CGUI> top() const;
172
175
176 /**
177 * The page stack must not move pointers on push/pop, or pushing a page in a page's init method
178 * may crash (as the pusher page will suddenly have moved, and the stack will be confused).
179 * Therefore use std::deque over std::vector.
180 * Also the elements have to be destructed back to front.
181 */
182 class PageStackType : public std::deque<SGUIPage>
183 {
184 public:
186 {
187 clear();
188 }
189
190 void clear()
191 {
192 while (!std::deque<SGUIPage>::empty())
193 std::deque<SGUIPage>::pop_back();
194 }
195 };
197
199};
200
201extern CGUIManager* g_GUI;
202
203extern InReaction gui_handler(const SDL_Event_* ev);
204
205#endif // INCLUDED_GUIMANAGER
InReaction gui_handler(const SDL_Event_ *ev)
Definition: GUIManager.cpp:58
CGUIManager * g_GUI
Definition: GUIManager.cpp:46
Definition: Canvas2D.h:36
The page stack must not move pointers on push/pop, or pushing a page in a page's init method may cras...
Definition: GUIManager.h:183
void clear()
Definition: GUIManager.h:190
~PageStackType()
Definition: GUIManager.h:185
External interface to the GUI system.
Definition: GUIManager.h:44
ScriptInterface & m_ScriptInterface
Definition: GUIManager.h:174
void TickObjects()
See CGUI::TickObjects; applies to all loaded pages.
Definition: GUIManager.cpp:367
Status ReloadAllPages()
Called when we should reload all pages (e.g.
Definition: GUIManager.cpp:297
PageStackType m_PageStack
Definition: GUIManager.h:196
CGUIManager(ScriptContext &scriptContext, ScriptInterface &scriptInterface)
Definition: GUIManager.cpp:72
void DisplayLoadProgress(int percent, const wchar_t *pending_task)
Display progress / description in loading screen.
Definition: GUIManager.cpp:418
void SendEventToAll(const CStr &eventName) const
See CGUI::SendEventToAll; applies to the currently active page.
Definition: GUIManager.cpp:348
NONCOPYABLE(CGUIManager)
ScriptContext & GetContext()
Definition: GUIManager.h:54
void SwitchPage(const CStrW &name, const ScriptInterface *srcScriptInterface, JS::HandleValue initData)
Load a new GUI page and make it active.
Definition: GUIManager.cpp:97
std::shared_ptr< CGUI > top() const
Definition: GUIManager.cpp:437
bool TemplateExists(const std::string &templateName) const
Check if a template with this name exists.
Definition: GUIManager.cpp:404
ScriptInterface & GetScriptInterface()
Definition: GUIManager.h:50
void Draw(CCanvas2D &canvas) const
See CGUI::Draw; applies to all loaded pages.
Definition: GUIManager.cpp:384
std::shared_ptr< CGUI > GetActiveGUI()
Definition: GUIManager.h:55
InReaction HandleEvent(const SDL_Event_ *ev)
Pass input events to the currently active GUI page.
Definition: GUIManager.cpp:306
Status ReloadChangedFile(const VfsPath &path)
Called when a file has been modified, to hotload changes.
Definition: GUIManager.cpp:284
JS::Value PushPage(const CStrW &pageName, Script::StructuredClone initData)
Load a new GUI page and make it active.
Definition: GUIManager.cpp:119
ScriptContext & m_ScriptContext
Definition: GUIManager.h:173
void UpdateResolution()
See CGUI::UpdateResolution; applies to all loaded pages.
Definition: GUIManager.cpp:392
void PopPage(Script::StructuredClone args)
Unload the currently active GUI page, and make the previous page active.
Definition: GUIManager.cpp:140
const CParamNode & GetTemplate(const std::string &templateName)
Retrieve the requested template, used for displaying faction specificities.
Definition: GUIManager.cpp:409
size_t GetPageCount() const
Returns the number of currently open GUI pages.
Definition: GUIManager.cpp:92
~CGUIManager()
Definition: GUIManager.cpp:87
CTemplateLoader m_TemplateLoader
Definition: GUIManager.h:198
The main object that represents a whole GUI page.
Definition: CGUI.h:61
An entity initialisation parameter node.
Definition: ParamNode.h:151
Template loader: Handles the loading of entity template files for:
Definition: TemplateLoader.h:48
Definition: path.h:80
Abstraction around a SpiderMonkey JSContext.
Definition: ScriptContext.h:46
Abstraction around a SpiderMonkey JS::Realm.
Definition: ScriptInterface.h:72
InReaction
Definition: input.h:35
std::shared_ptr< JSStructuredCloneData > StructuredClone
Structured clones are a way to serialize 'simple' JS::Values into a buffer that can safely be passed ...
Definition: StructuredClone.h:36
i64 Status
Error handling system.
Definition: status.h:173
Definition: GUIManager.h:134
void ResolvePromise(Script::StructuredClone args)
Execute the stored callback function with the given arguments.
Definition: GUIManager.cpp:261
std::shared_ptr< JS::PersistentRootedObject > callbackFunction
Function executed by this parent GUI page when the child GUI page it pushed is popped.
Definition: GUIManager.h:168
std::unordered_set< VfsPath > inputs
Definition: GUIManager.h:160
SGUIPage(const CStrW &pageName, const Script::StructuredClone initData)
Initializes the data that will be used to create the CGUI page one or multiple times (hotloading).
Definition: GUIManager.cpp:158
std::shared_ptr< CGUI > gui
Definition: GUIManager.h:162
std::wstring m_Name
Definition: GUIManager.h:159
void LoadPage(ScriptContext &scriptContext)
Create the CGUI with it's own ScriptInterface.
Definition: GUIManager.cpp:163
JS::Value ReplacePromise(ScriptInterface &scriptInterface)
A new promise gets set.
Definition: GUIManager.cpp:253
Script::StructuredClone initData
Definition: GUIManager.h:161
Definition: libsdl.h:53