irrlicht/examples/25.XmlHandling/tutorial.html
cutealien c481179825 Update tutorial.html's in example folders
Add some for newer examples which didn't have those so far.
Only updating this once now as some were broken. 
Next time on release.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6204 dfc29bdd-3216-0410-991c-e03cc46cb475
2021-03-18 21:50:11 +00:00

220 lines
42 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Tutorial 25: Xml Handling</title>
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- Wanted to avoid copying .css to each folder, so copied default .css from doxyen in here, kicked out most stuff we don't need for examples and modified some a little bit.
Target was having a single html in each example folder which is created from the main.cpp files and needs no files besides some images below media folder.
Feel free to improve :)
-->
<style>
body, table, div, p, dl {
font: 400 14px/22px;
}
body {
background-color: #F0F0F0;
color: black;
margin-left: 5%;
margin-right: 5%;
}
p.reference, p.definition {
font: 400 14px/22px;
}
.title {
font: 400 14px/28px;
font-size: 150%;
font-weight: bold;
margin: 10px 2px;
}
h1, h2, h3, h4, h5, h6 {
-webkit-transition: text-shadow 0.5s linear;
-moz-transition: text-shadow 0.5s linear;
-ms-transition: text-shadow 0.5s linear;
-o-transition: text-shadow 0.5s linear;
transition: text-shadow 0.5s linear;
margin-right: 15px;
}
caption {
font-weight: bold;
}
h3.version {
font-size: 90%;
text-align: center;
}
a {
color: #3D578C;
font-weight: normal;
text-decoration: none;
}
.contents a:visited {
color: #4665A2;
}
a:hover {
text-decoration: underline;
}
a.el {
font-weight: bold;
}
a.code, a.code:visited, a.line, a.line:visited {
color: #4665A2;
}
a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
color: #4665A2;
}
pre.fragment {
border: 1px solid #C4CFE5;
background-color: #FBFCFD;
padding: 4px 6px;
margin: 4px 8px 4px 2px;
overflow: auto;
word-wrap: break-word;
font-size: 9pt;
line-height: 125%;
font-family: monospace, fixed;
font-size: 105%;
}
div.fragment {
padding: 0px;
margin: 4px 8px 4px 2px;
background-color: #FBFCFD;
border: 1px solid #C4CFE5;
}
div.line {
font-family: monospace, fixed;
font-size: 13px;
min-height: 13px;
line-height: 1.0;
text-wrap: unrestricted;
white-space: -moz-pre-wrap; /* Moz */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
white-space: pre-wrap; /* CSS3 */
word-wrap: break-word; /* IE 5.5+ */
text-indent: -53px;
padding-left: 53px;
padding-bottom: 0px;
margin: 0px;
-webkit-transition-property: background-color, box-shadow;
-webkit-transition-duration: 0.5s;
-moz-transition-property: background-color, box-shadow;
-moz-transition-duration: 0.5s;
-ms-transition-property: background-color, box-shadow;
-ms-transition-duration: 0.5s;
-o-transition-property: background-color, box-shadow;
-o-transition-duration: 0.5s;
transition-property: background-color, box-shadow;
transition-duration: 0.5s;
}
div.contents {
margin-top: 10px;
margin-left: 12px;
margin-right: 8px;
}
div.center {
text-align: center;
margin-top: 0px;
margin-bottom: 0px;
padding: 0px;
}
div.center img {
border: 0px;
}
span.keyword {
color: #008000
}
span.keywordtype {
color: #604020
}
span.keywordflow {
color: #e08000
}
span.comment {
color: #800000
}
span.preprocessor {
color: #806020
}
span.stringliteral {
color: #002080
}
span.charliteral {
color: #008080
}
blockquote {
background-color: #F7F8FB;
border-left: 2px solid #9CAFD4;
margin: 0 24px 0 4px;
padding: 0 12px 0 16px;
}
hr {
height: 0px;
border: none;
border-top: 1px solid #4A6AAA;
}
address {
font-style: normal;
color: #2A3D61;
}
div.header {
background-image:url('nav_h.png');
background-repeat:repeat-x;
background-color: #F9FAFC;
margin: 0px;
border-bottom: 1px solid #C4CFE5;
}
div.headertitle {
padding: 5px 5px 5px 10px;
}
.image {
text-align: center;
}
.caption {
font-weight: bold;
}
div.zoom {
border: 1px solid #90A5CE;
}
tr.heading h2 {
margin-top: 12px;
margin-bottom: 4px;
}
</style>
</head>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--END TITLEAREA-->
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">Tutorial 25: Xml Handling </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><div class="image">
<img src="../../media/example_screenshots/025shot.jpg" alt="025shot.jpg"/>
</div>
<p>Demonstrates loading and saving of configurations via XML</p>
<dl class="section author"><dt>Author</dt><dd>Y.M. Bosman &lt;<a href="#" onclick="location.href='mai'+'lto:'+'yor'+'an'+'.bo'+'sm'+'an@'+'gm'+'ail'+'.c'+'om'; return false;">yoran<span style="display: none;">.nosp@m.</span>.bos<span style="display: none;">.nosp@m.</span>man@g<span style="display: none;">.nosp@m.</span>mail<span style="display: none;">.nosp@m.</span>.com</a>&gt;</dd></dl>
<p>This demo features a fully usable system for configuration handling. The code can easily be integrated into own apps.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;irrlicht.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;exampleHelper.h&quot;</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span>irr;</div><div class="line"><span class="keyword">using namespace </span>core;</div><div class="line"><span class="keyword">using namespace </span>scene;</div><div class="line"><span class="keyword">using namespace </span>video;</div><div class="line"><span class="keyword">using namespace </span>io;</div><div class="line"><span class="keyword">using namespace </span>gui;</div><div class="line"></div><div class="line"><span class="preprocessor">#ifdef _MSC_VER</span></div><div class="line"><span class="preprocessor">#pragma comment(lib, &quot;Irrlicht.lib&quot;)</span></div><div class="line"><span class="preprocessor">#endif</span></div></div><!-- fragment --><p> SettingManager class.</p>
<p>This class loads and writes the settings and manages the options.</p>
<p>The class makes use of irrMap which is a an associative arrays using a red-black tree it allows easy mapping of a key to a value, along the way there is some information on how to use it. </p><div class="fragment"><div class="line"><span class="keyword">class </span>SettingManager</div><div class="line">{</div><div class="line"><span class="keyword">public</span>:</div><div class="line"></div><div class="line"> <span class="comment">// Construct setting managers and set default settings</span></div><div class="line"> SettingManager(<span class="keyword">const</span> stringw&amp; settings_file): SettingsFile(settings_file), NullDevice(0)</div><div class="line"> {</div><div class="line"> <span class="comment">// Irrlicht null device, we want to load settings before we actually created our device, therefore, nulldevice</span></div><div class="line"> NullDevice = irr::createDevice(irr::video::EDT_NULL);</div><div class="line"></div><div class="line"> <span class="comment">//DriverOptions is an irrlicht map,</span></div><div class="line"> <span class="comment">//we can insert values in the map in two ways by calling insert(key,value) or by using the [key] operator</span></div><div class="line"> <span class="comment">//the [] operator overrides values if they already exist</span></div><div class="line"> DriverOptions.insert(L<span class="stringliteral">&quot;Software&quot;</span>, EDT_SOFTWARE);</div><div class="line"> DriverOptions.insert(L<span class="stringliteral">&quot;OpenGL&quot;</span>, EDT_OPENGL);</div><div class="line"> DriverOptions.insert(L<span class="stringliteral">&quot;Direct3D9&quot;</span>, EDT_DIRECT3D9);</div><div class="line"></div><div class="line"> <span class="comment">//some resolution options</span></div><div class="line"> ResolutionOptions.insert(L<span class="stringliteral">&quot;640x480&quot;</span>, dimension2du(640,480));</div><div class="line"> ResolutionOptions.insert(L<span class="stringliteral">&quot;800x600&quot;</span>, dimension2du(800,600));</div><div class="line"> ResolutionOptions.insert(L<span class="stringliteral">&quot;1024x768&quot;</span>, dimension2du(1024,768));</div><div class="line"></div><div class="line"> <span class="comment">//our preferred defaults</span></div><div class="line"> SettingMap.insert(L<span class="stringliteral">&quot;driver&quot;</span>, L<span class="stringliteral">&quot;Direct3D9&quot;</span>);</div><div class="line"> SettingMap.insert(L<span class="stringliteral">&quot;resolution&quot;</span>, L<span class="stringliteral">&quot;640x480&quot;</span>);</div><div class="line"> SettingMap.insert(L<span class="stringliteral">&quot;fullscreen&quot;</span>, L<span class="stringliteral">&quot;0&quot;</span>); <span class="comment">//0 is false</span></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Destructor, you could store settings automatically on exit of your</span></div><div class="line"> <span class="comment">// application if you wanted to in our case we simply drop the</span></div><div class="line"> <span class="comment">// nulldevice</span></div><div class="line"> ~SettingManager()</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (NullDevice)</div><div class="line"> {</div><div class="line"> NullDevice-&gt;closeDevice();</div><div class="line"> NullDevice-&gt;drop();</div><div class="line"> }</div><div class="line"> };</div></div><!-- fragment --><p> Load xml from disk, overwrite default settings The xml we are trying to load has the following structure settings nested in sections nested in the root node, like: </p><pre class="fragment"> &lt;pre&gt;
&lt;?xml version="1.0"?&gt;
&lt;mygame&gt;
&lt;video&gt;
&lt;setting name="driver" value="Direct3D9" /&gt;
&lt;setting name="fullscreen" value="0" /&gt;
&lt;setting name="resolution" value="1024x768" /&gt;
&lt;/video&gt;
&lt;/mygame&gt;
&lt;/pre&gt;</pre> <div class="fragment"><div class="line"> <span class="keywordtype">bool</span> load()</div><div class="line"> {</div><div class="line"> <span class="comment">//if not able to create device don&#39;t attempt to load</span></div><div class="line"> <span class="keywordflow">if</span> (!NullDevice)</div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"></div><div class="line"> irr::io::IXMLReader* xml = NullDevice-&gt;getFileSystem()-&gt;createXMLReader(SettingsFile); <span class="comment">//create xml reader</span></div><div class="line"> <span class="keywordflow">if</span> (!xml)</div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"></div><div class="line"> <span class="keyword">const</span> stringw settingTag(L<span class="stringliteral">&quot;setting&quot;</span>); <span class="comment">//we&#39;ll be looking for this tag in the xml</span></div><div class="line"> stringw currentSection; <span class="comment">//keep track of our current section</span></div><div class="line"> <span class="keyword">const</span> stringw videoTag(L<span class="stringliteral">&quot;video&quot;</span>); <span class="comment">//constant for videotag</span></div><div class="line"></div><div class="line"> <span class="comment">//while there is more to read</span></div><div class="line"> <span class="keywordflow">while</span> (xml-&gt;read())</div><div class="line"> {</div><div class="line"> <span class="comment">//check the node type</span></div><div class="line"> <span class="keywordflow">switch</span> (xml-&gt;getNodeType())</div><div class="line"> {</div><div class="line"> <span class="comment">//we found a new element</span></div><div class="line"> <span class="keywordflow">case</span> irr::io::EXN_ELEMENT:</div><div class="line"> {</div><div class="line"> <span class="comment">//we currently are in the empty or mygame section and find the video tag so we set our current section to video</span></div><div class="line"> <span class="keywordflow">if</span> (currentSection.empty() &amp;&amp; videoTag.equals_ignore_case(xml-&gt;getNodeName()))</div><div class="line"> {</div><div class="line"> currentSection = videoTag;</div><div class="line"> }</div><div class="line"> <span class="comment">//we are in the video section and we find a setting to parse</span></div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (currentSection.equals_ignore_case(videoTag) &amp;&amp; settingTag.equals_ignore_case(xml-&gt;getNodeName() ))</div><div class="line"> {</div><div class="line"> <span class="comment">//read in the key</span></div><div class="line"> stringw key = xml-&gt;getAttributeValueSafe(L<span class="stringliteral">&quot;name&quot;</span>);</div><div class="line"> <span class="comment">//if there actually is a key to set</span></div><div class="line"> <span class="keywordflow">if</span> (!key.empty())</div><div class="line"> {</div><div class="line"> <span class="comment">//set the setting in the map to the value,</span></div><div class="line"> <span class="comment">//the [] operator overrides values if they already exist or inserts a new key value</span></div><div class="line"> <span class="comment">//pair into the settings map if it was not defined yet</span></div><div class="line"> SettingMap[key] = xml-&gt;getAttributeValueSafe(L<span class="stringliteral">&quot;value&quot;</span>);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//..</span></div><div class="line"> <span class="comment">// You can add your own sections and tags to read in here</span></div><div class="line"> <span class="comment">//..</span></div><div class="line"> }</div><div class="line"> <span class="keywordflow">break</span>;</div><div class="line"></div><div class="line"> <span class="comment">//we found the end of an element</span></div><div class="line"> <span class="keywordflow">case</span> irr::io::EXN_ELEMENT_END:</div><div class="line"> <span class="comment">//we were at the end of the video section so we reset our tag</span></div><div class="line"> currentSection=L<span class="stringliteral">&quot;&quot;</span>;</div><div class="line"> <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">default</span>:</div><div class="line"> <span class="keywordflow">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// don&#39;t forget to delete the xml reader</span></div><div class="line"> xml-&gt;drop();</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Save the xml to disk. We use the nulldevice.</span></div><div class="line"> <span class="keywordtype">bool</span> save()</div><div class="line"> {</div><div class="line"></div><div class="line"> <span class="comment">//if not able to create device don&#39;t attempt to save</span></div><div class="line"> <span class="keywordflow">if</span> (!NullDevice)</div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"></div><div class="line"> <span class="comment">//create xml writer</span></div><div class="line"> irr::io::IXMLWriter* xwriter = NullDevice-&gt;getFileSystem()-&gt;createXMLWriter( SettingsFile );</div><div class="line"> <span class="keywordflow">if</span> (!xwriter)</div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"></div><div class="line"> <span class="comment">//write out the obligatory xml header. Each xml-file needs to have exactly one of those.</span></div><div class="line"> xwriter-&gt;writeXMLHeader();</div><div class="line"></div><div class="line"> <span class="comment">//start element mygame, you replace the label &quot;mygame&quot; with anything you want</span></div><div class="line"> xwriter-&gt;writeElement(L<span class="stringliteral">&quot;mygame&quot;</span>);</div><div class="line"> xwriter-&gt;writeLineBreak(); <span class="comment">//new line</span></div><div class="line"></div><div class="line"> <span class="comment">//start section with video settings</span></div><div class="line"> xwriter-&gt;writeElement(L<span class="stringliteral">&quot;video&quot;</span>);</div><div class="line"> xwriter-&gt;writeLineBreak(); <span class="comment">//new line</span></div><div class="line"></div><div class="line"> <span class="comment">// getIterator gets us a pointer to the first node of the settings map</span></div><div class="line"> <span class="comment">// every iteration we increase the iterator which gives us the next map node</span></div><div class="line"> <span class="comment">// until we reach the end we write settings one by one by using the nodes key and value functions</span></div><div class="line"> map&lt;stringw, stringw&gt;::Iterator i = SettingMap.getIterator();</div><div class="line"> <span class="keywordflow">for</span>(; !i.atEnd(); i++)</div><div class="line"> {</div><div class="line"> <span class="comment">//write element as &lt;setting name=&quot;key&quot; value=&quot;x&quot; /&gt;</span></div><div class="line"> <span class="comment">//the second parameter indicates this is an empty element with no children, just attributes</span></div><div class="line"> xwriter-&gt;writeElement(L<span class="stringliteral">&quot;setting&quot;</span>,<span class="keyword">true</span>, L<span class="stringliteral">&quot;name&quot;</span>, i-&gt;getKey().c_str(), L<span class="stringliteral">&quot;value&quot;</span>,i-&gt;getValue().c_str() );</div><div class="line"> xwriter-&gt;writeLineBreak();</div><div class="line"> }</div><div class="line"> xwriter-&gt;writeLineBreak();</div><div class="line"></div><div class="line"> <span class="comment">//close video section</span></div><div class="line"> xwriter-&gt;writeClosingTag(L<span class="stringliteral">&quot;video&quot;</span>);</div><div class="line"> xwriter-&gt;writeLineBreak();</div><div class="line"></div><div class="line"> <span class="comment">//..</span></div><div class="line"> <span class="comment">// You can add writing sound settings, savegame information etc</span></div><div class="line"> <span class="comment">//..</span></div><div class="line"></div><div class="line"> <span class="comment">//close mygame section</span></div><div class="line"> xwriter-&gt;writeClosingTag(L<span class="stringliteral">&quot;mygame&quot;</span>);</div><div class="line"></div><div class="line"> <span class="comment">//delete xml writer</span></div><div class="line"> xwriter-&gt;drop();</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Set setting in our manager</span></div><div class="line"> <span class="keywordtype">void</span> setSetting(<span class="keyword">const</span> stringw&amp; name, <span class="keyword">const</span> stringw&amp; value)</div><div class="line"> {</div><div class="line"> SettingMap[name]=value;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// set setting overload to quickly assign integers to our setting map</span></div><div class="line"> <span class="keywordtype">void</span> setSetting(<span class="keyword">const</span> stringw&amp; name, s32 value)</div><div class="line"> {</div><div class="line"> SettingMap[name]=stringw(value);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Get setting as string</span></div><div class="line"> stringw getSetting(<span class="keyword">const</span> stringw&amp; key)<span class="keyword"> const</span></div><div class="line"><span class="keyword"> </span>{</div><div class="line"> <span class="comment">//the find function or irrmap returns a pointer to a map Node</span></div><div class="line"> <span class="comment">//if the key can be found, otherwise it returns null</span></div><div class="line"> <span class="comment">//the map node has the function getValue and getKey, as we already know the key, we return node-&gt;getValue()</span></div><div class="line"> map&lt;stringw, stringw&gt;::Node* n = SettingMap.find(key);</div><div class="line"> <span class="keywordflow">if</span> (n)</div><div class="line"> <span class="keywordflow">return</span> n-&gt;getValue();</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> <span class="keywordflow">return</span> L<span class="stringliteral">&quot;&quot;</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordtype">bool</span> getSettingAsBoolean(<span class="keyword">const</span> stringw&amp; key )<span class="keyword"> const</span></div><div class="line"><span class="keyword"> </span>{</div><div class="line"> stringw s = getSetting(key);</div><div class="line"> <span class="keywordflow">if</span> (s.empty())</div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"> <span class="keywordflow">return</span> s.equals_ignore_case(L<span class="stringliteral">&quot;1&quot;</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//</span></div><div class="line"> s32 getSettingAsInteger(<span class="keyword">const</span> stringw&amp; key)<span class="keyword"> const</span></div><div class="line"><span class="keyword"> </span>{</div><div class="line"> <span class="comment">//we implicitly cast to string instead of stringw because strtol10 does not accept wide strings</span></div><div class="line"> <span class="keyword">const</span> stringc s = getSetting(key);</div><div class="line"> <span class="keywordflow">if</span> (s.empty())</div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> strtol10(s.c_str());</div><div class="line"> }</div><div class="line"></div><div class="line"><span class="keyword">public</span>:</div><div class="line"> map&lt;stringw, s32&gt; DriverOptions; <span class="comment">//available options for driver config</span></div><div class="line"> map&lt;stringw, dimension2du&gt; ResolutionOptions; <span class="comment">//available options for resolution config</span></div><div class="line"><span class="keyword">private</span>:</div><div class="line"> SettingManager(<span class="keyword">const</span> SettingManager&amp; other); <span class="comment">// defined but not implemented</span></div><div class="line"> SettingManager&amp; operator=(<span class="keyword">const</span> SettingManager&amp; other); <span class="comment">// defined but not implemented</span></div><div class="line"></div><div class="line"> map&lt;stringw, stringw&gt; SettingMap; <span class="comment">//current config</span></div><div class="line"></div><div class="line"> stringw SettingsFile; <span class="comment">// location of the xml, usually the</span></div><div class="line"> irr::IrrlichtDevice* NullDevice;</div><div class="line">};</div></div><!-- fragment --><p> Application context for global variables </p><div class="fragment"><div class="line"><span class="keyword">struct </span>SAppContext</div><div class="line">{</div><div class="line"> SAppContext()</div><div class="line"> : Device(0),Gui(0), Driver(0), Settings(0), ShouldQuit(false),</div><div class="line"> ButtonSave(0), ButtonExit(0), ListboxDriver(0),</div><div class="line"> ListboxResolution(0), CheckboxFullscreen(0)</div><div class="line"> {</div><div class="line"> }</div><div class="line"></div><div class="line"> ~SAppContext()</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (Settings)</div><div class="line"> <span class="keyword">delete</span> Settings;</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (Device)</div><div class="line"> {</div><div class="line"> Device-&gt;closeDevice();</div><div class="line"> Device-&gt;drop();</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> IrrlichtDevice* Device;</div><div class="line"> IGUIEnvironment* Gui;</div><div class="line"> IVideoDriver* Driver;</div><div class="line"> SettingManager* Settings;</div><div class="line"> <span class="keywordtype">bool</span> ShouldQuit;</div><div class="line"></div><div class="line"> <span class="comment">//settings dialog</span></div><div class="line"> IGUIButton* ButtonSave;</div><div class="line"> IGUIButton* ButtonExit;</div><div class="line"> IGUIListBox* ListboxDriver;</div><div class="line"> IGUIListBox* ListboxResolution;</div><div class="line"> IGUICheckBox* CheckboxFullscreen;</div><div class="line">};</div></div><!-- fragment --><p> A typical event receiver. </p><div class="fragment"><div class="line"><span class="keyword">class </span>MyEventReceiver : <span class="keyword">public</span> IEventReceiver</div><div class="line">{</div><div class="line"><span class="keyword">public</span>:</div><div class="line"> MyEventReceiver(SAppContext &amp; a) : App(a) { }</div><div class="line"></div><div class="line"> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> OnEvent(<span class="keyword">const</span> SEvent&amp; event)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (event.EventType == EET_GUI_EVENT )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">switch</span> ( event.GUIEvent.EventType )</div><div class="line"> {</div><div class="line"> <span class="comment">//handle button click events</span></div><div class="line"> <span class="keywordflow">case</span> EGET_BUTTON_CLICKED:</div><div class="line"> {</div><div class="line"> <span class="comment">//Our save button was called so we obtain the settings from our dialog and save them</span></div><div class="line"> <span class="keywordflow">if</span> ( event.GUIEvent.Caller == App.ButtonSave )</div><div class="line"> {</div><div class="line"> <span class="comment">//if there is a selection write it</span></div><div class="line"> <span class="keywordflow">if</span> ( App.ListboxDriver-&gt;getSelected() != -1)</div><div class="line"> App.Settings-&gt;setSetting(L<span class="stringliteral">&quot;driver&quot;</span>, App.ListboxDriver-&gt;getListItem(App.ListboxDriver-&gt;getSelected()));</div><div class="line"></div><div class="line"> <span class="comment">//if there is a selection write it</span></div><div class="line"> <span class="keywordflow">if</span> ( App.ListboxResolution-&gt;getSelected() != -1)</div><div class="line"> App.Settings-&gt;setSetting(L<span class="stringliteral">&quot;resolution&quot;</span>, App.ListboxResolution-&gt;getListItem(App.ListboxResolution-&gt;getSelected()));</div><div class="line"></div><div class="line"> App.Settings-&gt;setSetting(L<span class="stringliteral">&quot;fullscreen&quot;</span>, App.CheckboxFullscreen-&gt;isChecked());</div><div class="line"></div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (App.Settings-&gt;save())</div><div class="line"> {</div><div class="line"> App.Gui-&gt;addMessageBox(L<span class="stringliteral">&quot;settings save&quot;</span>,L<span class="stringliteral">&quot;settings saved, please restart for settings to change effect&quot;</span>,<span class="stringliteral">&quot;&quot;</span>,<span class="keyword">true</span>);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="comment">// cancel/exit button clicked, tell the application to exit</span></div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( event.GUIEvent.Caller == App.ButtonExit)</div><div class="line"> {</div><div class="line"> App.ShouldQuit = <span class="keyword">true</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">default</span>:</div><div class="line"> <span class="keywordflow">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"><span class="keyword">private</span>:</div><div class="line"> SAppContext &amp; App;</div><div class="line">};</div></div><!-- fragment --><p> Function to create a video settings dialog This dialog shows the current settings from the configuration xml and allows them to be changed </p><div class="fragment"><div class="line"><span class="keywordtype">void</span> createSettingsDialog(SAppContext&amp; app)</div><div class="line">{</div><div class="line"> <span class="comment">// first get rid of alpha in gui</span></div><div class="line"> <span class="keywordflow">for</span> (irr::s32 i=0; i&lt;irr::gui::EGDC_COUNT ; ++i)</div><div class="line"> {</div><div class="line"> irr::video::SColor col = app.Gui-&gt;getSkin()-&gt;getColor((irr::gui::EGUI_DEFAULT_COLOR)i);</div><div class="line"> col.setAlpha(255);</div><div class="line"> app.Gui-&gt;getSkin()-&gt;setColor((irr::gui::EGUI_DEFAULT_COLOR)i, col);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//create video settings windows</span></div><div class="line"> gui::IGUIWindow* windowSettings = app.Gui-&gt;addWindow(rect&lt;s32&gt;(10,10,400,400),<span class="keyword">true</span>,L<span class="stringliteral">&quot;Videosettings&quot;</span>);</div><div class="line"> app.Gui-&gt;addStaticText (L<span class="stringliteral">&quot;Select your desired video settings&quot;</span>, rect&lt; s32 &gt;(10,20, 200, 40), <span class="keyword">false</span>, <span class="keyword">true</span>, windowSettings);</div><div class="line"></div><div class="line"> <span class="comment">// add listbox for driver choice</span></div><div class="line"> app.Gui-&gt;addStaticText (L<span class="stringliteral">&quot;Driver&quot;</span>, rect&lt; s32 &gt;(10,50, 200, 60), <span class="keyword">false</span>, <span class="keyword">true</span>, windowSettings);</div><div class="line"> app.ListboxDriver = app.Gui-&gt;addListBox(rect&lt;s32&gt;(10,60,220,120), windowSettings, 1,<span class="keyword">true</span>);</div><div class="line"></div><div class="line"> <span class="comment">//add all available options to the driver choice listbox</span></div><div class="line"> map&lt;stringw, s32&gt;::Iterator i = app.Settings-&gt;DriverOptions.getIterator();</div><div class="line"> <span class="keywordflow">for</span>(; !i.atEnd(); i++)</div><div class="line"> app.ListboxDriver-&gt;addItem(i-&gt;getKey().c_str());</div><div class="line"></div><div class="line"> <span class="comment">//set currently selected driver</span></div><div class="line"> app.ListboxDriver-&gt;setSelected(app.Settings-&gt;getSetting(<span class="stringliteral">&quot;driver&quot;</span>).c_str());</div><div class="line"></div><div class="line"> <span class="comment">// add listbox for resolution choice</span></div><div class="line"> app.Gui-&gt;addStaticText (L<span class="stringliteral">&quot;Resolution&quot;</span>, rect&lt; s32 &gt;(10,130, 200, 140), <span class="keyword">false</span>, <span class="keyword">true</span>, windowSettings);</div><div class="line"> app.ListboxResolution = app.Gui-&gt;addListBox(rect&lt;s32&gt;(10,140,220,200), windowSettings, 1,<span class="keyword">true</span>);</div><div class="line"></div><div class="line"> <span class="comment">//add all available options to the resolution listbox</span></div><div class="line"> map&lt;stringw, dimension2du&gt;::Iterator ri = app.Settings-&gt;ResolutionOptions.getIterator();</div><div class="line"> <span class="keywordflow">for</span>(; !ri.atEnd(); ri++)</div><div class="line"> app.ListboxResolution-&gt;addItem(ri-&gt;getKey().c_str());</div><div class="line"></div><div class="line"> <span class="comment">//set currently selected resolution</span></div><div class="line"> app.ListboxResolution-&gt;setSelected(app.Settings-&gt;getSetting(<span class="stringliteral">&quot;resolution&quot;</span>).c_str());</div><div class="line"></div><div class="line"> <span class="comment">//add checkbox to toggle fullscreen, initially set to loaded setting</span></div><div class="line"> app.CheckboxFullscreen = app.Gui-&gt;addCheckBox(</div><div class="line"> app.Settings-&gt;getSettingAsBoolean(<span class="stringliteral">&quot;fullscreen&quot;</span>),</div><div class="line"> rect&lt;s32&gt;(10,220,220,240), windowSettings, -1,</div><div class="line"> L<span class="stringliteral">&quot;Fullscreen&quot;</span>);</div><div class="line"></div><div class="line"> <span class="comment">//last but not least add save button</span></div><div class="line"> app.ButtonSave = app.Gui-&gt;addButton(</div><div class="line"> rect&lt;s32&gt;(80,250,150,270), windowSettings, 2,</div><div class="line"> L<span class="stringliteral">&quot;Save video settings&quot;</span>);</div><div class="line"></div><div class="line"> <span class="comment">//exit/cancel button</span></div><div class="line"> app.ButtonExit = app.Gui-&gt;addButton(</div><div class="line"> rect&lt;s32&gt;(160,250,240,270), windowSettings, 2,</div><div class="line"> L<span class="stringliteral">&quot;Cancel and exit&quot;</span>);</div><div class="line">}</div></div><!-- fragment --><p> The main function. Creates all objects and does the XML handling. </p><div class="fragment"><div class="line"><span class="keywordtype">int</span> main()</div><div class="line">{</div><div class="line"> <span class="comment">//create new application context</span></div><div class="line"> SAppContext app;</div><div class="line"></div><div class="line"> <span class="comment">//create device creation parameters that can get overwritten by our settings file</span></div><div class="line"> SIrrlichtCreationParameters param;</div><div class="line"> param.DriverType = EDT_SOFTWARE;</div><div class="line"> param.WindowSize.set(640,480);</div><div class="line"></div><div class="line"> <span class="comment">// Try to load config.</span></div><div class="line"> <span class="comment">// I leave it as an exercise of the reader to store the configuration in the local application data folder,</span></div><div class="line"> <span class="comment">// the only logical place to store config data for games. For all other operating systems I redirect to your manuals</span></div><div class="line"> app.Settings = <span class="keyword">new</span> SettingManager(getExampleMediaPath() + <span class="stringliteral">&quot;settings.xml&quot;</span>);</div><div class="line"> <span class="keywordflow">if</span> ( !app.Settings-&gt;load() )</div><div class="line"> {</div><div class="line"> <span class="comment">// ...</span></div><div class="line"> <span class="comment">// Here add your own exception handling, for now we continue because there are defaults set in SettingManager constructor</span></div><div class="line"> <span class="comment">// ...</span></div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> <span class="comment">//settings xml loaded from disk,</span></div><div class="line"></div><div class="line"> <span class="comment">//map driversetting to driver type and test if the setting is valid</span></div><div class="line"> <span class="comment">//the DriverOptions map contains string representations mapped to to irrlicht E_DRIVER_TYPE enum</span></div><div class="line"> <span class="comment">//e.g &quot;direct3d9&quot; will become 4</span></div><div class="line"> <span class="comment">//see DriverOptions in the settingmanager class for details</span></div><div class="line"> map&lt;stringw, s32&gt;::Node* driver = app.Settings-&gt;DriverOptions.find( app.Settings-&gt;getSetting(<span class="stringliteral">&quot;driver&quot;</span>) );</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (driver)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> ( irr::IrrlichtDevice::isDriverSupported( static_cast&lt;E_DRIVER_TYPE&gt;( driver-&gt;getValue() )))</div><div class="line"> {</div><div class="line"> <span class="comment">// selected driver is supported, so we use it.</span></div><div class="line"> param.DriverType = <span class="keyword">static_cast&lt;</span>E_DRIVER_TYPE<span class="keyword">&gt;</span>( driver-&gt;getValue());</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//map resolution setting to dimension in a similar way as demonstrated above</span></div><div class="line"> map&lt;stringw, dimension2du&gt;::Node* res = app.Settings-&gt;ResolutionOptions.find( app.Settings-&gt;getSetting(<span class="stringliteral">&quot;resolution&quot;</span>) );</div><div class="line"> <span class="keywordflow">if</span> (res)</div><div class="line"> {</div><div class="line"> param.WindowSize = res-&gt;getValue();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//get fullscreen setting from config</span></div><div class="line"> param.Fullscreen = app.Settings-&gt;getSettingAsBoolean(<span class="stringliteral">&quot;fullscreen&quot;</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//create the irrlicht device using the settings</span></div><div class="line"> app.Device = createDeviceEx(param);</div><div class="line"> <span class="keywordflow">if</span> (app.Device == 0)</div><div class="line"> {</div><div class="line"> <span class="comment">// You can add your own exception handling on driver failure</span></div><div class="line"> exit(0);</div><div class="line"> }</div><div class="line"></div><div class="line"> app.Device-&gt;setWindowCaption(L<span class="stringliteral">&quot;Xmlhandling - Irrlicht engine tutorial&quot;</span>);</div><div class="line"> app.Driver = app.Device-&gt;getVideoDriver();</div><div class="line"> app.Gui = app.Device-&gt;getGUIEnvironment();</div><div class="line"></div><div class="line"> createSettingsDialog(app);</div><div class="line"></div><div class="line"> <span class="comment">//set event receiver so we can respond to gui events</span></div><div class="line"> MyEventReceiver receiver(app);</div><div class="line"> app.Device-&gt;setEventReceiver(&amp;receiver);</div><div class="line"></div><div class="line"> <span class="comment">//enter main loop</span></div><div class="line"> <span class="keywordflow">while</span> (!app.ShouldQuit &amp;&amp; app.Device-&gt;run())</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (app.Device-&gt;isWindowActive())</div><div class="line"> {</div><div class="line"> app.Driver-&gt;beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, SColor(0,200,200,200));</div><div class="line"> app.Gui-&gt;drawAll();</div><div class="line"> app.Driver-&gt;endScene();</div><div class="line"> }</div><div class="line"> app.Device-&gt;sleep(10);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//app destroys device in destructor</span></div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --> </div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.13-->
<!-- start footer part -->
<p>&nbsp;</p>
</body>
</html>