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)
{
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();
}
};
dimension2d< u32 > dimension2du
Typedef for an unsigned integer dimension.
string< wchar_t > stringw
Typedef for wide character strings.
@ EDT_SOFTWARE
The Irrlicht Engine Software renderer.
@ EDT_OPENGL
OpenGL device, available on most platforms.
@ EDT_DIRECT3D9
Direct3D 9 device, only available on Win32 platforms.
@ 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 so
<?xml version="1.0"?>
<mygame>
<video>
<setting name="driver" value="Direct3D9" >
<setting name="fullscreen" value="0" >
<setting name="resolution" value="1024x768" >
</video>
</mygame>
bool load()
{
if (!NullDevice)
return false;
if (!xml)
return false;
const stringw settingTag(L
"setting");
{
{
{
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;
}
{
SettingMap[name]=value;
}
{
}
{
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");
}
{
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.
@ 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();
}
}
IrrlichtDevice* Device;
IGUIEnvironment* Gui;
IVideoDriver* Driver;
SettingManager* Settings;
bool ShouldQuit;
IGUIButton* ButtonSave;
IGUIButton* ButtonExit;
IGUIListBox* ListboxDriver;
IGUIListBox* ListboxResolution;
IGUICheckBox* CheckboxFullscreen;
};
A typical event receiver.
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(SAppContext & a) : App(a) { }
virtual bool OnEvent(const SEvent& event)
{
{
switch ( event.GUIEvent.EventType )
{
{
if ( event.GUIEvent.Caller == App.ButtonSave )
{
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);
}
}
else if ( event.GUIEvent.Caller == App.ButtonExit)
{
App.ShouldQuit = true;
}
}
break;
}
}
return false;
}
private:
SAppContext & App;
};
@ EGET_BUTTON_CLICKED
A button was clicked.
@ EET_GUI_EVENT
An event of the graphical user interface.
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");
}
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;
SIrrlichtCreationParameters param;
param.WindowSize.set(640,480);
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.WindowSize = res->getValue();
}
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.
E_DRIVER_TYPE
An enum for all types of drivers the Irrlicht Engine supports.
IRRLICHT_API IrrlichtDevice *IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters ¶meters)
Creates an Irrlicht device with the option to specify advanced parameters.