Demonstrates loading and saving of configurations via XML
- Author
- Y.M. Bosman <yoran.nosp@m..bos.nosp@m.man@g.nosp@m.mail.nosp@m..com>
This demo features a fully usable system for configuration handling. The code can easily be integrated into own apps.
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
Main header file of the irrlicht, the only file needed to include.
Everything in the Irrlicht Engine can be found in this namespace.
SettingManager class.
This class loads and writes the settings and manages the options.
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.
class SettingManager
{
public:
SettingManager(const stringw& settings_file): SettingsFile(settings_file), NullDevice(0)
{
DriverOptions.insert(L"Software", EDT_SOFTWARE);
DriverOptions.insert(L"OpenGL", EDT_OPENGL);
DriverOptions.insert(L"Direct3D9", EDT_DIRECT3D9);
ResolutionOptions.insert(L"640x480", dimension2du(640,480));
ResolutionOptions.insert(L"800x600", dimension2du(800,600));
ResolutionOptions.insert(L"1024x768", dimension2du(1024,768));
SettingMap.insert(L"driver", L"Direct3D9");
SettingMap.insert(L"resolution", L"640x480");
SettingMap.insert(L"fullscreen", L"0");
}
~SettingManager()
{
if (NullDevice)
{
NullDevice->closeDevice();
NullDevice->drop();
}
};
@ EDT_NULL
Null driver, useful for applications to run the engine without visualisation.
IRRLICHT_API IrrlichtDevice *IRRCALLCONV createDevice(video::E_DRIVER_TYPE deviceType=video::EDT_SOFTWARE, const core::dimension2d< u32 > &windowSize=(core::dimension2d< u32 >(640, 480)), u32 bits=16, bool fullscreen=false, bool stencilbuffer=false, bool vsync=false, IEventReceiver *receiver=0)
Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.
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:
<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>
bool load()
{
if (!NullDevice)
return false;
if (!xml)
return false;
const stringw settingTag(L"setting");
stringw currentSection;
const stringw videoTag(L"video");
{
{
{
if (currentSection.empty() && videoTag.equals_ignore_case(xml->
getNodeName()))
{
currentSection = videoTag;
}
else if (currentSection.equals_ignore_case(videoTag) && settingTag.equals_ignore_case(xml->
getNodeName() ))
{
if (!key.empty())
{
}
}
}
break;
currentSection=L"";
break;
}
}
xml->drop();
return true;
}
bool save()
{
if (!NullDevice)
return false;
if (!xwriter)
return false;
map<stringw, stringw>::Iterator i = SettingMap.getIterator();
for(; !i.atEnd(); i++)
{
xwriter->
writeElement(L
"setting",
true, L
"name", i->getKey().c_str(), L
"value",i->getValue().c_str() );
}
return true;
}
void setSetting(const stringw& name, const stringw& value)
{
SettingMap[name]=value;
}
void setSetting(
const stringw& name,
s32 value)
{
}
stringw getSetting(
const stringw& key)
const
{
map<stringw, stringw>::Node* n = SettingMap.find(key);
if (n)
return n->getValue();
else
return L"";
}
bool getSettingAsBoolean(const stringw& key ) const
{
if (s.empty())
return false;
return s.equals_ignore_case(L"1");
}
s32 getSettingAsInteger(
const stringw& key)
const
{
if (s.empty())
return 0;
}
public:
map<stringw, s32> DriverOptions;
map<stringw, dimension2du> ResolutionOptions;
private:
SettingManager(const SettingManager& other);
SettingManager& operator=(const SettingManager& other);
map<stringw, stringw> SettingMap;
};
bool drop() const
Drops the object. Decrements the reference counter by one.
The Irrlicht device. You can create it with createDevice() or createDeviceEx().
Interface providing easy read access to a XML file.
virtual bool read()=0
Reads forward to the next xml node.
virtual EXML_NODE getNodeType() const =0
Returns the type of the current XML node.
virtual const char_type * getAttributeValueSafe(const char_type *name) const =0
Returns the value of an attribute in a safe way.
virtual const char_type * getNodeName() const =0
Returns the name of the current node.
Interface providing methods for making it easier to write XML files.
virtual void writeElement(const wchar_t *name, bool empty=false, const wchar_t *attr1Name=0, const wchar_t *attr1Value=0, const wchar_t *attr2Name=0, const wchar_t *attr2Value=0, const wchar_t *attr3Name=0, const wchar_t *attr3Value=0, const wchar_t *attr4Name=0, const wchar_t *attr4Value=0, const wchar_t *attr5Name=0, const wchar_t *attr5Value=0)=0
virtual void writeXMLHeader()=0
Writes an xml 1.0 header.
virtual void writeClosingTag(const wchar_t *name)=0
Writes the closing tag for an element. Like "</foo>".
virtual void writeLineBreak()=0
Writes a line break.
s32 strtol10(const char *in, const char **out=0)
Convert a simple string of base 10 digits into a signed 32 bit integer.
string< c8 > stringc
Typedef for character strings.
string< wchar_t > stringw
Typedef for wide character strings.
@ EXN_ELEMENT_END
End of an xml element such as </foo>.
@ EXN_ELEMENT
An xml element such as <foo>.
signed int s32
32 bit signed variable.
Application context for global variables
struct SAppContext
{
SAppContext()
: Device(0),Gui(0), Driver(0), Settings(0), ShouldQuit(false),
ButtonSave(0), ButtonExit(0), ListboxDriver(0),
ListboxResolution(0), CheckboxFullscreen(0)
{
}
~SAppContext()
{
if (Settings)
delete Settings;
if (Device)
{
Device->closeDevice();
Device->drop();
}
}
IGUIEnvironment* Gui;
IVideoDriver* Driver;
SettingManager* Settings;
bool ShouldQuit;
IGUIButton* ButtonSave;
IGUIButton* ButtonExit;
IGUIListBox* ListboxDriver;
IGUIListBox* ListboxResolution;
IGUICheckBox* CheckboxFullscreen;
};
A typical event receiver.
{
public:
MyEventReceiver(SAppContext & a) : App(a) { }
virtual bool OnEvent(
const SEvent& event)
{
{
{
case EGET_BUTTON_CLICKED:
{
{
if ( App.ListboxDriver->getSelected() != -1)
App.Settings->setSetting(L"driver", App.ListboxDriver->getListItem(App.ListboxDriver->getSelected()));
if ( App.ListboxResolution->getSelected() != -1)
App.Settings->setSetting(L"resolution", App.ListboxResolution->getListItem(App.ListboxResolution->getSelected()));
App.Settings->setSetting(L"fullscreen", App.CheckboxFullscreen->isChecked());
if (App.Settings->save())
{
App.Gui->addMessageBox(L"settings save",L"settings saved, please restart for settings to change effect","",true);
}
}
{
App.ShouldQuit = true;
}
}
break;
}
}
return false;
}
private:
SAppContext & App;
};
Interface of an object which can receive events.
gui::IGUIElement * Caller
IGUIElement who called the event.
gui::EGUI_EVENT_TYPE EventType
Type of GUI Event.
SEvents hold information about an event. See irr::IEventReceiver for details on event handling.
struct SGUIEvent GUIEvent
Function to create a video settings dialog This dialog shows the current settings from the configuration xml and allows them to be changed
void createSettingsDialog(SAppContext& app)
{
{
}
gui::IGUIWindow* windowSettings = app.Gui->addWindow(rect<s32>(10,10,400,400),
true,L
"Videosettings");
app.Gui->addStaticText (L
"Select your desired video settings",
rect< s32 >(10,20, 200, 40),
false,
true, windowSettings);
app.Gui->addStaticText (L
"Driver",
rect< s32 >(10,50, 200, 60),
false,
true, windowSettings);
app.ListboxDriver = app.Gui->addListBox(rect<s32>(10,60,220,120), windowSettings, 1,true);
map<stringw, s32>::Iterator i = app.Settings->DriverOptions.getIterator();
for(; !i.atEnd(); i++)
app.ListboxDriver->addItem(i->getKey().c_str());
app.ListboxDriver->setSelected(app.Settings->getSetting("driver").c_str());
app.Gui->addStaticText (L
"Resolution",
rect< s32 >(10,130, 200, 140),
false,
true, windowSettings);
app.ListboxResolution = app.Gui->addListBox(rect<s32>(10,140,220,200), windowSettings, 1,true);
map<stringw, dimension2du>::Iterator ri = app.Settings->ResolutionOptions.getIterator();
for(; !ri.atEnd(); ri++)
app.ListboxResolution->addItem(ri->getKey().c_str());
app.ListboxResolution->setSelected(app.Settings->getSetting("resolution").c_str());
app.CheckboxFullscreen = app.Gui->addCheckBox(
app.Settings->getSettingAsBoolean("fullscreen"),
rect<s32>(10,220,220,240), windowSettings, -1,
L"Fullscreen");
app.ButtonSave = app.Gui->addButton(
rect<s32>(80,250,150,270), windowSettings, 2,
L"Save video settings");
app.ButtonExit = app.Gui->addButton(
rect<s32>(160,250,240,270), windowSettings, 2,
L"Cancel and exit");
}
Default moveable window GUI element with border, caption and close icons.
Class representing a 32 bit ARGB color.
void setAlpha(u32 a)
Sets the alpha component of the Color.
EGUI_DEFAULT_COLOR
Enumeration for skin colors.
The main function. Creates all objects and does the XML handling.
int main()
{
SAppContext app;
app.Settings = new SettingManager("../../media/settings.xml");
if ( !app.Settings->load() )
{
}
else
{
map<stringw, s32>::Node* driver = app.Settings->DriverOptions.find( app.Settings->getSetting("driver") );
if (driver)
{
{
param.
DriverType =
static_cast<E_DRIVER_TYPE
>( driver->getValue());
}
}
map<stringw, dimension2du>::Node* res = app.Settings->ResolutionOptions.find( app.Settings->getSetting("resolution") );
if (res)
{
}
param.
Fullscreen = app.Settings->getSettingAsBoolean(
"fullscreen");
}
if (app.Device == 0)
{
exit(0);
}
app.Device->setWindowCaption(L"Xmlhandling - Irrlicht engine tutorial");
app.Driver = app.Device->getVideoDriver();
app.Gui = app.Device->getGUIEnvironment();
createSettingsDialog(app);
MyEventReceiver receiver(app);
app.Device->setEventReceiver(&receiver);
while (!app.ShouldQuit && app.Device->run())
{
if (app.Device->isWindowActive())
{
app.Driver->beginScene(true, true, SColor(0,200,200,200));
app.Gui->drawAll();
app.Driver->endScene();
}
app.Device->sleep(10);
}
return 0;
}
static bool isDriverSupported(video::E_DRIVER_TYPE driver)
Check if a driver type is supported by the engine.
dimension2d< T > & set(const T &width, const T &height)
Set to new values.
IRRLICHT_API IrrlichtDevice *IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters ¶meters)
Creates an Irrlicht device with the option to specify advanced parameters.
Structure for holding Irrlicht Device creation parameters.
core::dimension2d< u32 > WindowSize
Size of the window or the video mode in fullscreen mode. Default: 800x600.
video::E_DRIVER_TYPE DriverType
Type of video driver used to render graphics.
bool Fullscreen
Should be set to true if the device should run in fullscreen.