many changes and refactoring

master
Eduardo Bart 13 years ago
parent 6c05ee0e82
commit 8ef1b28546

@ -47,17 +47,23 @@ ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(SOURCES
# game sources
src/main.cpp
src/allocator.cpp
# game net
src/protocollogin.cpp
# framework core
src/framework/core/global.cpp
src/framework/core/dispatcher.cpp
src/framework/core/configs.cpp
src/framework/core/resources.cpp
src/framework/core/engine.cpp
src/framework/core/modules.cpp
src/framework/core/allocator.cpp
# framework otml
src/framework/otml/otmlemitter.cpp
src/framework/otml/otmlparser.cpp
src/framework/otml/otmlnode.cpp
# framework script
src/framework/script/scriptable.cpp
@ -66,11 +72,10 @@ SET(SOURCES
# framework utilities
src/framework/util/color.cpp
src/framework/util/util.cpp
src/framework/util/translator.cpp
src/framework/util/convert.cpp
src/framework/util/logger.cpp
src/framework/util/rsa.cpp
src/framework/util/apngloader.cpp
src/framework/util/fml.cpp
# framework graphics
src/framework/graphics/image.cpp
@ -108,6 +113,7 @@ SET(SOURCES
src/framework/net/protocol.cpp
src/framework/net/inputmessage.cpp
src/framework/net/outputmessage.cpp
src/framework/net/rsa.cpp
)
IF(WIN32)

@ -1,25 +1,25 @@
window#enterGameWindow
%window#enterGameWindow
title: Enter Game
size: [236, 178]
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
onLoad: self.locked = true
label#accountNameLabel
%label#accountNameLabel
text: Account name
anchors.left: parent.left
anchors.top: parent.top
margin.left: 18
margin.top: 33
label#passwordLabel
%label#passwordLabel
text: "Password:"
anchors.left: parent.left
anchors.top: parent.top
margin.left: 18
margin.top: 62
label#createAccountLabel
%label#createAccountLabel
text: |
If you don't have
an account yet
@ -28,7 +28,7 @@ window#enterGameWindow
margin.left: 18
margin.top: 87
button#createAccountButton
%button#createAccountButton
text: Create Account
anchors.left: parent.left
anchors.top: parent.top
@ -36,7 +36,7 @@ window#enterGameWindow
margin.left: 132
onClick: messageBox("Error", "Not implemented yet")
button#okButton
%button#okButton
text: Ok
size: [43, 20]
anchors.right: parent.right
@ -45,7 +45,7 @@ window#enterGameWindow
margin.right: 66
onClick: enterGame_onOkClicked()
button#cancelButton
%button#cancelButton
text: Cancel
size: [43, 20]
anchors.right: parent.right
@ -54,13 +54,13 @@ window#enterGameWindow
margin.right: 13
onClick: self.parent:destroy()
textEdit#accountNameTextEdit
%textEdit#accountNameTextEdit
anchors.right: parent.right
anchors.top: parent.top
margin.top: 32
margin.right: 18
textEdit#passwordTextEdit
%textEdit#passwordTextEdit
anchors.right: parent.right
anchors.top: parent.top
margin.top: 61

@ -1,11 +1,11 @@
window#infoWindow
%window#infoWindow
title: Info
size: [244, 221]
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
onLoad: self.locked = true
panel#infoPanel
%panel#infoPanel
skin: flatPanel
size: [208, 129]
anchors.left: parent.left
@ -13,7 +13,7 @@ window#infoWindow
margin.top: 32
margin.left: 18
label#infoLabel
%label#infoLabel
align: center
text: |-
OTClient
@ -23,21 +23,21 @@ window#infoWindow
anchors.top: parent.top
margin.top: 20
lineDecoration#bottomSeparator
%lineDecoration#bottomSeparator
size: [190, 2]
anchors.left: parent.left
anchors.top: parent.top
margin.top: 83
margin.left: 9
label#websiteLabel
%label#websiteLabel
text: Official Website
anchors.left: parent.left
anchors.bottom: parent.bottom
margin.bottom: 14
margin.left: 9
button#websiteButton
%button#websiteButton
text: Github Page
size: [80,22]
anchors.right: parent.right
@ -45,7 +45,7 @@ window#infoWindow
margin.bottom: 9
margin.right: 9
lineDecoration#bottomSeparator
%lineDecoration#bottomSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
@ -53,7 +53,7 @@ window#infoWindow
margin.left: 13
margin.right: 13
button#okButton
%button#okButton
text: Ok
size: [43, 20]
anchors.left: parent.left

@ -1,11 +1,11 @@
panel#background
%panel#background
skin: mainMenuBackground
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
panel#icos4d
%panel#icos4d
skin:
image: /skins/lightness/mouse.png
anchors.left: parent.left
@ -13,7 +13,7 @@ panel#background
margin.left: -2
margin.top: 70
panel#mouse
%panel#mouse
skin:
image: /skins/lightness/icos4d.png
anchors.right: parent.right
@ -21,7 +21,7 @@ panel#background
margin.left: 60
margin.top: 70
panel#mainMenu
%panel#mainMenu
skin: roundedGridPanel
size: [117, 171]
anchors.left: parent.left
@ -29,35 +29,35 @@ panel#background
margin.left: 60
margin.bottom: 70
button#enterGameButton
%button#enterGameButton
text: Enter Game
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 16
onClick: UI.load("entergamewindow.yml")
button#accessAccountButton
%button#accessAccountButton
text: Access Account
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 46
onClick: messageBox("Error", "Not implemented yet")
button#optionsButton
%button#optionsButton
text: Options
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 76
onClick: UI.load("optionswindow.yml")
button#infoButton
%button#infoButton
text: Info
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 106
onClick: UI.load("infowindow.yml")
button#exitGameButton
%button#exitGameButton
text: Exit
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter

@ -1,4 +1,4 @@
window#optionsWindow
%window#optionsWindow
title: Options
size: [286, 262]
anchors.horizontalCenter: parent.horizontalCenter
@ -6,14 +6,14 @@ window#optionsWindow
onLoad: self.locked = true
# general
button#generalButton
%button#generalButton
text: General
anchors.left: parent.left
anchors.top: parent.top
margin.left: 18
margin.top: 32
label#generalLabel
%label#generalLabel
text: |-
Change general
game options
@ -23,14 +23,14 @@ window#optionsWindow
margin.top: 29
# graphics
button#graphicsButton
%button#graphicsButton
text: Graphics
anchors.left: parent.left
anchors.top: parent.top
margin.left: 18
margin.top: 65
label#graphicsLabel
%label#graphicsLabel
text: |-
Change graphics and
performance settings
@ -40,14 +40,14 @@ window#optionsWindow
margin.top: 62
# console
button#consoleButton
%button#consoleButton
text: Console
anchors.left: parent.left
anchors.top: parent.top
margin.left: 18
margin.top: 98
label#consoleLabel
%label#consoleLabel
text: Customise the console
anchors.left: parent.left
anchors.top: parent.top
@ -55,21 +55,21 @@ window#optionsWindow
margin.top: 95
# hotkeys
button#hotkeysButton
%button#hotkeysButton
text: Hotkeys
anchors.left: parent.left
anchors.top: parent.top
margin.left: 18
margin.top: 131
label#hotkeysLabel
%label#hotkeysLabel
text: Edit your hotkey texts
anchors.left: parent.left
anchors.top: parent.top
margin.left: 117
margin.top: 128
lineDecoration#middleSeparator
%lineDecoration#middleSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
@ -78,14 +78,14 @@ window#optionsWindow
margin.right: 18
# motd
button#motdButton
%button#motdButton
text: Motd
anchors.left: parent.left
anchors.bottom: parent.bottom
margin.left: 18
margin.bottom: 60
label#motdLabel
%label#motdLabel
text: |
Show the most recent
Message of the Day
@ -94,7 +94,7 @@ window#optionsWindow
margin.left: 117
margin.bottom: 56
lineDecoration#bottomSeparator
%lineDecoration#bottomSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
@ -103,7 +103,7 @@ window#optionsWindow
margin.right: 13
# ok button
button#okButton
%button#okButton
text: Ok
size: [43, 20]
anchors.right: parent.right

@ -1,15 +1,15 @@
window#messageBoxWindow
%window#messageBoxWindow
size: [192, 78]
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
label#textLabel
%label#textLabel
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
margin.top: 27
button#okButton
%button#okButton
text: Ok
size: [43, 20]
anchors.right: parent.right

@ -0,0 +1,22 @@
#ifndef CONST_H
#define CONST_H
enum AlignmentFlag {
AlignLeft = 1,
AlignRight = 2,
AlignTop = 4,
AlignBottom = 8,
AlignHorizontalCenter = 16,
AlignVerticalCenter = 32,
AlignTopLeft = AlignTop | AlignLeft,
AlignTopRight = AlignTop | AlignRight,
AlignBottomLeft = AlignBottom | AlignLeft,
AlignBottomRight = AlignBottom | AlignRight,
AlignLeftCenter = AlignLeft | AlignVerticalCenter,
AlignRightCenter = AlignRight | AlignVerticalCenter,
AlignTopCenter = AlignTop | AlignHorizontalCenter,
AlignBottomCenter = AlignBottom | AlignHorizontalCenter,
AlignCenter = AlignVerticalCenter | AlignHorizontalCenter
};
#endif // CONST_H

@ -1,3 +1,27 @@
/* The MIT License
*
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifdef _DEBUG_MEMORY
#include "allocator.h"
@ -101,6 +125,13 @@ static void addr2line(void *address, const char* name, bool viewSource = false)
}
}
}
} else {
pos = (char*)strrchr(name, '/');
if(!pos)
pos = (char*) name;
else
pos++;
printf("%p (%s)", address, pos);
}
printf("\n");

@ -1,3 +1,27 @@
/* The MIT License
*
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef __ALLOCATOR_H__
#define __ALLOCATOR_H__
@ -31,7 +55,7 @@ struct block_hash : std::unary_function<AllocationBlock *, std::size_t> {
std::size_t seed = 0;
boost::hash_combine(seed, block->bytes);
for(int i=0;i<3;++i) {
for(int i=0;i<4;++i) {
if(i < block->backtraceSize)
boost::hash_combine(seed, block->backtraceBuffer[i]);
else

@ -22,9 +22,10 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/configs.h>
#include <core/resources.h>
#include <otml/otml.h>
Configs g_configs;
@ -32,18 +33,18 @@ bool Configs::load(const std::string& fileName)
{
m_fileName = fileName;
if(!g_resources.fileExists(fileName))
return false;
std::stringstream fin;
if(!g_resources.loadFile(fileName, fin))
return false;
try {
FML::Parser parser(fin, fileName);
FML::Node* doc = parser.getDocument();
foreach(FML::Node* node, *doc)
m_confsMap[node->tag()] = node->value();
} catch(FML::Exception e) {
flogError("ERROR: Malformed config file: %s", e.what());
OTMLParser parser(fin, fileName);
parser.getDocument()->read(&m_confsMap);
} catch(OTMLException e) {
error("ERROR: Malformed config file: ", e.what());
return false;
}
@ -53,9 +54,8 @@ bool Configs::load(const std::string& fileName)
void Configs::save()
{
if(!m_fileName.empty()) {
FML::Emitter emitter;
FML::Node *doc = emitter.createDocument();
doc->write(m_confsMap);
OTMLEmitter emitter;
emitter.createDocument()->write(m_confsMap);
g_resources.saveFile(m_fileName, emitter.emitDocument());
}
}

@ -25,13 +25,13 @@
#ifndef CONFIGS_H
#define CONFIGS_H
#include <prerequisites.h>
#include <global.h>
struct ConfigValueProxy {
operator std::string() const { return convert_cast<std::string>(value); }
operator float() const { return convert_cast<float>(value); }
operator int() const { return convert_cast<int>(value); }
operator bool() const { return convert_cast<bool>(value); }
operator std::string() const { return convert<std::string>(value); }
operator float() const { return convert<float>(value); }
operator int() const { return convert<int>(value); }
operator bool() const { return convert<bool>(value); }
std::string value;
};
@ -41,7 +41,9 @@ public:
bool load(const std::string& fileName);
void save();
template<class T> void set(const std::string& key, const T& value) { m_confsMap[key] = convert_cast<std::string>(value); }
template<class T>
void set(const std::string& key, const T& value) { m_confsMap[key] = convert<std::string>(value); }
ConfigValueProxy get(const std::string& key) { return ConfigValueProxy{m_confsMap[key]}; }
private:

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/dispatcher.h>
#include <core/engine.h>
@ -54,12 +54,12 @@ void Dispatcher::poll()
}
}
void Dispatcher::scheduleTask(const SimpleCallback& callback, int delay)
void Dispatcher::scheduleTask(const boost::function<void()>& callback, int delay)
{
m_scheduledTaskList.push(new ScheduledTask(g_engine.getCurrentFrameTicks() + delay, callback));
}
void Dispatcher::addTask(const SimpleCallback& callback, bool pushFront)
void Dispatcher::addTask(const boost::function<void()>& callback, bool pushFront)
{
if(pushFront)
m_taskList.push_front(callback);

@ -25,15 +25,19 @@
#ifndef DISPATCHER_H
#define DISPATCHER_H
#include <prerequisites.h>
#include <global.h>
#include <queue>
#include <boost/bind.hpp>
#include <boost/function.hpp>
class ScheduledTask {
public:
inline ScheduledTask(const SimpleCallback& _callback) : ticks(0), callback(_callback) { }
inline ScheduledTask(int _ticks, const SimpleCallback& _callback) : ticks(_ticks), callback(_callback) { }
inline ScheduledTask(const boost::function<void()>& _callback) : ticks(0), callback(_callback) { }
inline ScheduledTask(int _ticks, const boost::function<void()>& _callback) : ticks(_ticks), callback(_callback) { }
inline bool operator<(const ScheduledTask& other) const { return ticks > other.ticks; }
int ticks;
SimpleCallback callback;
boost::function<void()> callback;
};
class lessScheduledTask : public std::binary_function<ScheduledTask*&, ScheduledTask*&, bool> {
@ -53,13 +57,13 @@ public:
void poll();
/// Add an event
void addTask(const SimpleCallback& callback, bool pushFront = false);
void addTask(const boost::function<void()>& callback, bool pushFront = false);
/// Schedula an event
void scheduleTask(const SimpleCallback& callback, int delay);
void scheduleTask(const boost::function<void()>& callback, int delay);
private:
std::list<SimpleCallback> m_taskList;
std::list<boost::function<void()>> m_taskList;
std::priority_queue<ScheduledTask*, std::vector<ScheduledTask*>, lessScheduledTask> m_scheduledTaskList;
};

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/engine.h>
#include <core/platform.h>
#include <core/dispatcher.h>
@ -78,7 +78,7 @@ void Engine::run()
// check if root container has elements
const UIContainerPtr& rootContainer = UIContainer::getRoot();
if(rootContainer->getChildCount() == 0)
logFatal("FATAL ERROR: no ui loaded at all, no reason to continue running");
fatal("FATAL ERROR: no ui loaded at all, no reason to continue running");
std::string fpsText;
Size fpsTextSize;
@ -106,7 +106,7 @@ void Engine::run()
frameCount = 0;
// update fps text
fpsText = fmt("FPS: %d", fps);
fpsText = make_string("FPS: ", fps);
fpsTextSize = defaultFont->calculateTextRectSize(fpsText);
}
}

@ -25,7 +25,7 @@
#ifndef ENGINE_H
#define ENGINE_H
#include <prerequisites.h>
#include <global.h>
#include <core/input.h>
class Engine

@ -21,29 +21,5 @@
* THE SOFTWARE.
*/
#include <util/util.h>
#include <boost/algorithm/string.hpp>
AlignmentFlag parseAlignment(std::string aligment)
{
boost::to_lower(aligment);
boost::erase_all(aligment, " ");
if(aligment == "topleft")
return AlignTopLeft;
else if(aligment == "topright")
return AlignTopRight;
else if(aligment == "bottomleft")
return AlignBottomLeft;
else if(aligment == "bottomright")
return AlignBottomRight;
else if(aligment == "left")
return AlignLeftCenter;
else if(aligment == "right")
return AlignRightCenter;
else if(aligment == "top")
return AlignTopCenter;
else if(aligment == "bottom")
return AlignBottomCenter;
else
return AlignCenter;
}
#include "global.h"

@ -25,7 +25,7 @@
#ifndef INPUT_H
#define INPUT_H
#include <prerequisites.h>
#include <global.h>
enum EKeyCode {
KC_UNKNOWN = 0x00,

@ -25,7 +25,7 @@
#ifndef PLATFORM_H
#define PLATFORM_H
#include <prerequisites.h>
#include <global.h>
class Platform
{

@ -22,10 +22,11 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/resources.h>
#include <core/platform.h>
#include <boost/algorithm/string.hpp>
#include <physfs.h>
Resources g_resources;
@ -35,34 +36,32 @@ void Resources::init(const char *argv0)
PHYSFS_init(argv0);
// try to find data directory
std::list<std::string> searchPaths;
std::string dir;
std::string baseDir = PHYSFS_getBaseDir();
std::list<std::string> possibleDirs;
possibleDirs.push_back("data");
possibleDirs.push_back(baseDir + "data");
possibleDirs.push_back(baseDir + "../data");
possibleDirs.push_back(baseDir + "../share/otclient/data");
possibleDirs.push_back("");
std::string possibleDirs[] = { "data",
baseDir + "data",
baseDir + "../data",
baseDir + "../share/otclient/data",
"" };
bool found = false;
foreach(dir, possibleDirs) {
if(g_resources.addToSearchPath(dir)) {
flogInfo("Using data directory: %s", dir.c_str());
info("Using data directory: ", dir.c_str());
found = true;
break;
}
}
if(!found)
logFatal("ERROR: could not find data directory");
fatal("ERROR: could not find data directory");
// setup write directory
dir = Platform::getAppUserDir();
if(g_resources.setWriteDir(dir))
g_resources.addToSearchPath(dir);
else
logError("ERROR: could not setup write directory");
error("ERROR: could not setup write directory");
}
void Resources::terminate()
@ -109,7 +108,7 @@ bool Resources::loadFile(const std::string& fileName, std::iostream& out)
out.clear(std::ios::goodbit);
PHYSFS_file *file = PHYSFS_openRead(fullPath.c_str());
if(!file) {
flogError("ERROR: Failed to load file \"%s\": %s", fullPath.c_str() % PHYSFS_getLastError());
error("ERROR: Failed to load file '", fullPath.c_str(), "': ", PHYSFS_getLastError());
out.clear(std::ios::failbit);
return false;
} else {
@ -131,7 +130,7 @@ bool Resources::saveFile(const std::string &fileName, const uchar *data, uint si
{
PHYSFS_file *file = PHYSFS_openWrite(resolvePath(fileName).c_str());
if(!file) {
flogError("ERROR: Failed to save file \"%s\": %s", fileName.c_str() % PHYSFS_getLastError());
error("ERROR: Failed to save file '",fileName,"': ",PHYSFS_getLastError());
return false;
}

@ -25,7 +25,8 @@
#ifndef RESOURCES_H
#define RESOURCES_H
#include <prerequisites.h>
#include <global.h>
#include <stack>
class Resources
{

@ -0,0 +1,45 @@
#ifndef GLOBAL_H
#define GLOBAL_H
// common C headers
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <ctime>
#include <cmath>
// common STL headers
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <algorithm>
// smart pointers
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
// constants
#include "const.h"
// easy types
#include <util/types.h>
// custom types
#include <util/point.h>
#include <util/color.h>
#include <util/rect.h>
#include <util/size.h>
// additional utilities
#include <util/convert.h>
#include <util/foreach.h>
#include <util/makestring.h>
#include <util/logger.h>
#endif // GLOBAL_H

@ -25,8 +25,8 @@
#ifndef ANIMATEDTEXTURE_H
#define ANIMATEDTEXTURE_H
#include <prerequisites.h>
#include <graphics/texture.h>
#include <global.h>
#include <graphics/graphics.h>
class AnimatedTexture : public Texture
{

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <graphics/borderedimage.h>
#include <graphics/graphics.h>
#include <graphics/textures.h>

@ -25,7 +25,7 @@
#ifndef BORDEREDIMAGE_H
#define BORDEREDIMAGE_H
#include <prerequisites.h>
#include <global.h>
#include <graphics/image.h>
#include <graphics/texture.h>

@ -22,11 +22,12 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/resources.h>
#include <graphics/font.h>
#include <graphics/textures.h>
#include <graphics/graphics.h>
#include <otml/otml.h>
void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
{
@ -70,7 +71,7 @@ bool Font::load(const std::string& file)
{
std::stringstream fin;
if(!g_resources.loadFile(file, fin)) {
flogError("ERROR: Coult not load font file \"%s", file.c_str());
error("ERROR: Coult not load font file '",file,"'");
return false;
}
@ -78,8 +79,8 @@ bool Font::load(const std::string& file)
Size glyphSize;
try {
FML::Parser parser(fin, file);
FML::Node* doc = parser.getDocument();
OTMLParser parser(fin, file);
OTMLNode* doc = parser.getDocument();
// required values
textureName = doc->valueAt("image");
@ -92,7 +93,7 @@ bool Font::load(const std::string& file)
// load texture
m_texture = g_textures.get(textureName);
if(!m_texture) {
flogError("ERROR: Failed to load image for font file \"%s\"", file.c_str());
error("ERROR: Failed to load image for font file '",file,"'");
return false;
}
@ -115,8 +116,8 @@ bool Font::load(const std::string& file)
m_glyphsSize[glyph].width(),
m_glyphHeight);
}
} catch(FML::Exception e) {
flogError("ERROR: Malformed font file \"%s\":\n %s", file.c_str() % e.what());
} catch(OTMLException e) {
error("ERROR: Malformed font file \"", file.c_str(), "\":\n ", e.what());
return false;
}

@ -25,8 +25,8 @@
#ifndef FONT_H
#define FONT_H
#include <prerequisites.h>
#include <graphics/texture.h>
#include <global.h>
#include <graphics/graphics.h>
class Font
{

@ -22,10 +22,12 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/resources.h>
#include <graphics/fonts.h>
#include <boost/algorithm/string.hpp>
Fonts g_fonts;
void Fonts::init()
@ -55,7 +57,7 @@ FontPtr Fonts::get(const std::string& fontName)
return font;
}
flogFatal("ERROR: Font \"%s\" not found", fontName.c_str());
fatal("ERROR: Font '",fontName,"' not found");
return FontPtr();
}

@ -25,7 +25,7 @@
#ifndef FONTS_H
#define FONTS_H
#include <prerequisites.h>
#include <global.h>
#include <graphics/font.h>
class Fonts

@ -21,7 +21,7 @@
* THE SOFTWARE.
*/
#include <prerequisites.h>
#include <global.h>
#include <core/platform.h>
#include <graphics/framebuffer.h>
#include <graphics/graphics.h>

@ -25,7 +25,7 @@
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include <prerequisites.h>
#include <global.h>
class FrameBuffer
{

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <graphics/graphics.h>
Graphics g_graphics;
@ -40,8 +40,8 @@ void Graphics::init()
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
flogInfo("GPU %s", (const char*)glGetString(GL_RENDERER));
flogInfo("OpenGL %s", (const char*)glGetString(GL_VERSION));
info("GPU ", glGetString(GL_RENDERER));
info("OpenGL ", glGetString(GL_VERSION));
}
void Graphics::terminate()

@ -25,8 +25,12 @@
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include <prerequisites.h>
#include <graphics/texture.h>
#include <global.h>
#include <graphics/textures.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
class Graphics
{

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <graphics/image.h>
#include <graphics/graphics.h>
#include <graphics/textures.h>

@ -25,7 +25,7 @@
#ifndef IMAGE_H
#define IMAGE_H
#include <prerequisites.h>
#include <global.h>
#include <graphics/texture.h>
class Image

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/engine.h>
#include <graphics/textarea.h>
#include <graphics/graphics.h>

@ -25,7 +25,7 @@
#ifndef TEXTAREA_H
#define TEXTAREA_H
#include <prerequisites.h>
#include <global.h>
#include "font.h"
class TextArea

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <graphics/texture.h>
#include "graphics.h"
@ -37,7 +37,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
GLint texSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
if(width > texSize || height > texSize) {
flogError("loading texture with size %dx%d failed, the maximum size is %dx%d", width % height % texSize % texSize);
error("loading texture with size ",width,"x",height," failed, the maximum size is ",texSize,"x",texSize);
return 0;
}

@ -25,7 +25,7 @@
#ifndef TEXTURE_H
#define TEXTURE_H
#include <prerequisites.h>
#include <global.h>
class Texture : public boost::enable_shared_from_this<Texture>
{

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <graphics/textureloader.h>
#include <graphics/texture.h>
#include <util/apngloader.h>

@ -25,7 +25,7 @@
#ifndef TEXTURELOADER_H
#define TEXTURELOADER_H
#include <prerequisites.h>
#include <global.h>
#include <graphics/texture.h>
class TextureLoader

@ -22,12 +22,14 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/resources.h>
#include <graphics/textures.h>
#include <graphics/textureloader.h>
#include <core/dispatcher.h>
#include <boost/algorithm/string.hpp>
Textures g_textures;
TexturePtr Textures::get(const std::string& textureFile)
@ -47,14 +49,14 @@ TexturePtr Textures::get(const std::string& textureFile)
if(!texture) {
// currently only png textures are supported
if(!boost::ends_with(textureFile, ".png")) {
flogError("ERROR: Unable to load texture %s, file format no supported.", textureFile.c_str());
error("ERROR: Unable to load texture '",textureFile,"', file format no supported.");
return texture;
}
// load texture file data
std::stringstream fin;
if(!g_resources.loadFile(textureFile, fin)) {
flogError("ERROR: Unable to load texture %s, file could not be read.", textureFile.c_str());
error("ERROR: Unable to load texture '",textureFile,"', file could not be read.");
return texture;
}
@ -62,7 +64,7 @@ TexturePtr Textures::get(const std::string& textureFile)
// load the texture
texture = TexturePtr(TextureLoader::loadPNG(fin));
if(!texture)
flogError("ERROR: Unable to load texture %s", textureFile.c_str());
error("ERROR: Unable to load texture '",textureFile,"'");
}
return texture;
}

@ -25,9 +25,8 @@
#ifndef TEXTURES_H
#define TEXTURES_H
#include <prerequisites.h>
#include <global.h>
#include <graphics/texture.h>
#include <graphics/animatedtexture.h>
class Textures
{

@ -40,12 +40,12 @@ void Connection::poll()
ioService.reset();
}
void Connection::connect(const std::string& host, uint16 port, const SimpleCallback& connectCallback)
void Connection::connect(const std::string& host, uint16 port, const boost::function<void()>& connectCallback)
{
m_connectCallback = connectCallback;
m_connectionState = CONNECTION_STATE_RESOLVING;
boost::asio::ip::tcp::resolver::query query(host, convert_cast<std::string>(port));
boost::asio::ip::tcp::resolver::query query(host, convert<std::string>(port));
m_resolver.async_resolve(query, boost::bind(&Connection::onResolve, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::iterator));
m_timer.expires_from_now(boost::posix_time::seconds(2));
@ -70,7 +70,7 @@ void Connection::onTimeout(const boost::system::error_code& error)
void Connection::onResolve(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpointIterator)
{
logTrace();
trace();
m_timer.cancel();
@ -88,7 +88,7 @@ void Connection::onResolve(const boost::system::error_code& error, boost::asio::
void Connection::onConnect(const boost::system::error_code& error)
{
logTrace();
trace();
m_timer.cancel();
@ -108,7 +108,7 @@ void Connection::onConnect(const boost::system::error_code& error)
void Connection::onSend(const boost::system::error_code& error, size_t)
{
logTrace();
trace();
m_timer.cancel();
@ -121,7 +121,7 @@ void Connection::onSend(const boost::system::error_code& error, size_t)
void Connection::onRecvHeader(const boost::system::error_code& error)
{
logTrace();
trace();
if(error) {
if(m_errorCallback)
@ -139,7 +139,7 @@ void Connection::onRecvHeader(const boost::system::error_code& error)
void Connection::onRecvData(const boost::system::error_code& error)
{
logTrace();
trace();
if(error) {
if(m_errorCallback)

@ -25,10 +25,13 @@
#ifndef CONNECTION_H
#define CONNECTION_H
#include <global.h>
#include <net/inputmessage.h>
#include <net/outputmessage.h>
#include <prerequisites.h>
#include <boost/asio.hpp>
#include <boost/function.hpp>
typedef boost::function<void(boost::system::error_code&)> ErrorCallback;
typedef boost::function<void(InputMessage*)> RecvCallback;
@ -40,7 +43,7 @@ public:
static void poll();
void connect(const std::string& host, uint16 port, const SimpleCallback& connectCallback);
void connect(const std::string& host, uint16 port, const boost::function<void()>& connectCallback);
void send(OutputMessage *outputMessage);
void setErrorCallback(const ErrorCallback& errorCallback) { m_errorCallback = errorCallback; }
@ -63,7 +66,7 @@ public:
private:
ErrorCallback m_errorCallback;
RecvCallback m_recvCallback;
SimpleCallback m_connectCallback;
boost::function<void()> m_connectCallback;
ConnectionState_t m_connectionState;
boost::asio::deadline_timer m_timer;

@ -87,6 +87,6 @@ std::string InputMessage::getString()
bool InputMessage::canRead(int bytes)
{
if((m_readPos + bytes > m_messageSize) || (m_readPos + bytes > BUFFER_MAXSIZE))
logFatal("[InputMessage::canRead()]: Cant read. Message is finished or read position has reached buffer's maximum size.");
fatal("[InputMessage::canRead()]: Cant read. Message is finished or read position has reached buffer's maximum size.");
return true;
}

@ -25,7 +25,7 @@
#ifndef INPUTMESSAGE_H
#define INPUTMESSAGE_H
#include <prerequisites.h>
#include <global.h>
class InputMessage
{

@ -105,6 +105,6 @@ void OutputMessage::addPaddingBytes(int bytes, uint8 byte)
bool OutputMessage::canWrite(int bytes)
{
if(m_writePos + bytes > BUFFER_MAXSIZE)
logFatal("[OutputMessage::canWrite()]: Can't write. Write position has reached buffer's maxium size.");
fatal("[OutputMessage::canWrite()]: Can't write. Write position has reached buffer's maxium size.");
return true;
}

@ -25,7 +25,7 @@
#ifndef OUTPUTMESSAGE_H
#define OUTPUTMESSAGE_H
#include <prerequisites.h>
#include <global.h>
class OutputMessage
{

@ -24,6 +24,8 @@
#include <net/protocol.h>
#include <boost/bind.hpp>
Protocol::Protocol() :
m_connection(new Connection)
{
@ -32,7 +34,7 @@ Protocol::Protocol() :
m_xteaEncryptionEnabled = false;
}
void Protocol::connect(const std::string& host, uint16 port, const SimpleCallback& callback)
void Protocol::connect(const std::string& host, uint16 port, const boost::function<void()>& callback)
{
m_connection->connect(host, port, callback);
}
@ -62,7 +64,7 @@ void Protocol::onRecv(InputMessage *inputMessage)
uint32 checksum = getAdlerChecksum(inputMessage->getBuffer() + InputMessage::DATA_POS, inputMessage->getMessageSize() - InputMessage::CHECKSUM_LENGTH);
if(inputMessage->getU32() != checksum) {
// error
logError("Checksum is invalid.");
error("Checksum is invalid.");
return;
}
@ -70,9 +72,9 @@ void Protocol::onRecv(InputMessage *inputMessage)
xteaDecrypt(inputMessage);
}
void Protocol::onError(const boost::system::error_code& error)
void Protocol::onError(const boost::system::error_code& err)
{
flogError("PROTOCOL ERROR: %s", error.message());
error("PROTOCOL ERROR: ", err.message());
// invalid hostname
// connection timeouted

@ -43,11 +43,11 @@ class Protocol : public Scriptable
public:
Protocol();
void connect(const std::string& host, uint16 port, const SimpleCallback& callback);
void connect(const std::string& host, uint16 port, const boost::function<void()>& callback);
void send(OutputMessage *outputMessage);
virtual void onRecv(InputMessage *inputMessage);
virtual void onError(const boost::system::error_code& error);
virtual void onError(const boost::system::error_code& err);
virtual const char *getScriptableName() const { return "Protocol"; }

@ -21,8 +21,8 @@
* THE SOFTWARE.
*/
#include <prerequisites.h>
#include <util/rsa.h>
#include <global.h>
#include "rsa.h"
Rsa::Rsa()
{

@ -24,11 +24,12 @@
#ifndef RSA_H
#define RSA_H
#include <prerequisites.h>
#include <global.h>
#include <gmp.h>
class Rsa{
class Rsa
{
public:
Rsa();
~Rsa();

@ -0,0 +1,9 @@
#ifndef OTML_H
#define OTML_H
#include "otmlnode.h"
#include "otmlemitter.h"
#include "otmlparser.h"
#endif // OTML_H

@ -0,0 +1,63 @@
#include "otmlemitter.h"
#include "otmlnode.h"
#include <boost/algorithm/string.hpp>
OTMLEmitter::OTMLEmitter() :
m_rootNode(0)
{
}
OTMLEmitter::~OTMLEmitter()
{
if(m_rootNode)
delete m_rootNode;
}
OTMLNode* OTMLEmitter::createDocument()
{
m_rootNode = new OTMLNode;
return m_rootNode;
}
std::string OTMLEmitter::emitDocument()
{
if(m_rootNode)
return emitNode(m_rootNode, 0);
return std::string();
}
std::string OTMLEmitter::emitNodeValue(OTMLNode* node)
{
std::string value = node->value();
if(!value.empty() && (value[0] == '"' || *value.rbegin() == '"'||
value[0] == ' ' || *value.rbegin() == ' '||
value[0] == '-' || value[0] == '{' || value[0] == '[' || value[0] == '|' ||
value.find("\n") != std::string::npos)) {
boost::replace_all(value, "\\", "\\\\");
boost::replace_all(value, "\"", "\\\"");
boost::replace_all(value, "\n", "\\n");
value.append("\"");
value.insert(0, "\"");
}
return value;
}
std::string OTMLEmitter::emitNode(OTMLNode* node, int currentDepth)
{
std::stringstream ss;
for(int i=1;i<currentDepth;++i)
ss << " ";
if(currentDepth > 0) {
if(node->hasTag())
ss << node->tag();
if(node->hasValue())
ss << (node->hasTag() ? ": " : "- ") << emitNodeValue(node);
if(!node->hasTag() && !node->hasValue())
ss << "-";
ss << std::endl;
}
for(int i=0;i<node->size();++i)
ss << emitNode(node->at(i), currentDepth+1);
return ss.str();
}

@ -0,0 +1,24 @@
#ifndef OTMLEMITTER_H
#define OTMLEMITTER_H
#include <string>
class OTMLNode;
class OTMLEmitter
{
public:
OTMLEmitter();
~OTMLEmitter();
OTMLNode* createDocument();
std::string emitDocument();
static std::string emitNodeValue(OTMLNode* node);
static std::string emitNode(OTMLNode* node, int currentDepth = 0);
private:
OTMLNode* m_rootNode;
};
#endif // OTMLEMITTER_H

@ -0,0 +1,93 @@
#include "otmlnode.h"
#include <boost/algorithm/string.hpp>
OTMLNode::OTMLNode(std::string what) :
m_parent(0), m_line(0), m_what(what)
{
}
OTMLNode::~OTMLNode()
{
for(int i=0;i<size();++i)
delete at(i);
}
OTMLNode* OTMLNode::at(const std::string& childTag) const {
int i=0;
while(i<size() && at(i)->tag()!=childTag)
++i;
return at(i);
}
OTMLNode* OTMLNode::at(int pos) const
{
if(pos < (int)m_children.size() && pos >= 0)
return m_children[pos];
return 0;
}
OTMLNode* OTMLNode::atPath(const std::string& path) const
{
std::vector<std::string> nodeTags;
OTMLNode* node = const_cast<OTMLNode*>(this);
std::string shortcutKey;
boost::split(nodeTags, path, boost::is_any_of(std::string("/")));
foreach(std::string& stag, nodeTags) {
if(!shortcutKey.empty())
shortcutKey += '.';
shortcutKey += stag;
if(node)
node = node->at(stag);
}
if(node)
return node;
else
return at(shortcutKey);
}
OTMLNode* OTMLNode::createNode(std::string tag)
{
OTMLNode* node = new OTMLNode;
node->setTag(tag);
addNode(node);
return node;
}
void OTMLNode::addNode(OTMLNode* node) {
if(node->hasTag() && node->hasValue())
if(OTMLNode* other = at(node->tag()))
removeNode(other);
m_children.push_back(node);
node->setParent(this);
}
bool OTMLNode::removeNode(OTMLNode* node) {
for(NodeList::iterator it = m_children.begin(); it != m_children.end(); ++it) {
if((*it) == node) {
m_children.erase(it);
return true;
}
}
return false;
}
std::string OTMLNode::generateErrorMessage(const std::string& message) const {
std::stringstream ss;
ss << "OTML error";
if(!what().empty())
ss << " in '" << what() << "'";
if(m_line > 0)
ss << " at line " << m_line;
if(m_line > 0 && hasTag())
ss << ", in node '" << tag() << "'";
ss << ": " << message;
return ss.str();
}
void OTMLNode::throwError(const std::string& message) const
{
throw OTMLException(generateErrorMessage(message));
}

@ -0,0 +1,260 @@
#ifndef OTMLNODE_H
#define OTMLNODE_H
#include <string>
#include <vector>
#include <list>
#include <map>
#include <stdexcept>
#include <typeinfo>
#include <util/foreach.h>
#include <util/makestring.h>
#include <util/convert.h>
class OTMLException : public std::runtime_error {
public:
OTMLException(const std::string& what) : std::runtime_error(what) {}
};
class OTMLNode
{
public:
typedef std::vector<OTMLNode*> NodeList;
typedef NodeList::iterator iterator;
typedef NodeList::const_iterator const_iterator;
OTMLNode(std::string what = "");
~OTMLNode();
bool hasTag() const { return !m_tag.empty(); }
bool hasChildren() const { return size() > 0; }
bool hasValue() const { return !m_value.empty(); }
bool hasNode(const std::string ctag) const { return at(ctag) != 0; }
void setTag(std::string tag) { m_tag = tag; }
void setLine(int line) { m_line = line; }
void setValue(const std::string& value) { m_value = value; }
void setParent(OTMLNode* parent) { m_parent = parent; }
std::string tag() const { return m_tag; }
int line() const { return m_line; }
int size() const { return m_children.size(); }
OTMLNode* parent() { return m_parent; }
std::string what() const { return (m_parent ? m_parent->what() : m_what); }
iterator begin() { return m_children.begin(); }
iterator end() { return m_children.end(); }
const_iterator begin() const { return m_children.begin(); }
const_iterator end() const { return m_children.end(); }
OTMLNode* front() const { return at(0); }
OTMLNode* back() const { return at(size()-1); }
OTMLNode* at(const std::string& ctag) const;
OTMLNode* at(int pos) const;
OTMLNode *atPath(const std::string& path) const;
OTMLNode* createNode(std::string tag = "");
void addNode(OTMLNode* node);
bool removeNode(OTMLNode* node);
std::string generateErrorMessage(const std::string& message) const;
void throwError(const std::string& message) const;
std::string value(const std::string& def = "") const { return (m_value.empty() ? def : m_value); }
std::string valueAt(const std::string ctag, const std::string& def = "") const {
OTMLNode* c = at(ctag);
return (c ? c->value() : def);
}
std::string valueAt(int pos, const std::string& def = "") const {
OTMLNode* n = at(pos);
return (n ? n->value() : def);
}
std::string valueAtPath(const std::string path, const std::string& def = "") const {
OTMLNode* c = atPath(path);
return (c ? c->value() : def);
}
// read into memory
template <typename T>
void read(T* v) const {
if(!(*this >> *v))
throwError(make_string("failed to cast node value to type ", std::string(typeid(T).name())));
}
template <typename T>
bool readAt(const std::string& ctag, T* v) const {
if(OTMLNode* node = at(ctag)) {
node->read<T>(v);
return true;
}
return false;
}
template <typename T>
bool readAt(int pos, T* v) const {
if(OTMLNode* node = at(pos)) {
node->read<T>(v);
return true;
}
return false;
}
template <typename T>
bool readAtPath(const std::string& ctag, T* v) const {
if(OTMLNode* node = atPath(ctag)) {
node->read<T>(v);
return true;
}
return false;
}
// read returning the result
template <typename T>
T read() const { T v; read<T>(&v); return v;}
template <typename T>
T readAt(const std::string& ctag) const {
T v;
if(!readAt(ctag, &v))
throwError(make_string("child node \'", ctag, "\' not found"));
return v;
}
template <typename T>
T readAt(int pos) const {
T v;
if(!readAt(pos, &v))
throwError(make_string("child node at pos ", pos, " not found"));
return v;
}
template <typename T>
T readAtPath(const std::string& ctag) const {
T v;
if(!readAtPath(ctag, &v))
throwError(make_string("child node in path \'", ctag, "\' not found"));
return v;
}
// read with default supplied
template <typename T>
T readAt(const std::string& ctag, const T& def) const {
OTMLNode* c = at(ctag);
return (c ? c->read<T>() : def);
}
template <typename T>
T readAt(int pos, const T& def) const {
OTMLNode* c = at(pos);
return (c ? c->read<T>() : def);
}
template <typename T>
T readAtPath(const std::string& path, const T& def) const {
OTMLNode* c = atPath(path);
return (c ? c->read<T>() : def);
}
// writing
template <typename T>
void write(T v) {
if(!(*this << v))
throwError(make_string("failed to cast to string node value of type ", typeid(T).name()));
}
template <typename T>
void writeIn(int pos, T v) {
OTMLNode* c;
while(!at(pos))
c = createNode();
c->write<T>(v);
}
template <typename T>
void writeIn(const std::string& ctag, T v) {
OTMLNode* c = at(ctag);
if(!c)
c = createNode(ctag);
c->write<T>(v);
}
private:
OTMLNode* m_parent;
int m_line;
std::string m_what;
NodeList m_children;
std::string m_tag;
std::string m_value;
};
// read operators
template <typename T>
bool operator >> (const OTMLNode& node, T& v) { return safe_convert(node.value(), v); }
template <typename T>
bool operator >> (const OTMLNode& node, std::vector<T>& v) {
v.resize(node.size());
for(unsigned i=0;i<node.size();++i)
v[i] = node.readAt<T>(i);
return true;
}
template <typename T>
bool operator >> (const OTMLNode& node, std::list<T>& v) {
for(unsigned i=0;i<node.size();++i)
v.push_back(node.readAt<T>(i));
return true;
}
template <typename K, typename T>
bool operator >> (const OTMLNode& node, std::map<K, T>& m) {
for(int i=0;i<node.size();++i) {
K k;
if(!safe_convert(node.at(i)->tag(), k))
return false;
m[k] = node.at(i)->read<T>();
}
return true;
}
// write operators
template <typename T>
bool operator << (OTMLNode& node, const T& v) {
std::string out;
if(!safe_convert(v, out))
return false;
node.setValue(out);
return true;
}
template <typename T>
bool operator << (OTMLNode& node, const std::vector<T>& v) {
for(unsigned i=0;i<v.size();++i)
node.createNode()->write(v[i]);
return true;
}
template <typename T>
bool operator << (OTMLNode& node, const std::list<T>& v) {
for(unsigned i=0;i<v.size();++i)
node.createNode()->write(v[i]);
return true;
}
template <typename K, typename T>
bool operator << (OTMLNode& node, const std::map<K, T>& m) {
typename std::map<K, T>::const_iterator it;
for(it = m.begin(); it != m.end(); ++it) {
std::string k;
if(!safe_convert(it->first, k))
return false;
node.createNode(k)->write(it->second);
}
return true;
}
#include "otmlnodeext.h"
#endif // OTMLNODE_H

@ -0,0 +1,84 @@
/* The MIT License
*
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef OTMLNODEEXT_H
#define OTMLNODEEXT_H
#include <util/point.h>
#include <util/color.h>
#include <util/rect.h>
#include <util/size.h>
inline bool operator>>(const OTMLNode& node, Color& color)
{
int r, g, b, a;
if(node.readAt(0, &r) &&
node.readAt(1, &g) &&
node.readAt(2, &b)) {
a = 255;
node.readAt(3, &a);
color.setRGBA(r,g,b,a);
return true;
}
return false;
}
template <class T>
inline bool operator>>(const OTMLNode& node, TPoint<T>& point)
{
T x, y;
if(node.readAt(0, &x) && node.readAt(1, &y)) {
point.x = x;
point.y = y;
return true;
}
return false;
}
template <class T>
inline bool operator>>(const OTMLNode& node, TSize<T>& size)
{
T w, h;
if(node.readAt(0, &w) && node.readAt(1, &h)) {
size.setSize(w, h);
return true;
}
return false;
}
template <class T>
inline bool operator>>(const OTMLNode& node, TRect<T>& rect)
{
T x, y, width, height;
if(node.readAt(0, &x) &&
node.readAt(1, &y) &&
node.readAt(2, &width) &&
node.readAt(3, &height)) {
rect.setRect(x, y, width, height);
return true;
}
return false;
}
#endif // OTMLNODEEXT_H

@ -0,0 +1,259 @@
#include "otmlparser.h"
#include "otmlnode.h"
#include <boost/algorithm/string.hpp>
OTMLParser::OTMLParser(std::istream& in, std::string what) :
m_currentDepth(0), m_currentLine(0),
m_rootNode(new OTMLNode), m_currentParent(m_rootNode), m_previousNode(0),
m_what(what), m_in(in)
{
parse();
}
OTMLParser::~OTMLParser()
{
delete m_rootNode;
}
void OTMLParser::throwError(const std::string& message, int line)
{
std::stringstream ss;
ss << "OTML syntax error";
if(!m_what.empty())
ss << " in '" << m_what << "'";
if(line > 0)
ss << " at line " << line;
ss << ": " << message;
throw OTMLException(ss.str());
}
void OTMLParser::parse()
{
m_rootNode->setTag("document");
while(m_in.good() && !m_in.eof()) {
m_currentLine++;
std::string line;
std::getline(m_in, line);
parseLine(line);
}
}
void OTMLParser::parseLine(std::string line)
{
// calculate depth
std::size_t numSpaces = line.find_first_not_of(' ');
// trim left whitespaces
boost::trim_left(line);
// skip comment or empty lines
if(line[0] == '#' || line.empty())
return;
// calculate depth
int depth = 0;
if(numSpaces != std::string::npos)
depth = numSpaces / 2;
// check for syntax error
if(numSpaces != std::string::npos && numSpaces % 2 != 0)
throwError("file must be idented every 2 whitespaces", m_currentLine);
// a depth above, change current parent to the previous added node
if(depth == m_currentDepth+1) {
m_currentParent = m_previousNode;
// a depth below, change parent to previus parent
} else if(depth < m_currentDepth) {
for(int i=0;i<m_currentDepth-depth;++i)
m_currentParent = m_currentParent->parent();
// else if it isn't the current depth it's a syntax error
} else if(depth != m_currentDepth) {
throwError("invalid indentation level", m_currentLine);
}
// update current depth
m_currentDepth = depth;
// add node
OTMLNode* node = m_currentParent->createNode();
m_previousNode = node;
parseNode(node, line);
}
void OTMLParser::parseNode(OTMLNode* node, std::string data)
{
std::string tag;
std::string value;
std::size_t dotsPos = data.find_first_of(':');
// its a node that has a value but no tag
if(!data.empty() && data[0] == '-') {
value = data.substr(1);
boost::trim(value);
// check if it's value is shortcut for adding a child node
if(dotsPos != std::string::npos && !value.empty() && value[0] != '"') {
OTMLNode* child = node->createNode();
parseNode(child, value);
value.clear();
}
}
// its a node that has tag and possible a value
else if(dotsPos != std::string::npos) {
tag = data.substr(0, dotsPos);
value = data.substr(dotsPos+1);
}
// its a node that has only a tag
else {
tag = data;
}
// set node tag
boost::trim(tag);
node->setTag(tag);
// set node line
node->setLine(m_currentLine);
// process node value
parseNodeValue(node, value);
}
void OTMLParser::parseNodeValue(OTMLNode* node, std::string value)
{
boost::trim(value);
if(value.empty())
return;
// multiline text scalar
if(value[0] == '|') {
std::string multiLineData;
do {
std::string line;
size_t lastPos = m_in.tellg();
std::getline(m_in, line);
// calculate numspaces
std::size_t numSpaces = line.find_first_not_of(' ');
// depth above current depth, add the text to the multiline
if(numSpaces != std::string::npos && (int)numSpaces >= (m_currentDepth+1)*2) {
boost::trim(line);
parseTextValue(line);
multiLineData += line + "\n";
}
// if has contents below the current depth, its a node
else if(numSpaces != std::string::npos) {
m_in.seekg(lastPos, std::ios::beg);
break;
}
// else its just a new line
else {
multiLineData += "\n";
}
} while(!m_in.eof());
// determine how to treat last new lines
if(value.length() == 1 || (value.length() == 2 && value[1] == '-')) {
// remove all new lines at the end
while(*multiLineData.rbegin() == '\n')
multiLineData.erase(multiLineData.length()-1, 1);
// keep just one extra line
if(value[0] == '-')
multiLineData.append("\n");
} else if(value.length() > 2 || value[1] != '+')
throwError("invalid multiline identifier", m_currentLine);
node->setValue(multiLineData);
}
// sequence
else if(value[0] == '[') {
std::vector<std::string> tokens;
parseTokens(value.substr(1), tokens);
foreach(std::string& token, tokens) {
OTMLNode* child = node->createNode();
child->setLine(m_currentLine);
parseNodeValue(child, token);
}
}
// inline map
else if(value[0] == '{') {
std::vector<std::string> tokens;
parseTokens(value.substr(1), tokens);
foreach(std::string& token, tokens) {
OTMLNode* child = node->createNode();
parseNode(child, token);
}
}
// text scalar
else {
parseTextValue(value);
node->setValue(value);
}
}
void OTMLParser::parseTextValue(std::string& value)
{
if(value[0] == '"' && value[value.length()-1] == '"') {
value = value.substr(1, value.length()-2);
// escape characters
boost::replace_all(value, "\\\\", "\\");
boost::replace_all(value, "\\\"", "\"");
boost::replace_all(value, "\\n", "\n");
}
}
void OTMLParser::parseTokens(std::string data, std::vector<std::string>& out)
{
bool inQuote = false;
int brackets = 1;
std::string tmp;
uint i = 0;
do {
if(i<data.length()) {
char c = data[i];
tmp += c;
if(c == '"') {
if(!inQuote)
inQuote = true;
else if(data[i-1] != '\\')
inQuote = false;
} else if(!inQuote) {
if(c == '{' || c == '[')
brackets++;
else if(c == '}' || c == ']')
brackets--;
else if(c == ',' && brackets == 1) {
tmp.erase(tmp.length()-1);
boost::trim(tmp);
if(!tmp.empty())
out.push_back(tmp);
tmp.clear();
}
}
if(brackets == 0) {
tmp.erase(tmp.length()-1);
boost::trim(tmp);
if(!tmp.empty())
out.push_back(tmp);
break;
}
}
if(i+1 >= data.length() && !m_in.eof()) {
std::string line;
std::getline(m_in, line);
boost::trim(line);
data += " ";
data += line;
}
++i;
} while(i<data.length());
if(brackets != 0)
throwError("no matching bracket while parsing, did you forget to close one?", m_currentLine);
}

@ -0,0 +1,38 @@
#ifndef OTMLPARSER_H
#define OTMLPARSER_H
#include <global.h>
class OTMLNode;
class OTMLParser
{
public:
OTMLParser(std::istream& in, std::string what = "");
~OTMLParser();
OTMLNode* getDocument() const { return m_rootNode; }
std::string what() { return m_what; }
void throwError(const std::string& message, int line);
protected:
void parse();
void parseLine(std::string line);
void parseNode(OTMLNode* node, std::string data);
void parseNodeValue(OTMLNode* node, std::string value);
void parseTextValue(std::string& value);
void parseTokens(std::string data, std::vector<std::string>& out);
private:
int m_currentDepth;
int m_currentLine;
OTMLNode* m_rootNode;
OTMLNode* m_currentParent;
OTMLNode* m_previousNode;
std::string m_what;
std::istream& m_in;
};
#endif // OTMLPARSER_H

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/platform.h>
#include <core/engine.h>
@ -211,7 +211,7 @@ void Platform::init(const char *appName)
wc.lpszClassName = win32.appName.c_str(); // Set The Class Name
if(!RegisterClassA(&wc))
logFatal("FATAL ERROR: Failed to register the window class.");
fatal("FATAL ERROR: Failed to register the window class.");
// force first tick
Platform::getTicks();
@ -226,7 +226,7 @@ void Platform::terminate()
if(win32.instance) {
if(!UnregisterClassA(win32.appName.c_str(), win32.instance))
logError("ERROR: Unregister class failed.");
error("ERROR: Unregister class failed.");
win32.instance = NULL;
}
@ -286,7 +286,7 @@ bool Platform::createWindow(int x, int y, int width, int height, int minWidth, i
if(!win32.window) {
terminate();
logFatal("FATAL ERROR: Window creation error.");
fatal("FATAL ERROR: Window creation error.");
return false;
}
@ -315,31 +315,31 @@ bool Platform::createWindow(int x, int y, int width, int height, int minWidth, i
if(!(win32.hdc = GetDC(win32.window))) {
terminate();
logFatal("FATAL ERROR: Can't Create A GL Device Context.");
fatal("FATAL ERROR: Can't Create A GL Device Context.");
return false;
}
if(!(pixelFormat = ChoosePixelFormat(win32.hdc, &pfd))) {
terminate();
logFatal("FATAL ERROR: Can't Find A Suitable PixelFormat.");
fatal("FATAL ERROR: Can't Find A Suitable PixelFormat.");
return false;
}
if(!SetPixelFormat(win32.hdc, pixelFormat, &pfd)) {
terminate();
logFatal("FATAL ERROR: Can't Set The PixelFormat.");
fatal("FATAL ERROR: Can't Set The PixelFormat.");
return false;
}
if(!(win32.hrc = wglCreateContext(win32.hdc))) {
terminate();
logFatal("FATAL ERROR: Can't Create A GL Rendering Context.");
fatal("FATAL ERROR: Can't Create A GL Rendering Context.");
return false;
}
if(!wglMakeCurrent(win32.hdc, win32.hrc)) {
terminate();
logFatal("FATAL ERROR: Can't Activate The GL Rendering Context.");
fatal("FATAL ERROR: Can't Activate The GL Rendering Context.");
return false;
}
@ -350,24 +350,24 @@ void Platform::destroyWindow()
{
if(win32.hrc) {
if(!wglMakeCurrent(NULL, NULL))
logError("ERROR: Release Of DC And RC Failed.");
error("ERROR: Release Of DC And RC Failed.");
if(!wglDeleteContext(win32.hrc))
logError("ERROR: Release Rendering Context Failed.");
error("ERROR: Release Rendering Context Failed.");
win32.hrc = NULL;
}
if(win32.hdc) {
if(!ReleaseDC(win32.window, win32.hdc))
logError("ERROR: Release Device Context Failed.");
error("ERROR: Release Device Context Failed.");
win32.hdc = NULL;
}
if(win32.window) {
if(!DestroyWindow(win32.window))
logError("ERROR: Destroy window failed.");
error("ERROR: Destroy window failed.");
win32.window = NULL;
}
@ -502,7 +502,7 @@ std::string Platform::getAppUserDir()
std::stringstream sdir;
sdir << PHYSFS_getUserDir() << "/." << win32.appName << "/";
if((mkdir(sdir.str().c_str()) != 0) && (errno != EEXIST))
flogError("ERROR: Couldn't create directory for saving configuration file. (%s)", sdir.str().c_str());
ferror("ERROR: Couldn't create directory for saving configuration file. (%s)", sdir.str().c_str());
return sdir.str();
}

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/platform.h>
#include <core/engine.h>
@ -237,18 +237,18 @@ void Platform::init(const char *appName)
// open display
x11.display = XOpenDisplay(0);
if(!x11.display)
logFatal("FATAL ERROR: Failed to open X display");
fatal("FATAL ERROR: Failed to open X display");
// check if GLX is supported on this display
if(!glXQueryExtension(x11.display, 0, 0))
logFatal("FATAL ERROR: GLX not supported");
fatal("FATAL ERROR: GLX not supported");
// retrieve GLX version
int glxMajor;
int glxMinor;
if(!glXQueryVersion(x11.display, &glxMajor, &glxMinor))
logFatal("FATAL ERROR: Unable to query GLX version");
flogInfo("GLX version %d.%d", glxMajor % glxMinor);
fatal("FATAL ERROR: Unable to query GLX version");
info("GLX version ",glxMajor,".",glxMinor);
// clipboard related atoms
x11.atomClipboard = XInternAtom(x11.display, "CLIPBOARD", False);
@ -352,7 +352,7 @@ void Platform::poll()
keysym != XK_Escape &&
(uchar)(buf[0]) >= 32
) {
//logDebug("char: %c code: %d", buf[0], (uchar)buf[0]);
//debug("char: ", buf[0], " code: ", (uint)buf[0]);
inputEvent.type = EV_TEXT_ENTER;
inputEvent.keychar = buf[0];
inputEvent.keycode = KC_UNKNOWN;
@ -500,12 +500,12 @@ bool Platform::createWindow(int x, int y, int width, int height, int minWidth, i
// choose OpenGL, RGBA, double buffered, visual
x11.visual = glXChooseVisual(x11.display, DefaultScreen(x11.display), attrList);
if(!x11.visual)
logFatal("FATAL ERROR: RGBA/Double buffered visual not supported");
fatal("FATAL ERROR: RGBA/Double buffered visual not supported");
// create GLX context
x11.glxContext = glXCreateContext(x11.display, x11.visual, 0, GL_TRUE);
if(!x11.glxContext)
logFatal("FATAL ERROR: Unable to create GLX context");
fatal("FATAL ERROR: Unable to create GLX context");
// color map
x11.colormap = XCreateColormap(x11.display,
@ -538,7 +538,7 @@ bool Platform::createWindow(int x, int y, int width, int height, int minWidth, i
&wa);
if(!x11.window)
logFatal("FATAL ERROR: Unable to create X window");
fatal("FATAL ERROR: Unable to create X window");
// create input context (to have better key input handling)
if(XSupportsLocale()) {
@ -550,14 +550,14 @@ bool Platform::createWindow(int x, int y, int width, int height, int minWidth, i
XIMPreeditNothing | XIMStatusNothing,
XNClientWindow, x11.window, NULL);
if(!x11.xic)
logError("ERROR: Unable to create the input context");
error("ERROR: Unable to create the input context");
} else
logError("ERROR: Failed to open an input method");
error("ERROR: Failed to open an input method");
} else
logError("ERROR: X11 does not support the current locale");
error("ERROR: X11 does not support the current locale");
if(!x11.xic)
logWarning("Input of special keys maybe messed up because we couldn't create an input context");
warning("Input of special keys maybe messed up because we couldn't create an input context");
// set window minimum size
@ -839,6 +839,6 @@ std::string Platform::getAppUserDir()
std::stringstream sdir;
sdir << PHYSFS_getUserDir() << "." << x11.appName;
if((mkdir(sdir.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST))
flogError("ERROR: Couldn't create directory for saving configuration file. (%s)", sdir.str().c_str());
error("ERROR: Couldn't create directory for saving configuration file. (",sdir.str(),")");
return sdir.str();
}

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <script/luafunctions.h>
#include <script/luascript.h>
#include <core/engine.h>

@ -25,7 +25,7 @@
#ifndef LUAFUNCTIONS_H
#define LUAFUNCTIONS_H
#include <prerequisites.h>
#include <global.h>
#include <script/scriptable.h>
void registerLuaFunctions();

@ -22,19 +22,21 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <script/luascript.h>
#include <script/luafunctions.h>
#include <core/resources.h>
#include <lua.hpp>
#include <boost/algorithm/string.hpp>
LuaScript g_lua;
void LuaScript::init()
{
L = luaL_newstate();
if(!L)
logFatal("FATAL ERROR: could not create lua context");
fatal("FATAL ERROR: could not create lua context");
// load lua standard libraries
luaL_openlibs(L);
@ -70,7 +72,7 @@ bool LuaScript::loadFile(const std::string& fileName)
if(g_resources.loadFile(fileName, fin))
return loadBuffer(fin.str(), fileName);
else
flogError("ERROR: script file '%s' doesn't exist", fileName.c_str());
error("ERROR: script file '", fileName, "' doesn't exist");
return false;
}
@ -103,7 +105,7 @@ void LuaScript::reportError(const std::string& errorDesc, const char *funcName)
if(funcName)
ss << " in " << funcName << "(): ";
ss << errorDesc;
logError(ss.str());
error(ss.str());
}
void LuaScript::reportErrorWithTraceback(const std::string& errorDesc, const char* funcName)
@ -176,7 +178,7 @@ void LuaScript::setMetatable(const std::string& name, int index)
{
luaL_getmetatable(L, name.c_str());
if(isNil())
reportError(fmt("could not retrive metatable %d", name));
reportError(make_string("could not retrive metatable", name));
else
lua_setmetatable(L, index < 0 ? index-1 : index);
}
@ -407,7 +409,7 @@ std::string LuaScript::getFunctionSourcePath(bool functionIsOnStack, int level)
if(source[0] == '@' && pos != std::string::npos)
path = source.substr(1, pos - 1);
} else {
logError("no source");
error("no source");
}
}
return path;

@ -25,7 +25,7 @@
#ifndef LUASCRIPT_H
#define LUASCRIPT_H
#include <prerequisites.h>
#include <global.h>
#include <script/scriptable.h>
#define reportFuncError(a) reportError(a, __FUNCTION__)

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <script/scriptable.h>
#include <script/luascript.h>
#include <core/dispatcher.h>
@ -68,7 +68,7 @@ void Scriptable::callLuaTableField(const std::string& field, int numArgs)
g_lua.pop();
}
} else if(!g_lua.isNil()) {
g_lua.reportError(fmt("field '%s' for '%s' is not a valid function or array of functions", field % getScriptableName()));
g_lua.reportError(make_string("field '", field, "' for '", getScriptableName(), "' is not a valid function or array of functions"));
}
// release self

@ -25,7 +25,7 @@
#ifndef SCRIPTABLE_H
#define SCRIPTABLE_H
#include <prerequisites.h>
#include <global.h>
class Scriptable : public boost::enable_shared_from_this<Scriptable>
{

@ -25,7 +25,7 @@
#ifndef UI_H
#define UI_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uiconstants.h>
#include <ui/uiskins.h>

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <ui/uianchorlayout.h>
UIElementPtr Anchor::getAnchorLineElement() const
@ -61,19 +61,19 @@ bool UIAnchorLayout::addAnchor(const UIElementPtr& anchoredElement, UI::AnchorPo
UIElementPtr anchorLineElement = anchor.getAnchorLineElement();
if(!anchorLineElement) {
logError("ERROR: could not find the element to anchor on, wrong id?");
error("ERROR: could not find the element to anchor on, wrong id?");
return false;
}
// we can never anchor with itself
if(anchoredElement == anchorLineElement) {
logError("ERROR: anchoring with itself is not possible");
error("ERROR: anchoring with itself is not possible");
return false;
}
// we must never anchor to an anchor child
if(hasElementInAnchorTree(anchorLineElement, anchoredElement)) {
logError("ERROR: anchors is miss configurated, you must never make anchor chains in loops");
error("ERROR: anchors is miss configurated, you must never make anchor chains in loops");
return false;
}

@ -25,7 +25,7 @@
#ifndef UIANCHORLAYOUT_H
#define UIANCHORLAYOUT_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uiconstants.h>
#include <ui/uilayout.h>
#include <ui/uielement.h>

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/dispatcher.h>
#include <ui/uibutton.h>
#include "uicontainer.h"

@ -25,7 +25,7 @@
#ifndef UIBUTTON_H
#define UIBUTTON_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uielement.h>
#include <graphics/borderedimage.h>

@ -22,25 +22,25 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <graphics/fonts.h>
#include <ui/uibuttonskin.h>
#include <ui/uibutton.h>
void UIButtonSkin::load(FML::Node* node)
void UIButtonSkin::load(OTMLNode* node)
{
UIElementSkin::load(node);
m_buttonDownTextColor = getFontColor();
m_buttonHoverTextColor = getFontColor();
if(FML::Node* cnode = node->at("down state")) {
if(OTMLNode* cnode = node->at("down state")) {
m_buttonDownImage = loadImage(cnode);
m_buttonDownTranslate = cnode->readAt("text translate", Point());
m_buttonDownTextColor = cnode->readAt("font color", getFontColor());
}
if(FML::Node* cnode = node->at("hover state")) {
if(OTMLNode* cnode = node->at("hover state")) {
m_buttonHoverImage = loadImage(cnode);
m_buttonHoverTextColor = cnode->readAt("font color", getFontColor());
}

@ -25,7 +25,7 @@
#ifndef UIBUTTONSKIN_H
#define UIBUTTONSKIN_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uiconstants.h>
#include <ui/uielementskin.h>
@ -37,7 +37,7 @@ public:
UIButtonSkin(const std::string& name) :
UIElementSkin(name, UI::Button) { }
void load(FML::Node* node);
void load(OTMLNode* node);
void draw(UIElement *element);
private:

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <ui/uicheckbox.h>
UICheckBox::UICheckBox(UI::ElementType type): UIElement(type)

@ -25,7 +25,7 @@
#ifndef UICHECKBOX_H
#define UICHECKBOX_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uielement.h>
class UICheckBox : public UIElement

@ -22,6 +22,6 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <ui/uicheckboxskin.h>

@ -25,7 +25,7 @@
#ifndef UICHECKBOXSKIN_H
#define UICHECKBOXSKIN_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uielementskin.h>
class UICheckBoxSkin : public UIElementSkin

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/resources.h>
#include <ui/uicontainer.h>
#include <ui/uianchorlayout.h>

@ -25,7 +25,7 @@
#ifndef UICONTAINER_H
#define UICONTAINER_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uielement.h>
class UIContainer : public UIElement

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/dispatcher.h>
#include <graphics/graphics.h>
#include <ui/uielement.h>
@ -79,7 +79,7 @@ void UIElement::destroyCheck()
UIElementPtr me = asUIElement();
// check for leaks, the number of references must be always 2 here
if(me.use_count() != 2 && me != UIContainer::getRoot()) {
flogWarning("destroyed element with id '%s', but it still have %d references left", getId() % (me.use_count()-2));
warning("destroyed element with id '",getId(),"', but it still have ",(me.use_count()-2)," references left");
}
}

@ -25,7 +25,7 @@
#ifndef UIELEMENT_H
#define UIELEMENT_H
#include <prerequisites.h>
#include <global.h>
#include <core/input.h>
#include <script/scriptable.h>
#include <ui/uiconstants.h>

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <ui/uiskins.h>
#include <ui/uielement.h>
#include <ui/uielementskin.h>
@ -30,7 +30,7 @@
#include <graphics/textures.h>
#include <graphics/fonts.h>
void UIElementSkin::load(FML::Node* node)
void UIElementSkin::load(OTMLNode* node)
{
m_defaultSize = node->readAt("default size", Size());
m_defaultImage = loadImage(node);
@ -50,12 +50,12 @@ void UIElementSkin::draw(UIElement *element)
m_defaultImage->draw(element->getRect());
}
ImagePtr UIElementSkin::loadImage(FML::Node* node)
ImagePtr UIElementSkin::loadImage(OTMLNode* node)
{
ImagePtr image;
TexturePtr texture;
if(FML::Node* cnode = node->at("bordered image")) {
if(OTMLNode* cnode = node->at("bordered image")) {
Rect left = cnode->readAt("left border", Rect());
Rect right = cnode->readAt("right border", Rect());
Rect top = cnode->readAt("top border", Rect());
@ -86,8 +86,8 @@ ImagePtr UIElementSkin::loadImage(FML::Node* node)
}
if(!image)
logError(node->generateErrorMessage("failed to load bordered image"));
} else if(FML::Node* cnode = node->at("image")) {
error(node->generateErrorMessage("failed to load bordered image"));
} else if(OTMLNode* cnode = node->at("image")) {
texture = g_textures.get(cnode->value());
if(texture)
image = ImagePtr(new Image(texture));
@ -95,7 +95,7 @@ ImagePtr UIElementSkin::loadImage(FML::Node* node)
m_defaultSize = texture->getSize();
if(!image)
logError(cnode->generateErrorMessage("failed to load image"));
error(cnode->generateErrorMessage("failed to load image"));
}
if(texture) {
@ -107,10 +107,10 @@ ImagePtr UIElementSkin::loadImage(FML::Node* node)
return image;
}
FontPtr UIElementSkin::loadFont(FML::Node* node)
FontPtr UIElementSkin::loadFont(OTMLNode* node)
{
FontPtr font;
if(FML::Node* cnode = node->at("font"))
if(OTMLNode* cnode = node->at("font"))
font = g_fonts.get(cnode->value());
if(!font)
font = g_uiSkins.getDefaultFont();

@ -25,10 +25,11 @@
#ifndef UIELEMENTSKIN_H
#define UIELEMENTSKIN_H
#include <prerequisites.h>
#include <global.h>
#include <graphics/image.h>
#include <ui/uiconstants.h>
#include <graphics/font.h>
#include <otml/otmlnode.h>
class UIElement;
@ -42,7 +43,7 @@ public:
virtual ~UIElementSkin() { }
/// Load the skin from a FML node
virtual void load(FML::Node* node);
virtual void load(OTMLNode* node);
/// Apply the skin to an element
virtual void apply(UIElement *element);
/// Draw the skinned element
@ -56,8 +57,8 @@ public:
Color getFontColor() const { return m_fontColor; }
protected:
ImagePtr loadImage(FML::Node* node);
FontPtr loadFont(FML::Node* node);
ImagePtr loadImage(OTMLNode* node);
FontPtr loadFont(OTMLNode* node);
private:
std::string m_name;

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <ui/uilabel.h>
void UILabel::setText(const std::string& text)

@ -25,7 +25,7 @@
#ifndef UILABEL_H
#define UILABEL_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uielement.h>
#include <graphics/font.h>

@ -22,12 +22,12 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <graphics/fonts.h>
#include <ui/uilabelskin.h>
#include <ui/uilabel.h>
void UILabelSkin::load(FML::Node* node)
void UILabelSkin::load(OTMLNode* node)
{
UIElementSkin::load(node);
}

@ -25,7 +25,7 @@
#ifndef UILABELSKIN_H
#define UILABELSKIN_H
#include <prerequisites.h>
#include <global.h>
#include <graphics/font.h>
#include <ui/uielementskin.h>
@ -35,7 +35,7 @@ public:
UILabelSkin(const std::string& name) :
UIElementSkin(name, UI::Label) { }
void load(FML::Node* node);
void load(OTMLNode* node);
void apply(UIElement *element);
void draw(UIElement *element);
};

@ -25,7 +25,7 @@
#ifndef UILAYOUT_H
#define UILAYOUT_H
#include <prerequisites.h>
#include <global.h>
class UIElement;
typedef boost::shared_ptr<UIElement> UIElementPtr;

@ -22,13 +22,17 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/resources.h>
#include <ui/ui.h>
#include <ui/uiloader.h>
#include <script/luascript.h>
#include <script/luafunctions.h>
#include "uianchorlayout.h"
#include <otml/otml.h>
#include <ui/uianchorlayout.h>
#include <util/translator.h>
#include <boost/algorithm/string.hpp>
UILoader g_uiLoader;
@ -41,28 +45,26 @@ UIElementPtr UILoader::createElementFromId(const std::string& id)
if(split.size() != 2)
return element;
std::string elementType = split[0];
std::string elementType = split[0].substr(1);
std::string elementId = split[1];
if(elementType == "panel") {
if(elementType == "panel")
element = UIElementPtr(new UIContainer(UI::Panel));
} else if(elementType == "button") {
else if(elementType == "button")
element = UIElementPtr(new UIButton);
} else if(elementType == "label") {
else if(elementType == "label")
element = UIElementPtr(new UILabel);
} else if(elementType == "window") {
else if(elementType == "window")
element = UIElementPtr(new UIWindow);
} else if(elementType == "textEdit") {
else if(elementType == "textEdit")
element = UIElementPtr(new UITextEdit);
} else if(elementType == "lineDecoration") {
else if(elementType == "lineDecoration")
element = UIElementPtr(new UIElement(UI::LineDecoration));
} else if(elementType == "checkBox") {
else if(elementType == "checkBox")
element = UIElementPtr(new UICheckBox);
}
if(element) {
if(element)
element->setId(elementId);
}
return element;
}
@ -71,13 +73,13 @@ UIElementPtr UILoader::loadFromFile(std::string filePath, const UIContainerPtr&
{
std::stringstream fin;
if(!g_resources.loadFile(filePath, fin)) {
flogError("ERROR: Could not load ui %s", filePath.c_str());
error("ERROR: Could not load ui ", filePath);
return UIElementPtr();
}
try {
FML::Parser parser(fin, filePath);
FML::Node* doc = parser.getDocument();
OTMLParser parser(fin, filePath);
OTMLNode* doc = parser.getDocument();
// get element id
std::string elementId = doc->front()->tag();
@ -88,7 +90,7 @@ UIElementPtr UILoader::loadFromFile(std::string filePath, const UIContainerPtr&
// create element interpreting it's id
UIElementPtr element = createElementFromId(elementId);
if(!element) {
logError(doc->front()->generateErrorMessage("invalid root element type"));
error(doc->front()->generateErrorMessage("invalid root element type"));
return element;
}
parent->addChild(element);
@ -103,22 +105,22 @@ UIElementPtr UILoader::loadFromFile(std::string filePath, const UIContainerPtr&
// report onLoad events
element->onLoad();
return element;
} catch(FML::Exception e) {
flogError("ERROR: Failed to load ui %s: %s", filePath.c_str() % e.what());
} catch(OTMLException e) {
error("ERROR: Failed to load ui ",filePath,": ", e.what());
}
return UIElementPtr();
}
void UILoader::populateContainer(const UIContainerPtr& parent, FML::Node* node)
void UILoader::populateContainer(const UIContainerPtr& parent, OTMLNode* node)
{
// populate ordered elements
foreach(FML::Node* cnode, *node) {
foreach(OTMLNode* cnode, *node) {
std::string id = cnode->tag();
if(id.find("#") != std::string::npos) {
if(id[0] == '%') {
UIElementPtr element = createElementFromId(id);
if(!element) {
logError(cnode->generateErrorMessage("invalid element type"));
error(cnode->generateErrorMessage("invalid element type"));
continue;
}
parent->addChild(element);
@ -130,13 +132,13 @@ void UILoader::populateContainer(const UIContainerPtr& parent, FML::Node* node)
}
}
void UILoader::loadElements(const UIElementPtr& parent, FML::Node* node)
void UILoader::loadElements(const UIElementPtr& parent, OTMLNode* node)
{
loadElement(parent, node);
if(UIContainerPtr container = parent->asUIContainer()) {
foreach(const UIElementPtr& element, container->getChildren()) {
foreach(FML::Node* cnode, *node) {
foreach(OTMLNode* cnode, *node) {
// node found, load it
if(boost::ends_with(cnode->tag(), "#" + element->getId())) {
loadElements(element, cnode);
@ -147,10 +149,10 @@ void UILoader::loadElements(const UIElementPtr& parent, FML::Node* node)
}
}
void UILoader::loadElement(const UIElementPtr& element, FML::Node* node)
void UILoader::loadElement(const UIElementPtr& element, OTMLNode* node)
{
// set element skin
if(FML::Node* cnode = node->at("skin")) {
if(OTMLNode* cnode = node->at("skin")) {
if(cnode->hasValue()) {
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), cnode->value()));
} else {
@ -165,72 +167,61 @@ void UILoader::loadElement(const UIElementPtr& element, FML::Node* node)
if(node->hasNode("size"))
element->setSize(node->readAt<Size>("size"));
element->setMarginLeft(node->readAt("margin.left", 0));
element->setMarginRight(node->readAt("margin.right", 0));
element->setMarginTop(node->readAt("margin.top", 0));
element->setMarginBottom(node->readAt("margin.bottom", 0));
if(node->hasNode("anchors.left"))
loadElementAnchor(element, UI::AnchorLeft, node->at("anchors.left"));
if(node->hasNode("anchors.right"))
loadElementAnchor(element, UI::AnchorRight, node->at("anchors.right"));
if(node->hasNode("anchors.top"))
loadElementAnchor(element, UI::AnchorTop, node->at("anchors.top"));
if(node->hasNode("anchors.bottom"))
loadElementAnchor(element, UI::AnchorBottom, node->at("anchors.bottom"));
if(node->hasNode("anchors.horizontalCenter"))
loadElementAnchor(element, UI::AnchorHorizontalCenter, node->at("anchors.horizontalCenter"));
// load margins
element->setMarginLeft(node->readAtPath("margin/left", 0));
element->setMarginRight(node->readAtPath("margin/right", 0));
element->setMarginTop(node->readAtPath("margin/top", 0));
element->setMarginBottom(node->readAtPath("margin/bottom", 0));
if(node->hasNode("anchors.verticalCenter"))
loadElementAnchor(element, UI::AnchorVerticalCenter, node->at("anchors.verticalCenter"));
// load anchors
loadElementAnchor(element, UI::AnchorLeft, node->atPath("anchors/left"));
loadElementAnchor(element, UI::AnchorRight, node->atPath("anchors/right"));
loadElementAnchor(element, UI::AnchorTop, node->atPath("anchors/top"));
loadElementAnchor(element, UI::AnchorBottom, node->atPath("anchors/bottom"));
loadElementAnchor(element, UI::AnchorHorizontalCenter, node->atPath("anchors/horizontalCenter"));
loadElementAnchor(element, UI::AnchorVerticalCenter, node->atPath("anchors/verticalCenter"));
// load events
if(FML::Node* cnode = node->at("onLoad")) {
if(g_lua.loadBufferAsFunction(cnode->value(), getElementSourceDesc(element, cnode)))
g_lua.setScriptableField(element, "onLoad");
else
logError(cnode->generateErrorMessage("failed to parse inline lua script"));
}
if(FML::Node* cnode = node->at("onDestroy")) {
if(g_lua.loadBufferAsFunction(cnode->value(), getElementSourceDesc(element, cnode)))
g_lua.setScriptableField(element, "onDestroy");
else
logError(cnode->generateErrorMessage("failed to parse inline lua script"));
}
// load basic element events
loadElementScriptFunction(element, node->at("onLoad"));
loadElementScriptFunction(element, node->at("onDestroy"));
// load specific element type
if(element->getElementType() == UI::Button)
loadButton(boost::static_pointer_cast<UIButton>(element), node);
else if(element->getElementType() == UI::Window) {
UIWindowPtr window = boost::static_pointer_cast<UIWindow>(element);
window->setTitle(node->readAt("title", std::string()));
}
else if(element->getElementType() == UI::Label) {
UILabelPtr label = boost::static_pointer_cast<UILabel>(element);
label->setText(node->readAt("text", std::string()));
label->setAlign(parseAlignment(node->readAt("align", std::string("left"))));
}
switch(element->getElementType()) {
case UI::Button:
loadButton(boost::static_pointer_cast<UIButton>(element), node);
break;
case UI::Window:
loadWindow(boost::static_pointer_cast<UIWindow>(element), node);
break;
case UI::Label:
loadLabel(boost::static_pointer_cast<UILabel>(element), node);
break;
default:
break;
}
}
void UILoader::loadElementAnchor(const UIElementPtr& anchoredElement, UI::AnchorPoint anchoredEdge, FML::Node* node)
void UILoader::loadElementAnchor(const UIElementPtr& anchoredElement, UI::AnchorPoint anchoredEdge, OTMLNode* node)
{
if(!node)
return;
std::string anchorDescription = node->value();
if(anchorDescription.empty()) {
error(node->generateErrorMessage("anchor is empty, did you forget to fill it?"));
return;
}
UIAnchorLayoutPtr layout = boost::dynamic_pointer_cast<UIAnchorLayout>(anchoredElement->getLayout());
if(!layout) {
logError(node->generateErrorMessage("could not add anchor, because this element does not participate of an anchor layout"));
error(node->generateErrorMessage("could not add anchor, because this element does not participate of an anchor layout"));
return;
}
std::string anchorDescription = node->value();
std::vector<std::string> split;
boost::split(split, anchorDescription, boost::is_any_of(std::string(".")));
if(split.size() != 2) {
logError(node->generateErrorMessage("invalid anchor"));
error(node->generateErrorMessage("invalid anchor"));
return;
}
@ -238,33 +229,42 @@ void UILoader::loadElementAnchor(const UIElementPtr& anchoredElement, UI::Anchor
UI::AnchorPoint anchorLineEdge = UIAnchorLayout::parseAnchorPoint(split[1]);
if(anchorLineEdge == UI::AnchorNone) {
logError(node->generateErrorMessage("invalid anchor type"));
error(node->generateErrorMessage("invalid anchor type"));
return;
}
if(!layout->addAnchor(anchoredElement, anchoredEdge, AnchorLine(anchorLineElementId, anchorLineEdge)))
logError(node->generateErrorMessage("anchoring failed"));
error(node->generateErrorMessage("anchoring failed"));
}
void UILoader::loadButton(const UIButtonPtr& button, FML::Node* node)
void UILoader::loadElementScriptFunction(const UIElementPtr& element, OTMLNode* node)
{
button->setText(node->valueAt("text"));
if(!node)
return;
// set on click event
if(FML::Node* cnode = node->at("onClick")) {
if(g_lua.loadBufferAsFunction(cnode->value(), getElementSourceDesc(button, cnode)))
g_lua.setScriptableField(button, "onClick");
else
logError(cnode->generateErrorMessage("failed to parse inline lua script"));
}
std::string functionDesc;
functionDesc += g_resources.resolvePath(node->what()) + ":" + element->getId();
functionDesc += "[" + node->tag() + "]";
if(g_lua.loadBufferAsFunction(node->value(), functionDesc))
g_lua.setScriptableField(element, node->tag());
else
error(node->generateErrorMessage("failed to parse inline lua script"));
}
std::string UILoader::getElementSourceDesc(const UIElementPtr& element, const FML::Node *node)
void UILoader::loadButton(const UIButtonPtr& button, OTMLNode* node)
{
std::string desc;
desc += g_resources.resolvePath(node->what()) + ":" + element->getId();
if(!node->tag().empty())
desc += "[" + node->tag() + "]";
return desc;
button->setText(node->valueAt("text"));
loadElementScriptFunction(button, node->at("onClick"));
}
void UILoader::loadWindow(const UIWindowPtr& window, OTMLNode* node)
{
window->setTitle(node->readAt("title", std::string()));
}
void UILoader::loadLabel(const UILabelPtr& label, OTMLNode* node)
{
label->setText(node->readAt("text", std::string()));
label->setAlign(parseAlignment(node->readAt("align", std::string("left"))));
}

@ -25,10 +25,12 @@
#ifndef UILOADER_H
#define UILOADER_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uiconstants.h>
#include <ui/uicontainer.h>
#include <ui/uibutton.h>
#include <ui/uiwindow.h>
#include <ui/uilabel.h>
class UILoader
{
@ -40,22 +42,25 @@ private:
/// Detect element type and create it
UIElementPtr createElementFromId(const std::string& id);
/// Populate container children from a FML node
void populateContainer(const UIContainerPtr& parent, FML::Node* node);
/// Populate container children from a OTML node
void populateContainer(const UIContainerPtr& parent, OTMLNode* node);
/// Load element and its children from a FML node
void loadElements(const UIElementPtr& parent, FML::Node* node);
/// Load element and its children from a OTML node
void loadElements(const UIElementPtr& parent, OTMLNode* node);
/// Load element proprieties from a FML node
void loadElement(const UIElementPtr& element, FML::Node* node);
/// Load element proprieties from a OTML node
void loadElement(const UIElementPtr& element, OTMLNode* node);
/// Load anchor from a FML node
void loadElementAnchor(const UIElementPtr& anchoredElement, UI::AnchorPoint anchoredEdge, FML::Node* node);
/// Load anchor from a OTML node
void loadElementAnchor(const UIElementPtr& anchoredElement, UI::AnchorPoint anchoredEdge, OTMLNode* node);
// specific elements loading
void loadButton(const UIButtonPtr& button, FML::Node* node);
/// Load element lua function
void loadElementScriptFunction(const UIElementPtr& element, OTMLNode* node);
std::string getElementSourceDesc(const UIElementPtr& element, const FML::Node *node);
// specific elements loading
void loadButton(const UIButtonPtr& button, OTMLNode* node);
void loadWindow(const UIWindowPtr& window, OTMLNode* node);
void loadLabel(const UILabelPtr& label, OTMLNode* node);
};
extern UILoader g_uiLoader;

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <core/resources.h>
#include <graphics/textures.h>
#include <ui/uiskins.h>
@ -32,6 +32,7 @@
#include <ui/uitexteditskin.h>
#include <ui/uilabelskin.h>
#include <graphics/fonts.h>
#include <otml/otml.h>
UISkins g_uiSkins;
@ -41,15 +42,15 @@ void UISkins::load(const std::string& skinName)
std::stringstream fin;
if(!g_resources.loadFile(skinName + ".yml", fin))
flogFatal("FATAL ERROR: Could not load skin \"%s", skinName.c_str());
fatal("FATAL ERROR: Could not load skin '",skinName,"'");
try {
FML::Parser parser(fin, skinName);
FML::Node* doc = parser.getDocument();
OTMLParser parser(fin, skinName);
OTMLNode* doc = parser.getDocument();
m_defaultFont = g_fonts.get(doc->valueAt("default font"));
if(!m_defaultFont)
logFatal("FATAL ERROR: Could not load skin default font");
fatal("FATAL ERROR: Could not load skin default font");
m_defaultFontColor = doc->readAt("default font color", Color::white);
@ -57,9 +58,9 @@ void UISkins::load(const std::string& skinName)
if(!defaultTextureName.empty())
m_defaultTexture = g_textures.get(defaultTextureName);
foreach(FML::Node* node, *doc) {
foreach(OTMLNode* node, *doc) {
UIElementSkinPtr skin;
foreach(FML::Node* cnode, *node) {
foreach(OTMLNode* cnode, *node) {
if(node->tag() == "buttons")
skin = UIElementSkinPtr(new UIButtonSkin(cnode->tag()));
else if(node->tag() == "panels")
@ -79,8 +80,8 @@ void UISkins::load(const std::string& skinName)
m_elementSkins.push_back(skin);
}
}
} catch(FML::Exception e) {
flogFatal("FATAL ERROR: Malformed skin file \"%s\":\n %s", skinName.c_str() % e.what());
} catch(OTMLException e) {
fatal("FATAL ERROR: Malformed skin file '",skinName,"':\n ",e.what());
}
g_resources.popCurrentPath();
@ -99,6 +100,6 @@ UIElementSkinPtr UISkins::getElementSkin(UI::ElementType elementType, const std:
if(elementType == skin->getElementType() && name == skin->getName())
return skin;
}
flogWarning("Element skin '%s' not found", name.c_str());
warning("Element skin '",name,"' not found");
return UIElementSkinPtr();
}

@ -25,7 +25,7 @@
#ifndef UISKIN_H
#define UISKIN_H
#include <prerequisites.h>
#include <global.h>
#include <graphics/texture.h>
#include <ui/uielementskin.h>
#include <graphics/font.h>

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <ui/uitextedit.h>
#include <ui/uitexteditskin.h>
#include <ui/uicontainer.h>

@ -25,7 +25,7 @@
#ifndef UITEXTEDIT_H
#define UITEXTEDIT_H
#include <prerequisites.h>
#include <global.h>
#include <graphics/textarea.h>
#include <ui/uielement.h>

@ -22,12 +22,12 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <graphics/fonts.h>
#include <ui/uitexteditskin.h>
#include <ui/uitextedit.h>
void UITextEditSkin::load(FML::Node* node)
void UITextEditSkin::load(OTMLNode* node)
{
UIElementSkin::load(node);
m_textMargin = node->readAt("text margin", 2);

@ -25,7 +25,7 @@
#ifndef UITEXTEDITSKIN_H
#define UITEXTEDITSKIN_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uielementskin.h>
class Font;
@ -36,7 +36,7 @@ public:
UITextEditSkin(const std::string& name) :
UIElementSkin(name, UI::TextEdit) { }
void load(FML::Node* node);
void load(OTMLNode* node);
void apply(UIElement *element);
void draw(UIElement *element);

@ -22,7 +22,7 @@
*/
#include <prerequisites.h>
#include <global.h>
#include <ui/uiwindow.h>
#include <ui/uiwindowskin.h>

@ -25,7 +25,7 @@
#ifndef UIWINDOW_H
#define UIWINDOW_H
#include <prerequisites.h>
#include <global.h>
#include <ui/uicontainer.h>
class UIWindow : public UIContainer

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save