Pyrogenesis  trunk
GUIManager.h
Go to the documentation of this file.
1 /* Copyright (C) 2022 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 
21 #include "lib/file/vfs/vfs_path.h"
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 
31 class CCanvas2D;
32 class 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 {
46 public:
47  CGUIManager();
48  ~CGUIManager();
49 
50  std::shared_ptr<ScriptInterface> GetScriptInterface()
51  {
52  return m_ScriptInterface;
53  }
54  std::shared_ptr<ScriptContext> GetContext() { return m_ScriptContext; }
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  * If given, the callbackHandler function will be executed once this page is closed.
72  */
73  void PushPage(const CStrW& pageName, Script::StructuredClone initData, JS::HandleValue callbackFunc);
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 
132 private:
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(std::shared_ptr<ScriptContext> scriptContext);
147 
148  /**
149  * Sets the callback handler when a new page is opened that will be performed when the page is closed.
150  */
151  void SetCallbackFunction(ScriptInterface& scriptInterface, JS::HandleValue callbackFunc);
152 
153  /**
154  * Execute the stored callback function with the given arguments.
155  */
157 
158  CStrW m_Name;
159  std::unordered_set<VfsPath> inputs; // for hotloading
160  Script::StructuredClone initData; // data to be passed to the init() function
161  std::shared_ptr<CGUI> gui; // the actual GUI page
162 
163  /**
164  * Function executed by this parent GUI page when the child GUI page it pushed is popped.
165  * Notice that storing it in the SGUIPage instead of CGUI means that it will survive the hotloading CGUI reset.
166  */
167  std::shared_ptr<JS::PersistentRootedValue> callbackFunction;
168  };
169 
170  std::shared_ptr<CGUI> top() const;
171 
172  std::shared_ptr<ScriptContext> m_ScriptContext;
173  std::shared_ptr<ScriptInterface> m_ScriptInterface;
174 
175  /**
176  * The page stack must not move pointers on push/pop, or pushing a page in a page's init method
177  * may crash (as the pusher page will suddenly have moved, and the stack will be confused).
178  * Therefore use std::deque over std::vector.
179  */
180  using PageStackType = std::deque<SGUIPage>;
182 
184 };
185 
186 extern CGUIManager* g_GUI;
187 
188 extern InReaction gui_handler(const SDL_Event_* ev);
189 
190 #endif // INCLUDED_GUIMANAGER
An entity initialisation parameter node.
Definition: ParamNode.h:150
Template loader: Handles the loading of entity template files for:
Definition: TemplateLoader.h:47
size_t GetPageCount() const
Returns the number of currently open GUI pages.
Definition: GUIManager.cpp:89
void PushPage(const CStrW &pageName, Script::StructuredClone initData, JS::HandleValue callbackFunc)
Load a new GUI page and make it active.
Definition: GUIManager.cpp:116
void LoadPage(std::shared_ptr< ScriptContext > scriptContext)
Create the CGUI with it&#39;s own ScriptInterface.
Definition: GUIManager.cpp:156
PageStackType m_PageStack
Definition: GUIManager.h:181
void Draw(CCanvas2D &canvas) const
See CGUI::Draw; applies to all loaded pages.
Definition: GUIManager.cpp:391
std::shared_ptr< JSStructuredCloneData > StructuredClone
Structured clones are a way to serialize &#39;simple&#39; JS::Values into a buffer that can safely be passed ...
Definition: StructuredClone.h:36
bool TemplateExists(const std::string &templateName) const
Check if a template with this name exists.
Definition: GUIManager.cpp:411
Definition: GUIManager.h:133
Status ReloadAllPages()
Called when we should reload all pages (e.g.
Definition: GUIManager.cpp:306
void SetCallbackFunction(ScriptInterface &scriptInterface, JS::HandleValue callbackFunc)
Sets the callback handler when a new page is opened that will be performed when the page is closed...
Definition: GUIManager.cpp:246
std::deque< SGUIPage > PageStackType
The page stack must not move pointers on push/pop, or pushing a page in a page&#39;s init method may cras...
Definition: GUIManager.h:180
std::shared_ptr< CGUI > gui
Definition: GUIManager.h:161
Definition: libsdl.h:52
void UpdateResolution()
See CGUI::UpdateResolution; applies to all loaded pages.
Definition: GUIManager.cpp:399
void DisplayLoadProgress(int percent, const wchar_t *pending_task)
Display progress / description in loading screen.
Definition: GUIManager.cpp:425
The main object that represents a whole GUI page.
Definition: CGUI.h:60
~CGUIManager()
Definition: GUIManager.cpp:84
void PopPage(Script::StructuredClone args)
Unload the currently active GUI page, and make the previous page active.
Definition: GUIManager.cpp:133
std::shared_ptr< CGUI > GetActiveGUI()
Definition: GUIManager.h:55
void PerformCallbackFunction(Script::StructuredClone args)
Execute the stored callback function with the given arguments.
Definition: GUIManager.cpp:265
Definition: path.h:79
std::shared_ptr< ScriptInterface > m_ScriptInterface
Definition: GUIManager.h:173
InReaction
Definition: input.h:34
Definition: Canvas2D.h:35
std::shared_ptr< ScriptContext > m_ScriptContext
Definition: GUIManager.h:172
std::shared_ptr< ScriptInterface > GetScriptInterface()
Definition: GUIManager.h:50
void TickObjects()
See CGUI::TickObjects; applies to all loaded pages.
Definition: GUIManager.cpp:376
i64 Status
Error handling system.
Definition: status.h:169
const CParamNode & GetTemplate(const std::string &templateName)
Retrieve the requested template, used for displaying faction specificities.
Definition: GUIManager.cpp:416
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:151
void SendEventToAll(const CStr &eventName) const
See CGUI::SendEventToAll; applies to the currently active page.
Definition: GUIManager.cpp:357
CStrW m_Name
Definition: GUIManager.h:158
NONCOPYABLE(CGUIManager)
CGUIManager * g_GUI
Definition: GUIManager.cpp:43
std::shared_ptr< ScriptContext > GetContext()
Definition: GUIManager.h:54
std::unordered_set< VfsPath > inputs
Definition: GUIManager.h:159
Script::StructuredClone initData
Definition: GUIManager.h:160
Abstraction around a SpiderMonkey JS::Realm.
Definition: ScriptInterface.h:71
External interface to the GUI system.
Definition: GUIManager.h:43
CTemplateLoader m_TemplateLoader
Definition: GUIManager.h:183
std::shared_ptr< CGUI > top() const
Definition: GUIManager.cpp:444
CGUIManager()
Definition: GUIManager.cpp:69
Status ReloadChangedFile(const VfsPath &path)
Called when a file has been modified, to hotload changes.
Definition: GUIManager.cpp:293
InReaction HandleEvent(const SDL_Event_ *ev)
Pass input events to the currently active GUI page.
Definition: GUIManager.cpp:315
std::shared_ptr< JS::PersistentRootedValue > callbackFunction
Function executed by this parent GUI page when the child GUI page it pushed is popped.
Definition: GUIManager.h:167
void SwitchPage(const CStrW &name, const ScriptInterface *srcScriptInterface, JS::HandleValue initData)
Load a new GUI page and make it active.
Definition: GUIManager.cpp:94
InReaction gui_handler(const SDL_Event_ *ev)
Definition: GUIManager.cpp:55