diff options
Diffstat (limited to 'examples/25.XmlHandling/tutorial.html')
| -rw-r--r-- | examples/25.XmlHandling/tutorial.html | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/examples/25.XmlHandling/tutorial.html b/examples/25.XmlHandling/tutorial.html new file mode 100644 index 0000000..d5d28a8 --- /dev/null +++ b/examples/25.XmlHandling/tutorial.html @@ -0,0 +1,219 @@ +<!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/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 <<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>></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 <irrlicht.h></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 _IRR_WINDOWS_</span></div><div class="line"><span class="preprocessor">#pragma comment(lib, "Irrlicht.lib")</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& 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">"Software"</span>, EDT_SOFTWARE);</div><div class="line"> DriverOptions.insert(L<span class="stringliteral">"OpenGL"</span>, EDT_OPENGL);</div><div class="line"> DriverOptions.insert(L<span class="stringliteral">"Direct3D9"</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">"640x480"</span>, dimension2du(640,480));</div><div class="line"> ResolutionOptions.insert(L<span class="stringliteral">"800x600"</span>, dimension2du(800,600));</div><div class="line"> ResolutionOptions.insert(L<span class="stringliteral">"1024x768"</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">"driver"</span>, L<span class="stringliteral">"Direct3D9"</span>);</div><div class="line"> SettingMap.insert(L<span class="stringliteral">"resolution"</span>, L<span class="stringliteral">"640x480"</span>);</div><div class="line"> SettingMap.insert(L<span class="stringliteral">"fullscreen"</span>, L<span class="stringliteral">"0"</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->closeDevice();</div><div class="line"> NullDevice->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"> <pre> + <?xml version="1.0"?> + <mygame> + <video> + <setting name="driver" value="Direct3D9" /> + <setting name="fullscreen" value="0" /> + <setting name="resolution" value="1024x768" /> + </video> + </mygame> + </pre></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'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->getFileSystem()->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">"setting"</span>); <span class="comment">//we'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">"video"</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->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->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() && videoTag.equals_ignore_case(xml->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) && settingTag.equals_ignore_case(xml->getNodeName() ))</div><div class="line"> {</div><div class="line"> <span class="comment">//read in the key</span></div><div class="line"> stringw key = xml->getAttributeValueSafe(L<span class="stringliteral">"name"</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->getAttributeValueSafe(L<span class="stringliteral">"value"</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">""</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't forget to delete the xml reader</span></div><div class="line"> xml->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'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->getFileSystem()->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->writeXMLHeader();</div><div class="line"></div><div class="line"> <span class="comment">//start element mygame, you replace the label "mygame" with anything you want</span></div><div class="line"> xwriter->writeElement(L<span class="stringliteral">"mygame"</span>);</div><div class="line"> xwriter->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->writeElement(L<span class="stringliteral">"video"</span>);</div><div class="line"> xwriter->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<stringw, stringw>::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 <setting name="key" value="x" /></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->writeElement(L<span class="stringliteral">"setting"</span>,<span class="keyword">true</span>, L<span class="stringliteral">"name"</span>, i->getKey().c_str(), L<span class="stringliteral">"value"</span>,i->getValue().c_str() );</div><div class="line"> xwriter->writeLineBreak();</div><div class="line"> }</div><div class="line"> xwriter->writeLineBreak();</div><div class="line"></div><div class="line"> <span class="comment">//close video section</span></div><div class="line"> xwriter->writeClosingTag(L<span class="stringliteral">"video"</span>);</div><div class="line"> xwriter->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->writeClosingTag(L<span class="stringliteral">"mygame"</span>);</div><div class="line"></div><div class="line"> <span class="comment">//delete xml writer</span></div><div class="line"> xwriter->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& name, <span class="keyword">const</span> stringw& 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& 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& 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->getValue()</span></div><div class="line"> map<stringw, stringw>::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->getValue();</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> <span class="keywordflow">return</span> L<span class="stringliteral">""</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& 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">"1"</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& 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<stringw, s32> DriverOptions; <span class="comment">//available options for driver config</span></div><div class="line"> map<stringw, dimension2du> 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& other); <span class="comment">// defined but not implemented</span></div><div class="line"> SettingManager& operator=(<span class="keyword">const</span> SettingManager& other); <span class="comment">// defined but not implemented</span></div><div class="line"></div><div class="line"> map<stringw, stringw> 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->closeDevice();</div><div class="line"> Device->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 & 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& 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->getSelected() != -1)</div><div class="line"> App.Settings->setSetting(L<span class="stringliteral">"driver"</span>, App.ListboxDriver->getListItem(App.ListboxDriver->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->getSelected() != -1)</div><div class="line"> App.Settings->setSetting(L<span class="stringliteral">"resolution"</span>, App.ListboxResolution->getListItem(App.ListboxResolution->getSelected()));</div><div class="line"></div><div class="line"> App.Settings->setSetting(L<span class="stringliteral">"fullscreen"</span>, App.CheckboxFullscreen->isChecked());</div><div class="line"></div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (App.Settings->save())</div><div class="line"> {</div><div class="line"> App.Gui->addMessageBox(L<span class="stringliteral">"settings save"</span>,L<span class="stringliteral">"settings saved, please restart for settings to change effect"</span>,<span class="stringliteral">""</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"> }</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 & 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& 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<irr::gui::EGDC_COUNT ; ++i)</div><div class="line"> {</div><div class="line"> irr::video::SColor col = app.Gui->getSkin()->getColor((irr::gui::EGUI_DEFAULT_COLOR)i);</div><div class="line"> col.setAlpha(255);</div><div class="line"> app.Gui->getSkin()->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->addWindow(rect<s32>(10,10,400,400),<span class="keyword">true</span>,L<span class="stringliteral">"Videosettings"</span>);</div><div class="line"> app.Gui->addStaticText (L<span class="stringliteral">"Select your desired video settings"</span>, rect< s32 >(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->addStaticText (L<span class="stringliteral">"Driver"</span>, rect< s32 >(10,50, 200, 60), <span class="keyword">false</span>, <span class="keyword">true</span>, windowSettings);</div><div class="line"> app.ListboxDriver = app.Gui->addListBox(rect<s32>(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<stringw, s32>::Iterator i = app.Settings->DriverOptions.getIterator();</div><div class="line"> <span class="keywordflow">for</span>(; !i.atEnd(); i++)</div><div class="line"> app.ListboxDriver->addItem(i->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->setSelected(app.Settings->getSetting(<span class="stringliteral">"driver"</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->addStaticText (L<span class="stringliteral">"Resolution"</span>, rect< s32 >(10,130, 200, 140), <span class="keyword">false</span>, <span class="keyword">true</span>, windowSettings);</div><div class="line"> app.ListboxResolution = app.Gui->addListBox(rect<s32>(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<stringw, dimension2du>::Iterator ri = app.Settings->ResolutionOptions.getIterator();</div><div class="line"> <span class="keywordflow">for</span>(; !ri.atEnd(); ri++)</div><div class="line"> app.ListboxResolution->addItem(ri->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->setSelected(app.Settings->getSetting(<span class="stringliteral">"resolution"</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->addCheckBox(</div><div class="line"> app.Settings->getSettingAsBoolean(<span class="stringliteral">"fullscreen"</span>),</div><div class="line"> rect<s32>(10,220,220,240), windowSettings, -1,</div><div class="line"> L<span class="stringliteral">"Fullscreen"</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->addButton(</div><div class="line"> rect<s32>(80,250,150,270), windowSettings, 2,</div><div class="line"> L<span class="stringliteral">"Save video settings"</span>);</div><div class="line"></div><div class="line"> <span class="comment">//exit/cancel button</span></div><div class="line"> app.ButtonExit = app.Gui->addButton(</div><div class="line"> rect<s32>(160,250,240,270), windowSettings, 2,</div><div class="line"> L<span class="stringliteral">"Cancel and exit"</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(<span class="stringliteral">"../../media/settings.xml"</span>);</div><div class="line"> <span class="keywordflow">if</span> ( !app.Settings->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 "direct3d9" 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<stringw, s32>::Node* driver = app.Settings->DriverOptions.find( app.Settings->getSetting(<span class="stringliteral">"driver"</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<E_DRIVER_TYPE>( driver->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<</span>E_DRIVER_TYPE<span class="keyword">></span>( driver->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<stringw, dimension2du>::Node* res = app.Settings->ResolutionOptions.find( app.Settings->getSetting(<span class="stringliteral">"resolution"</span>) );</div><div class="line"> <span class="keywordflow">if</span> (res)</div><div class="line"> {</div><div class="line"> param.WindowSize = res->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->getSettingAsBoolean(<span class="stringliteral">"fullscreen"</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->setWindowCaption(L<span class="stringliteral">"Xmlhandling - Irrlicht engine tutorial"</span>);</div><div class="line"> app.Driver = app.Device->getVideoDriver();</div><div class="line"> app.Gui = app.Device->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->setEventReceiver(&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 && app.Device->run())</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (app.Device->isWindowActive())</div><div class="line"> {</div><div class="line"> app.Driver->beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, SColor(0,200,200,200));</div><div class="line"> app.Gui->drawAll();</div><div class="line"> app.Driver->endScene();</div><div class="line"> }</div><div class="line"> app.Device->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> </p> +</body> +</html> |
