aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/examples/25.XmlHandling/main.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-03-28 22:28:34 +1000
committerDavid Walter Seikel2016-03-28 22:28:34 +1000
commit7028cbe09c688437910a25623098762bf0fa592d (patch)
tree10b5af58277d9880380c2251f109325542c4e6eb /src/others/irrlicht-1.8.1/examples/25.XmlHandling/main.cpp
parentMove lemon to the src/others directory. (diff)
downloadSledjHamr-7028cbe09c688437910a25623098762bf0fa592d.zip
SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.gz
SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.bz2
SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.xz
Move Irrlicht to src/others.
Diffstat (limited to 'src/others/irrlicht-1.8.1/examples/25.XmlHandling/main.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/examples/25.XmlHandling/main.cpp505
1 files changed, 505 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/examples/25.XmlHandling/main.cpp b/src/others/irrlicht-1.8.1/examples/25.XmlHandling/main.cpp
new file mode 100644
index 0000000..3eb261d
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/examples/25.XmlHandling/main.cpp
@@ -0,0 +1,505 @@
1/** Example 025 Xml Handling
2
3Demonstrates loading and saving of configurations via XML
4
5@author Y.M. Bosman \<yoran.bosman@gmail.com\>
6
7This demo features a fully usable system for configuration handling. The code
8can easily be integrated into own apps.
9
10*/
11
12#include <irrlicht.h>
13
14using namespace irr;
15using namespace core;
16using namespace scene;
17using namespace video;
18using namespace io;
19using namespace gui;
20
21#ifdef _IRR_WINDOWS_
22#pragma comment(lib, "Irrlicht.lib")
23#endif
24
25
26/* SettingManager class.
27
28This class loads and writes the settings and manages the options.
29
30The class makes use of irrMap which is a an associative arrays using a
31red-black tree it allows easy mapping of a key to a value, along the way there
32is some information on how to use it.
33*/
34
35class SettingManager
36{
37public:
38
39 // Construct setting managers and set default settings
40 SettingManager(const stringw& settings_file): SettingsFile(settings_file), NullDevice(0)
41 {
42 // Irrlicht null device, we want to load settings before we actually created our device, therefore, nulldevice
43 NullDevice = irr::createDevice(irr::video::EDT_NULL);
44
45 //DriverOptions is an irrlicht map,
46 //we can insert values in the map in two ways by calling insert(key,value) or by using the [key] operator
47 //the [] operator overrides values if they already exist
48 DriverOptions.insert(L"Software", EDT_SOFTWARE);
49 DriverOptions.insert(L"OpenGL", EDT_OPENGL);
50 DriverOptions.insert(L"Direct3D9", EDT_DIRECT3D9);
51
52 //some resolution options
53 ResolutionOptions.insert(L"640x480", dimension2du(640,480));
54 ResolutionOptions.insert(L"800x600", dimension2du(800,600));
55 ResolutionOptions.insert(L"1024x768", dimension2du(1024,768));
56
57 //our preferred defaults
58 SettingMap.insert(L"driver", L"Direct3D9");
59 SettingMap.insert(L"resolution", L"640x480");
60 SettingMap.insert(L"fullscreen", L"0"); //0 is false
61 }
62
63 // Destructor, you could store settings automatically on exit of your
64 // application if you wanted to in our case we simply drop the
65 // nulldevice
66 ~SettingManager()
67 {
68 if (NullDevice)
69 {
70 NullDevice->closeDevice();
71 NullDevice->drop();
72 }
73 };
74
75 /*
76 Load xml from disk, overwrite default settings
77 The xml we are trying to load has the following structure
78 settings nested in sections nested in the root node, like so
79 <pre>
80 <?xml version="1.0"?>
81 <mygame>
82 <video>
83 <setting name="driver" value="Direct3D9" />
84 <setting name="fullscreen" value="0" />
85 <setting name="resolution" value="1024x768" />
86 </video>
87 </mygame>
88 </pre>
89 */
90 bool load()
91 {
92 //if not able to create device don't attempt to load
93 if (!NullDevice)
94 return false;
95
96 irr::io::IXMLReader* xml = NullDevice->getFileSystem()->createXMLReader(SettingsFile); //create xml reader
97 if (!xml)
98 return false;
99
100 const stringw settingTag(L"setting"); //we'll be looking for this tag in the xml
101 stringw currentSection; //keep track of our current section
102 const stringw videoTag(L"video"); //constant for videotag
103
104 //while there is more to read
105 while (xml->read())
106 {
107 //check the node type
108 switch (xml->getNodeType())
109 {
110 //we found a new element
111 case irr::io::EXN_ELEMENT:
112 {
113 //we currently are in the empty or mygame section and find the video tag so we set our current section to video
114 if (currentSection.empty() && videoTag.equals_ignore_case(xml->getNodeName()))
115 {
116 currentSection = videoTag;
117 }
118 //we are in the video section and we find a setting to parse
119 else if (currentSection.equals_ignore_case(videoTag) && settingTag.equals_ignore_case(xml->getNodeName() ))
120 {
121 //read in the key
122 stringw key = xml->getAttributeValueSafe(L"name");
123 //if there actually is a key to set
124 if (!key.empty())
125 {
126 //set the setting in the map to the value,
127 //the [] operator overrides values if they already exist or inserts a new key value
128 //pair into the settings map if it was not defined yet
129 SettingMap[key] = xml->getAttributeValueSafe(L"value");
130 }
131 }
132
133 //..
134 // You can add your own sections and tags to read in here
135 //..
136 }
137 break;
138
139 //we found the end of an element
140 case irr::io::EXN_ELEMENT_END:
141 //we were at the end of the video section so we reset our tag
142 currentSection=L"";
143 break;
144 }
145 }
146
147 // don't forget to delete the xml reader
148 xml->drop();
149
150 return true;
151 }
152
153 // Save the xml to disk. We use the nulldevice.
154 bool save()
155 {
156
157 //if not able to create device don't attempt to save
158 if (!NullDevice)
159 return false;
160
161 //create xml writer
162 irr::io::IXMLWriter* xwriter = NullDevice->getFileSystem()->createXMLWriter( SettingsFile );
163 if (!xwriter)
164 return false;
165
166 //write out the obligatory xml header. Each xml-file needs to have exactly one of those.
167 xwriter->writeXMLHeader();
168
169 //start element mygame, you replace the label "mygame" with anything you want
170 xwriter->writeElement(L"mygame");
171 xwriter->writeLineBreak(); //new line
172
173 //start section with video settings
174 xwriter->writeElement(L"video");
175 xwriter->writeLineBreak(); //new line
176
177 // getIterator gets us a pointer to the first node of the settings map
178 // every iteration we increase the iterator which gives us the next map node
179 // until we reach the end we write settings one by one by using the nodes key and value functions
180 map<stringw, stringw>::Iterator i = SettingMap.getIterator();
181 for(; !i.atEnd(); i++)
182 {
183 //write element as <setting name="key" value="x" />
184 //the second parameter indicates this is an empty element with no children, just attributes
185 xwriter->writeElement(L"setting",true, L"name", i->getKey().c_str(), L"value",i->getValue().c_str() );
186 xwriter->writeLineBreak();
187 }
188 xwriter->writeLineBreak();
189
190 //close video section
191 xwriter->writeClosingTag(L"video");
192 xwriter->writeLineBreak();
193
194 //..
195 // You can add writing sound settings, savegame information etc
196 //..
197
198 //close mygame section
199 xwriter->writeClosingTag(L"mygame");
200
201 //delete xml writer
202 xwriter->drop();
203
204 return true;
205 }
206
207 // Set setting in our manager
208 void setSetting(const stringw& name, const stringw& value)
209 {
210 SettingMap[name]=value;
211 }
212
213 // set setting overload to quickly assign integers to our setting map
214 void setSetting(const stringw& name, s32 value)
215 {
216 SettingMap[name]=stringw(value);
217 }
218
219 // Get setting as string
220 stringw getSetting(const stringw& key) const
221 {
222 //the find function or irrmap returns a pointer to a map Node
223 //if the key can be found, otherwise it returns null
224 //the map node has the function getValue and getKey, as we already know the key, we return node->getValue()
225 map<stringw, stringw>::Node* n = SettingMap.find(key);
226 if (n)
227 return n->getValue();
228 else
229 return L"";
230 }
231
232 //
233 bool getSettingAsBoolean(const stringw& key ) const
234 {
235 stringw s = getSetting(key);
236 if (s.empty())
237 return false;
238 return s.equals_ignore_case(L"1");
239 }
240
241 //
242 s32 getSettingAsInteger(const stringw& key) const
243 {
244 //we implicitly cast to string instead of stringw because strtol10 does not accept wide strings
245 const stringc s = getSetting(key);
246 if (s.empty())
247 return 0;
248
249 return strtol10(s.c_str());
250 }
251
252public:
253 map<stringw, s32> DriverOptions; //available options for driver config
254 map<stringw, dimension2du> ResolutionOptions; //available options for resolution config
255private:
256 SettingManager(const SettingManager& other); // defined but not implemented
257 SettingManager& operator=(const SettingManager& other); // defined but not implemented
258
259 map<stringw, stringw> SettingMap; //current config
260
261 stringw SettingsFile; // location of the xml, usually the
262 irr::IrrlichtDevice* NullDevice;
263};
264
265/*
266Application context for global variables
267*/
268struct SAppContext
269{
270 SAppContext()
271 : Device(0),Gui(0), Driver(0), Settings(0), ShouldQuit(false),
272 ButtonSave(0), ButtonExit(0), ListboxDriver(0),
273 ListboxResolution(0), CheckboxFullscreen(0)
274 {
275 }
276
277 ~SAppContext()
278 {
279 if (Settings)
280 delete Settings;
281
282 if (Device)
283 {
284 Device->closeDevice();
285 Device->drop();
286 }
287 }
288
289 IrrlichtDevice* Device;
290 IGUIEnvironment* Gui;
291 IVideoDriver* Driver;
292 SettingManager* Settings;
293 bool ShouldQuit;
294
295 //settings dialog
296 IGUIButton* ButtonSave;
297 IGUIButton* ButtonExit;
298 IGUIListBox* ListboxDriver;
299 IGUIListBox* ListboxResolution;
300 IGUICheckBox* CheckboxFullscreen;
301};
302
303/*
304 A typical event receiver.
305*/
306class MyEventReceiver : public IEventReceiver
307{
308public:
309 MyEventReceiver(SAppContext & a) : App(a) { }
310
311 virtual bool OnEvent(const SEvent& event)
312 {
313 if (event.EventType == EET_GUI_EVENT )
314 {
315 switch ( event.GUIEvent.EventType )
316 {
317 //handle button click events
318 case EGET_BUTTON_CLICKED:
319 {
320 //Our save button was called so we obtain the settings from our dialog and save them
321 if ( event.GUIEvent.Caller == App.ButtonSave )
322 {
323 //if there is a selection write it
324 if ( App.ListboxDriver->getSelected() != -1)
325 App.Settings->setSetting(L"driver", App.ListboxDriver->getListItem(App.ListboxDriver->getSelected()));
326
327 //if there is a selection write it
328 if ( App.ListboxResolution->getSelected() != -1)
329 App.Settings->setSetting(L"resolution", App.ListboxResolution->getListItem(App.ListboxResolution->getSelected()));
330
331 App.Settings->setSetting(L"fullscreen", App.CheckboxFullscreen->isChecked());
332
333
334 if (App.Settings->save())
335 {
336 App.Gui->addMessageBox(L"settings save",L"settings saved, please restart for settings to change effect","",true);
337 }
338 }
339 // cancel/exit button clicked, tell the application to exit
340 else if ( event.GUIEvent.Caller == App.ButtonExit)
341 {
342 App.ShouldQuit = true;
343 }
344 }
345 break;
346 }
347 }
348
349 return false;
350 }
351
352private:
353 SAppContext & App;
354};
355
356
357/*
358Function to create a video settings dialog
359This dialog shows the current settings from the configuration xml and allows them to be changed
360*/
361void createSettingsDialog(SAppContext& app)
362{
363 // first get rid of alpha in gui
364 for (irr::s32 i=0; i<irr::gui::EGDC_COUNT ; ++i)
365 {
366 irr::video::SColor col = app.Gui->getSkin()->getColor((irr::gui::EGUI_DEFAULT_COLOR)i);
367 col.setAlpha(255);
368 app.Gui->getSkin()->setColor((irr::gui::EGUI_DEFAULT_COLOR)i, col);
369 }
370
371 //create video settings windows
372 gui::IGUIWindow* windowSettings = app.Gui->addWindow(rect<s32>(10,10,400,400),true,L"Videosettings");
373 app.Gui->addStaticText (L"Select your desired video settings", rect< s32 >(10,20, 200, 40), false, true, windowSettings);
374
375 // add listbox for driver choice
376 app.Gui->addStaticText (L"Driver", rect< s32 >(10,50, 200, 60), false, true, windowSettings);
377 app.ListboxDriver = app.Gui->addListBox(rect<s32>(10,60,220,120), windowSettings, 1,true);
378
379 //add all available options to the driver choice listbox
380 map<stringw, s32>::Iterator i = app.Settings->DriverOptions.getIterator();
381 for(; !i.atEnd(); i++)
382 app.ListboxDriver->addItem(i->getKey().c_str());
383
384 //set currently selected driver
385 app.ListboxDriver->setSelected(app.Settings->getSetting("driver").c_str());
386
387 // add listbox for resolution choice
388 app.Gui->addStaticText (L"Resolution", rect< s32 >(10,130, 200, 140), false, true, windowSettings);
389 app.ListboxResolution = app.Gui->addListBox(rect<s32>(10,140,220,200), windowSettings, 1,true);
390
391 //add all available options to the resolution listbox
392 map<stringw, dimension2du>::Iterator ri = app.Settings->ResolutionOptions.getIterator();
393 for(; !ri.atEnd(); ri++)
394 app.ListboxResolution->addItem(ri->getKey().c_str());
395
396 //set currently selected resolution
397 app.ListboxResolution->setSelected(app.Settings->getSetting("resolution").c_str());
398
399 //add checkbox to toggle fullscreen, initially set to loaded setting
400 app.CheckboxFullscreen = app.Gui->addCheckBox(
401 app.Settings->getSettingAsBoolean("fullscreen"),
402 rect<s32>(10,220,220,240), windowSettings, -1,
403 L"Fullscreen");
404
405 //last but not least add save button
406 app.ButtonSave = app.Gui->addButton(
407 rect<s32>(80,250,150,270), windowSettings, 2,
408 L"Save video settings");
409
410 //exit/cancel button
411 app.ButtonExit = app.Gui->addButton(
412 rect<s32>(160,250,240,270), windowSettings, 2,
413 L"Cancel and exit");
414}
415
416/*
417The main function. Creates all objects and does the XML handling.
418*/
419int main()
420{
421 //create new application context
422 SAppContext app;
423
424 //create device creation parameters that can get overwritten by our settings file
425 SIrrlichtCreationParameters param;
426 param.DriverType = EDT_SOFTWARE;
427 param.WindowSize.set(640,480);
428
429 // Try to load config.
430 // I leave it as an exercise of the reader to store the configuration in the local application data folder,
431 // the only logical place to store config data for games. For all other operating systems I redirect to your manuals
432 app.Settings = new SettingManager("../../media/settings.xml");
433 if ( !app.Settings->load() )
434 {
435 // ...
436 // Here add your own exception handling, for now we continue because there are defaults set in SettingManager constructor
437 // ...
438 }
439 else
440 {
441 //settings xml loaded from disk,
442
443 //map driversetting to driver type and test if the setting is valid
444 //the DriverOptions map contains string representations mapped to to irrlicht E_DRIVER_TYPE enum
445 //e.g "direct3d9" will become 4
446 //see DriverOptions in the settingmanager class for details
447 map<stringw, s32>::Node* driver = app.Settings->DriverOptions.find( app.Settings->getSetting("driver") );
448
449 if (driver)
450 {
451 if ( irr::IrrlichtDevice::isDriverSupported( static_cast<E_DRIVER_TYPE>( driver->getValue() )))
452 {
453 // selected driver is supported, so we use it.
454 param.DriverType = static_cast<E_DRIVER_TYPE>( driver->getValue());
455 }
456 }
457
458 //map resolution setting to dimension in a similar way as demonstrated above
459 map<stringw, dimension2du>::Node* res = app.Settings->ResolutionOptions.find( app.Settings->getSetting("resolution") );
460 if (res)
461 {
462 param.WindowSize = res->getValue();
463 }
464
465 //get fullscreen setting from config
466 param.Fullscreen = app.Settings->getSettingAsBoolean("fullscreen");
467 }
468
469 //create the irrlicht device using the settings
470 app.Device = createDeviceEx(param);
471 if (app.Device == 0)
472 {
473 // You can add your own exception handling on driver failure
474 exit(0);
475 }
476
477 app.Device->setWindowCaption(L"Xmlhandling - Irrlicht engine tutorial");
478 app.Driver = app.Device->getVideoDriver();
479 app.Gui = app.Device->getGUIEnvironment();
480
481 createSettingsDialog(app);
482
483 //set event receiver so we can respond to gui events
484 MyEventReceiver receiver(app);
485 app.Device->setEventReceiver(&receiver);
486
487 //enter main loop
488 while (!app.ShouldQuit && app.Device->run())
489 {
490 if (app.Device->isWindowActive())
491 {
492 app.Driver->beginScene(true, true, SColor(0,200,200,200));
493 app.Gui->drawAll();
494 app.Driver->endScene();
495 }
496 app.Device->sleep(10);
497 }
498
499 //app destroys device in destructor
500
501 return 0;
502}
503
504/*
505**/