-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapplication_layout.html
More file actions
232 lines (230 loc) · 18.7 KB
/
Copy pathapplication_layout.html
File metadata and controls
232 lines (230 loc) · 18.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Rocket Game Engine: Your First Rocket Application</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript">var page_layout=1;</script>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
$(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="side-nav" class="ui-resizable side-nav-resizable"><!-- do not remove this div, it is closed by doxygen! -->
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Rocket Game Engine
</div>
</td>
</tr>
<tr><td colspan="2"> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<span id="MSearchSelect" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()"> </span>
<input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
</span>
</div>
</td></tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
</div><!-- top -->
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
$(document).ready(function(){initNavTree('application_layout.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div><div class="header">
<div class="headertitle"><div class="title">Your First Rocket Application</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="the_application"></a>
The Application Class</h1>
<dl class="section note"><dt>Note</dt><dd>Further documentation about the Application class can be found in the class' documentation page <a class="el" href="classApplication.html">here</a>.</dd></dl>
<p>Rocket uses the <a class="el" href="classApplication.html">Application</a> class as a hook to enter the Engine. It is, in essence, the "main" function of any application. In the following examples, we will be using the classname "ApplicationSubClass" as this hypothetical Rocket application.</p>
<h2><a class="anchor" id="subclassing_application"></a>
Subclassing Application</h2>
<p>The first thing most users should do is to subclass <a class="el" href="classApplication.html">Application</a>. The base class <a class="el" href="classApplication.html">Application</a> has one member that is very important to consider when making this subclass:</p><ul>
<li><a class="el" href="classApplication.html#a5c149f7d5d6784f859d16df61960a27c">Application::m_currApp</a>: A static pointer to the currently running <a class="el" href="classApplication.html">Application</a>. This should be set to the app when it is created.</li>
</ul>
<p>The base constructor of <a class="el" href="classApplication.html">Application</a> will take care of the rest of the fields inside <a class="el" href="classApplication.html">Application</a>.</p>
<p>There are a couple of ways of creating this <a class="el" href="classApplication.html">Application</a> subclass: 1) Design it such that the constructor is public, and inside said constructor initialize Components and Systems, as well as setting <code><a class="el" href="classApplication.html#a5c149f7d5d6784f859d16df61960a27c">Application::m_currApp</a> = this</code>. </p><div class="fragment"><div class="line"><span class="keyword">class </span>ApplicationSubClass : <span class="keyword">public</span> <a class="code hl_class" href="classApplication.html">Application</a></div>
<div class="line">{</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line"> ApplicationSubClass(<span class="keyword">const</span> std::string& windowName, <span class="keywordtype">int</span> width, <span class="keywordtype">int</span> height)</div>
<div class="line"> :<a class="code hl_class" href="classApplication.html">Application</a>(windowName, width, height)</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// Initialize components and systems here</span></div>
<div class="line"> m_currApp = <span class="keyword">this</span>;</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="ttc" id="aclassApplication_html"><div class="ttname"><a href="classApplication.html">Application</a></div><div class="ttdef"><b>Definition</b> Application.hpp:55</div></div>
</div><!-- fragment --><p>2) Design it such that the constructor is private, only calling the base constructor, and do all the work, as well as returning a pointer to the newly created class, via a static member function. </p><div class="fragment"><div class="line"><span class="keyword">class </span>ApplicationSubClass : <span class="keyword">public</span> <a class="code hl_class" href="classApplication.html">Application</a></div>
<div class="line">{</div>
<div class="line"><span class="keyword">private</span>:</div>
<div class="line"> ApplicationSubClass(<span class="keyword">const</span> std::string& windowName, <span class="keywordtype">int</span> width, <span class="keywordtype">int</span> height)</div>
<div class="line"> :<a class="code hl_class" href="classApplication.html">Application</a>(windowName, width, height) {}</div>
<div class="line"> </div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line"> ApplicationSubClass* <a class="code hl_function" href="classApplication.html#a20e7b40d2983b148ac53c84707379905">CreateApplication</a>(<span class="keyword">const</span> std::string& name, <span class="keywordtype">int</span> width, <span class="keywordtype">int</span> height)</div>
<div class="line"> {</div>
<div class="line"> ApplicationSubClass* app = <span class="keyword">new</span> ApplicationSubClass(name, width, height);</div>
<div class="line"> <span class="keywordflow">if</span> (m_currApp != <span class="keyword">nullptr</span>)</div>
<div class="line"> m_currApp->FreeApplication();</div>
<div class="line"> <span class="comment">// Initialize components and systems here</span></div>
<div class="line"> </div>
<div class="line"> <a class="code hl_variable" href="classApplication.html#a5c149f7d5d6784f859d16df61960a27c">Application::m_currApp</a> = app;</div>
<div class="line"> <span class="keywordflow">return</span> app;</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="ttc" id="aclassApplication_html_a20e7b40d2983b148ac53c84707379905"><div class="ttname"><a href="classApplication.html#a20e7b40d2983b148ac53c84707379905">Application::CreateApplication</a></div><div class="ttdeci">Application * CreateApplication(const std::string &appName, int width, int height)</div></div>
<div class="ttc" id="aclassApplication_html_a5c149f7d5d6784f859d16df61960a27c"><div class="ttname"><a href="classApplication.html#a5c149f7d5d6784f859d16df61960a27c">Application::m_currApp</a></div><div class="ttdeci">static Application * m_currApp</div><div class="ttdef"><b>Definition</b> Application.hpp:62</div></div>
</div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>Of the two options, option 2 is preferred. It has more memory safety, as you can choose when to delete an application via FreeApplication(). Option 1 is a fine option for smaller projects where only 1 <a class="el" href="classApplication.html">Application</a> instance will <b>ever</b> be created. If multiple Applications are created while using option 1, unintended behaviour will commence.</dd></dl>
<h2><a class="anchor" id="init_comps_and_systems"></a>
Initializing Components and Systems</h2>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000002">Todo:</a></b></dt><dd>Perhaps make the macros for InitComponent and InitSystem not rely on the user defining <code>cd</code>?</dd></dl>
<p>During the creation of an <a class="el" href="classApplication.html">Application</a>, you will need to initialize all the Components and Systems the app will need. All the shipped Components and Systems will be loaded during the base class <a class="el" href="classApplication.html">Application</a>'s constructor, but any user created ones will need to be loaded by the user.</p>
<p>To aid in this, Rocket has provided two macros: InitComponent() and InitSystem(). These do approximately what you would expect: InitComponent() takes the name of a component and initializes it to the engine. InitSystem() does the same, but for Systems. To use these macros, the user must first include the line: </p><div class="fragment"><div class="line"><a class="code hl_class" href="classCoordinator.html">Coordinator</a>* cd = Coordinator::Get();</div>
<div class="ttc" id="aclassCoordinator_html"><div class="ttname"><a href="classCoordinator.html">Coordinator</a></div><div class="ttdef"><b>Definition</b> Coordinator.h:9</div></div>
</div><!-- fragment --><p> These two macros rely on the definition of the variable <code>cd</code>.</p>
<dl class="section note"><dt>Note</dt><dd>To learn more about the Coordinator, see its class page <a class="el" href="classCoordinator.html">here</a>.</dd></dl>
<h2><a class="anchor" id="main_function"></a>
The Main Function</h2>
<p><a class="el" href="classApplication.html#ab404e626ddbbd2a59c94d58258f6f162">Application::Main()</a> is the only pure virtual function in the class. As such, it must be overridden in the subclass. <a class="el" href="classApplication.html#ab404e626ddbbd2a59c94d58258f6f162">Application::Main()</a> is, as the name implies, the main function of the <a class="el" href="classApplication.html">Application</a>. Inside it should be the per-frame logic of your application.</p>
<p>Things to consider defining inside of Main are:</p><ul>
<li>Framerate: Framerate is not managed by the engine, and is entirely on the programmer to implement, maintain, and edit as they see fit.</li>
<li><p class="startli">Systems: During each frame, any number of systems can and should be called upon to add functionality to the app. Notable among these is the <a class="el" href="classRenderSpriteSystem.html">RenderSpriteSystem</a>, a part of the main engine, and the renderer of the app.</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000003">Todo:</a></b></dt><dd>Remove the need for glfw calls in the main loop, that should be abstracted to the engine as a system or engine call of some kind.</dd></dl>
</li>
<li>glfwPollEvents() and glfwSwapBuffers(m_window): These two functions are currently needed to process events and update the window's graphics.</li>
<li>Rscene loads: If you need to load a scene, the Main() function would be the time to do it.</li>
</ul>
<p>An example of a Main function could be the following: </p><div class="fragment"><div class="line"><span class="keywordtype">void</span> Main()<span class="keyword"> override</span></div>
<div class="line"><span class="keyword"></span>{</div>
<div class="line"> <span class="keywordtype">double</span> curr_time = glfwGetTime();</div>
<div class="line"> <span class="keywordtype">double</span> prev_time = glfwGetTime();</div>
<div class="line"> <span class="keywordtype">double</span> deltatime = 0;</div>
<div class="line"> </div>
<div class="line"> <a class="code hl_class" href="classCoordinator.html">Coordinator</a>* cd = Coordinator::Get();</div>
<div class="line"> </div>
<div class="line"> <a class="code hl_function" href="LoadRscene_8cpp.html#a1c5c70438301ce70eb028e5bba115125">LoadScene</a>(<span class="stringliteral">"res/scene.rscene"</span>);</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">while</span> (!glfwWindowShouldClose(m_window))</div>
<div class="line"> {</div>
<div class="line"> curr_time = glfwGetTime();</div>
<div class="line"> deltatime = curr_time - prev_time;</div>
<div class="line"> </div>
<div class="line"> cd->GetSystem<<a class="code hl_class" href="classCollisionSystem.html">CollisionSystem</a>>()->Do();</div>
<div class="line"> </div>
<div class="line"> cd->GetSystem<<a class="code hl_class" href="classCollisionSystem.html">CollisionSystem</a>>()->Clear();</div>
<div class="line"> </div>
<div class="line"> glClearColor(0.0f, 0.0f, 0.0f, 0.0f);</div>
<div class="line"> glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);</div>
<div class="line"> cd->GetSystem<<a class="code hl_class" href="classRenderSpriteSystem.html">RenderSpriteSystem</a>>()->Do();</div>
<div class="line"> </div>
<div class="line"> glfwPollEvents();</div>
<div class="line"> glfwSwapBuffers(m_window);</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">double</span> timediff = glfwGetTime() - curr_time;</div>
<div class="line"> <span class="keywordtype">double</span> calculation = std::max((<span class="keywordtype">double</span>)(1.0 / m_framerate) - timediff, 0.0);</div>
<div class="line"> usleep((<span class="keywordtype">int</span>)(calculation * 1000000.0));</div>
<div class="line"> </div>
<div class="line"> prev_time = curr_time;</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="ttc" id="aLoadRscene_8cpp_html_a1c5c70438301ce70eb028e5bba115125"><div class="ttname"><a href="LoadRscene_8cpp.html#a1c5c70438301ce70eb028e5bba115125">LoadScene</a></div><div class="ttdeci">void LoadScene(const std::string &filepath)</div><div class="ttdef"><b>Definition</b> LoadRscene.cpp:53</div></div>
<div class="ttc" id="aclassCollisionSystem_html"><div class="ttname"><a href="classCollisionSystem.html">CollisionSystem</a></div><div class="ttdef"><b>Definition</b> CollisionSystem.hpp:8</div></div>
<div class="ttc" id="aclassRenderSpriteSystem_html"><div class="ttname"><a href="classRenderSpriteSystem.html">RenderSpriteSystem</a></div><div class="ttdef"><b>Definition</b> RenderSpriteSys.hpp:10</div></div>
</div><!-- fragment --><h2><a class="anchor" id="the_other_main"></a>
The... other main function</h2>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000004">Todo:</a></b></dt><dd>Remove the dependency on <code>int main()</code>, the user should only have to worry about one Main function, and it should be inside the <a class="el" href="classApplication.html">Application</a> they just took so long to make :(</dd></dl>
<p>Finally, we come to the main function... no the other one.</p>
<p><code>int main()</code> still has a part to play in the engine, although a small one. It's responsible for initializing GLFW (the windowing backend Rocket uses) and creating and running the app we just made.</p>
<p>An example of <code>int main()</code> could be the following: </p><div class="fragment"><div class="line"><span class="keywordtype">int</span> main()</div>
<div class="line">{</div>
<div class="line"> LogTrace(<span class="stringliteral">"Welcome to Rocket!"</span>);</div>
<div class="line"> <span class="keywordflow">if</span> (!glfwInit())</div>
<div class="line"> {</div>
<div class="line"> LogFatal(<span class="stringliteral">"Could not initialize GLFW!"</span>);</div>
<div class="line"> <span class="keywordflow">return</span> -1;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> ApplicationSubClass* app = ApplicationSubClass::CreateApplication(<span class="stringliteral">"test"</span>, 1920, 1080);</div>
<div class="line"> app->Main();</div>
<div class="line"> app->FreeApplication();</div>
<div class="line"> LogTrace(<span class="stringliteral">"Rocket is done!"</span>);</div>
<div class="line"> <span class="keywordflow">return</span> 0;</div>
<div class="line">}</div>
</div><!-- fragment --><h1><a class="anchor" id="conclusion"></a>
Conclusion</h1>
<p>With that out of the way, you've made your first Application! You're well on your way to making a game or other project inside Rocket! </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8 </li>
</ul>
</div>
</body>
</html>