rewrite and reoganize tools functions

* create stdext namespace which contains additional C++ algorithms
* organize stdext in string, math, cast and exception utilities
This commit is contained in:
Eduardo Bart 2012-05-28 10:06:26 -03:00
parent 2676eb4da3
commit 4c80d783d6
75 changed files with 856 additions and 652 deletions

1
TODO
View File

@ -46,6 +46,7 @@ move rendering of creatures names, skulls, etc to UI and scripts
clean sprites cache periodically
handle corrupt errors in dat/spr
throw exceptions when fail to read a file
fix C++ exceptions messages inside onExtendedOpcode
* framework
rework Settings/g_configs

View File

@ -107,6 +107,7 @@ function Locales.setLocale(name)
return true
end
-- global function used to translate texts
function tr(text, ...)
if currentLocale then
if tonumber(text) then

View File

@ -170,8 +170,7 @@ SET(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
# framework util
${CMAKE_CURRENT_LIST_DIR}/util/utf8.cpp
${CMAKE_CURRENT_LIST_DIR}/math/color.cpp
${CMAKE_CURRENT_LIST_DIR}/util/color.cpp
# framework core
${CMAKE_CURRENT_LIST_DIR}/core/logger.cpp

View File

@ -23,8 +23,6 @@
#ifndef FRAMEWORK_CONST_H
#define FRAMEWORK_CONST_H
#include "util/types.h"
#define DEG_TO_RAD (acos(-1)/180.0)
#define RAD_TO_DEC (180.0/acos(-1))
@ -44,7 +42,7 @@ namespace Fw
constexpr float pi = 3.14159265;
constexpr float MIN_ALPHA = 0.003f;
enum Key : uint8 {
enum Key : unsigned char {
KeyUnknown = 0,
KeyEscape = 1,
KeyTab = 2,

View File

@ -44,7 +44,7 @@ bool ConfigManager::load(const std::string& file)
if(confsDoc)
m_confsDoc = confsDoc;
return true;
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("could not load configurations: ", e.what());
return false;
}

View File

@ -72,7 +72,7 @@ void EventDispatcher::poll()
}
}
ScheduledEventPtr EventDispatcher::scheduleEvent(const SimpleCallback& callback, int delay)
ScheduledEventPtr EventDispatcher::scheduleEvent(const std::function<void()>& callback, int delay)
{
assert(delay >= 0);
ScheduledEventPtr scheduledEvent(new ScheduledEvent(callback, delay));
@ -80,7 +80,7 @@ ScheduledEventPtr EventDispatcher::scheduleEvent(const SimpleCallback& callback,
return scheduledEvent;
}
EventPtr EventDispatcher::addEvent(const SimpleCallback& callback, bool pushFront)
EventPtr EventDispatcher::addEvent(const std::function<void()>& callback, bool pushFront)
{
EventPtr event(new Event(callback));
// front pushing is a way to execute an event before others

View File

@ -30,7 +30,7 @@
class Event : public LuaObject
{
public:
Event(const SimpleCallback& callback) : m_callback(callback), m_canceled(false), m_executed(false) { }
Event(const std::function<void()>& callback) : m_callback(callback), m_canceled(false), m_executed(false) { }
void execute() {
if(!m_canceled && !m_executed && m_callback) {
@ -44,7 +44,7 @@ public:
bool isExecuted() { return m_executed; }
protected:
SimpleCallback m_callback;
std::function<void()> m_callback;
bool m_canceled;
bool m_executed;
};
@ -52,7 +52,7 @@ protected:
class ScheduledEvent : public Event
{
public:
ScheduledEvent(const SimpleCallback& callback, int delay) : Event(callback) {
ScheduledEvent(const std::function<void()>& callback, int delay) : Event(callback) {
m_ticks = g_clock.ticksFor(delay);
}
@ -75,8 +75,8 @@ public:
void flush();
void poll();
EventPtr addEvent(const SimpleCallback& callback, bool pushFront = false);
ScheduledEventPtr scheduleEvent(const SimpleCallback& callback, int delay);
EventPtr addEvent(const std::function<void()>& callback, bool pushFront = false);
ScheduledEventPtr scheduleEvent(const std::function<void()>& callback, int delay);
private:
std::list<EventPtr> m_eventList;

View File

@ -181,7 +181,7 @@ uint16 FileStream::getU16()
return 0;
}
v = Fw::readLE16(&m_cacheBuffer[m_cacheReadPos]);
v = stdext::readLE16(&m_cacheBuffer[m_cacheReadPos]);
m_cacheReadPos += 2;
}
return v;
@ -199,7 +199,7 @@ uint32 FileStream::getU32()
return 0;
}
v = Fw::readLE32(&m_cacheBuffer[m_cacheReadPos]);
v = stdext::readLE32(&m_cacheBuffer[m_cacheReadPos]);
m_cacheReadPos += 4;
}
return v;
@ -217,7 +217,7 @@ uint64 FileStream::getU64()
return 0;
}
v = Fw::readLE64(&m_cacheBuffer[m_cacheReadPos]);
v = stdext::readLE64(&m_cacheBuffer[m_cacheReadPos]);
m_cacheReadPos += 8;
}
return v;

View File

@ -93,6 +93,6 @@ void Logger::setLogFile(const std::string& file)
return;
}
m_outFile << "\n== application started at " << Fw::dateTimeString() << std::endl;
m_outFile << "\n== application started at " << stdext::date_time_string() << std::endl;
m_outFile.flush();
}

View File

@ -57,17 +57,17 @@ private:
extern Logger g_logger;
// specialized logging
#define logDebug(...) g_logger.log(Fw::LogDebug, Fw::mkstr(__VA_ARGS__))
#define logInfo(...) g_logger.log(Fw::LogInfo, Fw::mkstr(__VA_ARGS__))
#define logWarning(...) g_logger.log(Fw::LogWarning, Fw::mkstr(__VA_ARGS__))
#define logError(...) g_logger.log(Fw::LogError, Fw::mkstr(__VA_ARGS__))
#define logFatal(...) g_logger.log(Fw::LogFatal, Fw::mkstr(__VA_ARGS__))
#define logDebug(...) g_logger.log(Fw::LogDebug, stdext::mkstr(__VA_ARGS__))
#define logInfo(...) g_logger.log(Fw::LogInfo, stdext::mkstr(__VA_ARGS__))
#define logWarning(...) g_logger.log(Fw::LogWarning, stdext::mkstr(__VA_ARGS__))
#define logError(...) g_logger.log(Fw::LogError, stdext::mkstr(__VA_ARGS__))
#define logFatal(...) g_logger.log(Fw::LogFatal, stdext::mkstr(__VA_ARGS__))
#define logTrace() g_logger.logFunc(Fw::LogDebug, "", __PRETTY_FUNCTION__)
#define logTraceDebug(...) g_logger.logFunc(Fw::LogDebug, Fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
#define logTraceInfo(...) g_logger.logFunc(Fw::LogInfo, Fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
#define logTraceWarning(...) g_logger.logFunc(Fw::LogWarning, Fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
#define logTraceError(...) g_logger.logFunc(Fw::LogError, Fw::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
#define logTraceDebug(...) g_logger.logFunc(Fw::LogDebug, stdext::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
#define logTraceInfo(...) g_logger.logFunc(Fw::LogInfo, stdext::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
#define logTraceWarning(...) g_logger.logFunc(Fw::LogWarning, stdext::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
#define logTraceError(...) g_logger.logFunc(Fw::LogError, stdext::mkstr(__VA_ARGS__), __PRETTY_FUNCTION__)
#define logTraceCounter() { \
static int __count = 0; \

View File

@ -120,14 +120,14 @@ void Module::discover(const OTMLNodePtr& moduleNode)
if(OTMLNodePtr node = moduleNode->get("@onLoad")) {
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
g_lua.useValue();
m_loadCallback = g_lua.polymorphicPop<SimpleCallback>();
m_loadCallback = g_lua.polymorphicPop<std::function<void()>>();
}
// set onUnload callback
if(OTMLNodePtr node = moduleNode->get("@onUnload")) {
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
g_lua.useValue();
m_unloadCallback = g_lua.polymorphicPop<SimpleCallback>();
m_unloadCallback = g_lua.polymorphicPop<std::function<void()>>();
}
if(OTMLNodePtr node = moduleNode->get("load-later")) {

View File

@ -68,8 +68,8 @@ private:
std::string m_author;
std::string m_website;
std::string m_version;
SimpleCallback m_loadCallback;
SimpleCallback m_unloadCallback;
std::function<void()> m_loadCallback;
std::function<void()> m_unloadCallback;
std::list<std::string> m_dependencies;
std::list<std::string> m_loadLaterModules;
};

View File

@ -104,7 +104,7 @@ ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
std::string name = moduleNode->valueAt("name");
//if(getModule(name))
// Fw::throwException("module '", name, "' already exists, cannot have duplicate module names");
// stdext::throw_exception("module '", name, "' already exists, cannot have duplicate module names");
bool push = false;
module = getModule(name);
@ -117,7 +117,7 @@ ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
// not loaded modules are always in back
if(push)
m_modules.push_back(module);
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("Unable to discover module from file '", moduleFile, "': ", e.what());
}
return module;

View File

@ -43,7 +43,7 @@ void ResourceManager::terminate()
bool ResourceManager::setupWriteDir(const std::string& appWriteDirName)
{
std::string userDir = PHYSFS_getUserDir();
std::string dirName = Fw::mkstr(".", appWriteDirName);
std::string dirName = stdext::mkstr(".", appWriteDirName);
std::string writeDir = userDir + dirName;
if(!PHYSFS_setWriteDir(writeDir.c_str())) {
if(!PHYSFS_setWriteDir(userDir.c_str()))
@ -92,7 +92,7 @@ void ResourceManager::loadFile(const std::string& fileName, std::iostream& out)
PHYSFS_file* file = PHYSFS_openRead(fullPath.c_str());
if(!file) {
out.clear(std::ios::failbit);
Fw::throwException("failed to load file '", fullPath.c_str(), "': ", PHYSFS_getLastError());
stdext::throw_exception(stdext::format("failed to load file '%s': %s", fullPath.c_str(), PHYSFS_getLastError()));
} else {
int fileSize = PHYSFS_fileLength(file);
if(fileSize > 0) {

View File

@ -23,7 +23,7 @@
#ifndef TIMER_H
#define TIMER_H
#include <framework/util/types.h>
#include <framework/global.h>
class Timer
{

View File

@ -23,7 +23,7 @@
#ifndef FRAMEWORK_GLOBAL_H
#define FRAMEWORK_GLOBAL_H
#include "util/compiler.h"
#include "stdext/compiler.h"
// common C/C++ headers
#include "pch.h"
@ -31,14 +31,16 @@
// global constants
#include "const.h"
// stdext which includes additional C++ algorithms
#include "stdext/stdext.h"
// additional utilities
#include "util/types.h"
#include "util/tools.h"
#include "math/point.h"
#include "math/color.h"
#include "math/rect.h"
#include "math/size.h"
#include "math/matrix.h"
#include "util/point.h"
#include "util/color.h"
#include "util/rect.h"
#include "util/size.h"
#include "util/matrix.h"
#include "util/boolean.h"
// logger
#include "core/logger.h"

View File

@ -30,7 +30,7 @@
void Font::load(const OTMLNodePtr& fontNode)
{
OTMLNodePtr textureNode = fontNode->at("texture");
std::string textureFile = Fw::resolvePath(textureNode->value(), textureNode->source());
std::string textureFile = stdext::resolve_path(textureNode->value(), textureNode->source());
Size glyphSize = fontNode->valueAt<Size>("glyph-size");
m_glyphHeight = fontNode->valueAt<int>("height");
m_yOffset = fontNode->valueAt("y-offset", 0);
@ -53,7 +53,7 @@ void Font::load(const OTMLNodePtr& fontNode)
// read custom widths
if(OTMLNodePtr node = fontNode->get("glyph-widths")) {
for(const OTMLNodePtr& child : node->children())
m_glyphsSize[Fw::safeCast<int>(child->tag())].setWidth(child->value<int>());
m_glyphsSize[stdext::safe_cast<int>(child->tag())].setWidth(child->value<int>());
}
// calculate glyphs texture coords
@ -285,7 +285,7 @@ std::string Font::wrapText(const std::string& text, int maxWidth)
std::string outText;
std::string line;
std::vector<std::string> words;
std::vector<std::string> wordsSplit = Fw::split(text);
std::vector<std::string> wordsSplit = stdext::split(text);
// break huge words into small ones
for(uint i=0;i<wordsSplit.size();++i) {

View File

@ -49,7 +49,7 @@ bool FontManager::importFont(std::string fontFile)
std::string name = fontNode->valueAt("name");
//if(fontExists(name))
// Fw::throwException("font '", name, "' already exists, cannot have duplicate font names");
// stdext::throw_exception("font '", name, "' already exists, cannot have duplicate font names");
// remove any font with the same name
for(auto it = m_fonts.begin(); it != m_fonts.end(); ++it) {
@ -68,7 +68,7 @@ bool FontManager::importFont(std::string fontFile)
m_defaultFont = font;
return true;
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("Unable to load font from file '", fontFile, "': ", e.what());
return false;
}

View File

@ -41,11 +41,11 @@ ImagePtr Image::load(const std::string& file)
try {
// currently only png images are supported
if(!boost::ends_with(file, ".png"))
Fw::throwException("image file format no supported");
stdext::throw_exception("image file format no supported");
// load image file data
image = loadPNG(file);
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("unable to load image '", file, "': ", e.what());
}
return image;

View File

@ -71,8 +71,8 @@ bool ParticleAffector::load(const OTMLNodePtr& node)
maxDuration = childNode->value<float>();
}
m_delay = Fw::randomRange(minDelay, maxDelay);
m_duration = Fw::randomRange(minDuration, maxDuration);
m_delay = stdext::random_range(minDelay, maxDelay);
m_duration = stdext::random_range(minDuration, maxDuration);
return true;
}

View File

@ -25,7 +25,6 @@
#include "particlesystem.h"
#include <framework/core/clock.h>
#include <framework/graphics/texturemanager.h>
#include <framework/util/tools.h>
ParticleEmitter::ParticleEmitter(const ParticleSystemPtr& parent)
{
@ -152,9 +151,9 @@ bool ParticleEmitter::load(const OTMLNodePtr& node)
m_pFinalSize = childNode->value<Size>();
else if(childNode->tag() == "particle-colors")
m_pColors = Fw::split<Color>(childNode->value());
m_pColors = stdext::split<Color>(childNode->value());
else if(childNode->tag() == "particle-colors-stops")
m_pColorsStops = Fw::split<float>(childNode->value());
m_pColorsStops = stdext::split<float>(childNode->value());
else if(childNode->tag() == "particle-texture")
m_pTexture = g_textures.getTexture(childNode->value());
else if(childNode->tag() == "particle-composition-mode") {
@ -196,23 +195,23 @@ void ParticleEmitter::update(float elapsedTime)
for(int b = m_currentBurst; b < currentBurst; ++b) {
// every burst created at same position.
float pRadius = Fw::randomRange(m_pMinPositionRadius, m_pMaxPositionRadius);
float pAngle = Fw::randomRange(m_pMinPositionAngle, m_pMaxPositionAngle);
float pRadius = stdext::random_range(m_pMinPositionRadius, m_pMaxPositionRadius);
float pAngle = stdext::random_range(m_pMinPositionAngle, m_pMaxPositionAngle);
Point pPosition = m_position + Point(pRadius * cos(pAngle), pRadius * sin(pAngle));
for(int p = 0; p < m_burstCount; ++p) {
float pDuration = Fw::randomRange(m_pMinDuration, m_pMaxDuration);
float pDuration = stdext::random_range(m_pMinDuration, m_pMaxDuration);
// particles initial velocity
float pVelocityAbs = Fw::randomRange(m_pMinVelocity, m_pMaxVelocity);
float pVelocityAngle = Fw::randomRange(m_pMinVelocityAngle, m_pMaxVelocityAngle);
float pVelocityAbs = stdext::random_range(m_pMinVelocity, m_pMaxVelocity);
float pVelocityAngle = stdext::random_range(m_pMinVelocityAngle, m_pMaxVelocityAngle);
PointF pVelocity(pVelocityAbs * cos(pVelocityAngle), pVelocityAbs * sin(pVelocityAngle));
// particles initial acceleration
float pAccelerationAbs = Fw::randomRange(m_pMinAcceleration, m_pMaxAcceleration);
float pAccelerationAngle = Fw::randomRange(m_pMinAccelerationAngle, m_pMaxAccelerationAngle);
float pAccelerationAbs = stdext::random_range(m_pMinAcceleration, m_pMaxAcceleration);
float pAccelerationAngle = stdext::random_range(m_pMinAccelerationAngle, m_pMaxAccelerationAngle);
PointF pAcceleration(pAccelerationAbs * cos(pAccelerationAngle), pAccelerationAbs * sin(pAccelerationAngle));
ParticleSystemPtr particleSystem = m_parent.lock();

View File

@ -38,7 +38,7 @@ bool ParticleManager::load(const std::string& filename)
}
}
return true;
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("could not load particles: ", e.what());
return false;
}

View File

@ -50,13 +50,13 @@ TexturePtr TextureManager::getTexture(const std::string& fileName)
try {
// currently only png textures are supported
if(!boost::ends_with(filePath, ".png"))
Fw::throwException("texture file format no supported");
stdext::throw_exception("texture file format no supported");
// load texture file data
std::stringstream fin;
g_resources.loadFile(filePath, fin);
texture = loadPNG(fin);
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("unable to load texture '", fileName, "': ", e.what());
texture = g_graphics.getEmptyTexture();
}

View File

@ -37,14 +37,14 @@
void Application::registerLuaFunctions()
{
// conversion globals
g_lua.bindGlobalFunction("torect", [](const std::string& v) { return Fw::fromstring<Rect>(v); });
g_lua.bindGlobalFunction("topoint", [](const std::string& v) { return Fw::fromstring<Point>(v); });
g_lua.bindGlobalFunction("tocolor", [](const std::string& v) { return Fw::fromstring<Color>(v); });
g_lua.bindGlobalFunction("tosize", [](const std::string& v) { return Fw::fromstring<Size>(v); });
g_lua.bindGlobalFunction("recttostring", [](const Rect& v) { return Fw::tostring(v); });
g_lua.bindGlobalFunction("pointtostring", [](const Point& v) { return Fw::tostring(v); });
g_lua.bindGlobalFunction("colortostring", [](const Color& v) { return Fw::tostring(v); });
g_lua.bindGlobalFunction("sizetostring", [](const Size& v) { return Fw::tostring(v); });
g_lua.bindGlobalFunction("torect", [](const std::string& v) { return stdext::from_string<Rect>(v); });
g_lua.bindGlobalFunction("topoint", [](const std::string& v) { return stdext::from_string<Point>(v); });
g_lua.bindGlobalFunction("tocolor", [](const std::string& v) { return stdext::from_string<Color>(v); });
g_lua.bindGlobalFunction("tosize", [](const std::string& v) { return stdext::from_string<Size>(v); });
g_lua.bindGlobalFunction("recttostring", [](const Rect& v) { return stdext::to_string(v); });
g_lua.bindGlobalFunction("pointtostring", [](const Point& v) { return stdext::to_string(v); });
g_lua.bindGlobalFunction("colortostring", [](const Color& v) { return stdext::to_string(v); });
g_lua.bindGlobalFunction("sizetostring", [](const Size& v) { return stdext::to_string(v); });
// Event
g_lua.registerClass<Event>();

View File

@ -33,21 +33,21 @@ void LuaException::generateLuaErrorMessage(const std::string& error, int traceLe
{
// append trace level to error message
if(traceLevel >= 0)
m_what = Fw::mkstr("LUA ERROR: ", g_lua.traceback(error, traceLevel));
m_what = stdext::mkstr("LUA ERROR: ", g_lua.traceback(error, traceLevel));
else
m_what = Fw::mkstr("LUA ERROR: ", error);
m_what = stdext::mkstr("LUA ERROR: ", error);
}
LuaBadNumberOfArgumentsException::LuaBadNumberOfArgumentsException(int expected, int got)
{
std::string error = "attempt to call a function with wrong number of arguments";
if(expected >= 0 && got >= 0)
error = Fw::mkstr(error, " (expected ", expected, ", but got ", got, ")");
error = stdext::mkstr(error, " (expected ", expected, ", but got ", got, ")");
generateLuaErrorMessage(error, 1);
}
LuaBadValueCastException::LuaBadValueCastException(const std::string& luaTypeName, const std::string& cppTypeName)
{
std::string error = Fw::mkstr("attempt to cast a '", luaTypeName, "' lua value to '", cppTypeName, "'");
std::string error = stdext::mkstr("attempt to cast a '", luaTypeName, "' lua value to '", cppTypeName, "'");
generateLuaErrorMessage(error, 0);
}

View File

@ -25,7 +25,7 @@
#include "declarations.h"
class LuaException : public Exception
class LuaException : public stdext::exception
{
public:
LuaException(const std::string& error, int traceLevel = -1);

View File

@ -46,7 +46,7 @@ void LuaInterface::init()
createLuaState();
// check if demangle_type is working as expected
assert(Fw::demangleType<LuaObject>() == "LuaObject");
assert(stdext::demangle_type<LuaObject>() == "LuaObject");
// register LuaObject, the base of all other objects
registerClass<LuaObject>();
@ -163,12 +163,12 @@ void LuaInterface::registerClassMemberField(const std::string& className,
if(getFunction) {
pushCppFunction(getFunction);
setField(Fw::mkstr("get_", field));
setField(stdext::mkstr("get_", field));
}
if(setFunction) {
pushCppFunction(setFunction);
setField(Fw::mkstr("set_", field));
setField(stdext::mkstr("set_", field));
}
pop();
@ -310,7 +310,7 @@ void LuaInterface::loadScript(const std::string& fileName)
std::string buffer = g_resources.loadFile(filePath);
std::string source = "@" + filePath;
loadBuffer(buffer, source);
} catch(Exception& e) {
} catch(stdext::exception& e) {
throw LuaException(e.what());
}
}
@ -324,9 +324,9 @@ void LuaInterface::loadFunction(const std::string& buffer, const std::string& so
std::string buf;
if(boost::starts_with(buffer, "function"))
buf = Fw::mkstr("__func = ", buffer);
buf = stdext::mkstr("__func = ", buffer);
else
buf = Fw::mkstr("__func = function(self)\n", buffer,"\nend");
buf = stdext::mkstr("__func = function(self)\n", buffer,"\nend");
loadBuffer(buf, source);
safeCall();
@ -343,7 +343,7 @@ void LuaInterface::evaluateExpression(const std::string& expression, const std::
{
// evaluates the expression
if(!expression.empty()) {
std::string buffer = Fw::mkstr("__exp = (", expression, ")");
std::string buffer = stdext::mkstr("__exp = (", expression, ")");
loadBuffer(buffer, source);
safeCall();
@ -1019,7 +1019,7 @@ void LuaInterface::pushObject(const LuaObjectPtr& obj)
new(newUserdata(sizeof(LuaObjectPtr))) LuaObjectPtr(obj);
// set the userdata metatable
getGlobal(Fw::mkstr(obj->getClassName(), "_mt"));
getGlobal(stdext::mkstr(obj->getClassName(), "_mt"));
assert(!isNil());
setMetatable();
}

View File

@ -64,24 +64,24 @@ public:
// register shortcuts using templates
template<class C, class B = LuaObject>
void registerClass() {
registerClass(Fw::demangleType<C>(), Fw::demangleType<B>());
registerClass(stdext::demangle_type<C>(), stdext::demangle_type<B>());
}
template<class C>
void registerClassStaticFunction(const std::string& functionName, const LuaCppFunction& function) {
registerClassStaticFunction(Fw::demangleType<C>(), functionName, function);
registerClassStaticFunction(stdext::demangle_type<C>(), functionName, function);
}
template<class C>
void registerClassMemberFunction(const std::string& functionName, const LuaCppFunction& function) {
registerClassMemberFunction(Fw::demangleType<C>(), functionName, function);
registerClassMemberFunction(stdext::demangle_type<C>(), functionName, function);
}
template<class C>
void registerClassMemberField(const std::string& field,
const LuaCppFunction& getFunction,
const LuaCppFunction& setFunction) {
registerClassMemberField(Fw::demangleType<C>(), field, getFunction, setFunction);
registerClassMemberField(stdext::demangle_type<C>(), field, getFunction, setFunction);
}
// methods for binding functions
@ -388,7 +388,7 @@ template<class T>
T LuaInterface::castValue(int index) {
T o;
if(!luavalue_cast(index, o))
throw LuaBadValueCastException(typeName(index), Fw::demangleType<T>());
throw LuaBadValueCastException(typeName(index), stdext::demangle_type<T>());
return o;
}

View File

@ -70,7 +70,7 @@ public:
/// Returns the derived class name, its the same name used in Lua
virtual std::string getClassName() const {
// TODO: this could be cached for more performance
return Fw::demangleName(typeid(*this).name());
return stdext::demangle_name(typeid(*this).name());
}
LuaObjectPtr asLuaObject() { return shared_from_this(); }

View File

@ -114,7 +114,7 @@ bool luavalue_cast(int index, Color& color)
color.setAlpha(g_lua.popInteger());
return true;
} else if(g_lua.isString()) {
return Fw::cast(g_lua.toString(index), color);
return stdext::cast(g_lua.toString(index), color);
} else if(g_lua.isNil()) {
color = Color::white;
return true;
@ -149,7 +149,7 @@ bool luavalue_cast(int index, Rect& rect)
rect.setHeight(g_lua.popInteger());
return true;
} else if(g_lua.isString()) {
return Fw::cast(g_lua.toString(index), rect);
return stdext::cast(g_lua.toString(index), rect);
} else if(g_lua.isNil()) {
rect = Rect();
return true;
@ -176,7 +176,7 @@ bool luavalue_cast(int index, Point& point)
point.y = g_lua.popInteger();
return true;
} else if(g_lua.isString()) {
return Fw::cast(g_lua.toString(index), point);
return stdext::cast(g_lua.toString(index), point);
} else if(g_lua.isNil()) {
point = Point();
return true;
@ -203,7 +203,7 @@ bool luavalue_cast(int index, Size& size)
size.setHeight(g_lua.popInteger());
return true;
} else if(g_lua.isString()) {
return Fw::cast(g_lua.toString(index), size);
return stdext::cast(g_lua.toString(index), size);
} else if(g_lua.isNil()) {
size = Size();
return true;
@ -283,7 +283,7 @@ bool luavalue_cast(int index, OTMLNodePtr& node)
} else {
std::string value;
if(g_lua.isBoolean())
value = Fw::unsafeCast<std::string>(g_lua.toBoolean());
value = stdext::unsafe_cast<std::string>(g_lua.toBoolean());
else
value = g_lua.toString();
if(cnodeName.empty())

View File

@ -54,14 +54,14 @@ void Connection::terminate()
g_ioService.stop();
}
void Connection::connect(const std::string& host, uint16 port, const SimpleCallback& connectCallback)
void Connection::connect(const std::string& host, uint16 port, const std::function<void()>& connectCallback)
{
m_connected = false;
m_connecting = true;
m_error.clear();
m_connectCallback = connectCallback;
asio::ip::tcp::resolver::query query(host, Fw::unsafeCast<std::string>(port));
asio::ip::tcp::resolver::query query(host, stdext::unsafe_cast<std::string>(port));
auto weakSelf = ConnectionWeakPtr(shared_from_this());
m_resolver.async_resolve(query, [=](const boost::system::error_code& error, asio::ip::tcp::resolver::iterator endpointIterator) {

View File

@ -48,7 +48,7 @@ public:
static void poll();
static void terminate();
void connect(const std::string& host, uint16 port, const SimpleCallback& connectCallback);
void connect(const std::string& host, uint16 port, const std::function<void()>& connectCallback);
void close();
void write(uint8* buffer, uint16 size);
@ -68,7 +68,7 @@ protected:
void onTimeout(const boost::system::error_code& error);
void handleError(const boost::system::error_code& error);
SimpleCallback m_connectCallback;
std::function<void()> m_connectCallback;
ErrorCallback m_errorCallback;
RecvCallback m_recvCallback;

View File

@ -54,7 +54,7 @@ uint8 InputMessage::getU8()
uint16 InputMessage::getU16()
{
checkRead(2);
uint16 v = Fw::readLE16(m_buffer + m_readPos);
uint16 v = stdext::readLE16(m_buffer + m_readPos);
m_readPos += 2;
return v;
}
@ -62,7 +62,7 @@ uint16 InputMessage::getU16()
uint32 InputMessage::getU32()
{
checkRead(4);
uint32 v = Fw::readLE32(m_buffer + m_readPos);
uint32 v = stdext::readLE32(m_buffer + m_readPos);
m_readPos += 4;
return v;
}
@ -70,7 +70,7 @@ uint32 InputMessage::getU32()
uint64 InputMessage::getU64()
{
checkRead(8);
uint64 v = Fw::readLE64(m_buffer + m_readPos);
uint64 v = stdext::readLE64(m_buffer + m_readPos);
m_readPos += 8;
return v;
}
@ -104,7 +104,7 @@ void InputMessage::setHeaderSize(uint16 size)
bool InputMessage::readChecksum()
{
uint32_t receivedCheck = getU32();
uint32 checksum = Fw::getAdlerChecksum(m_buffer + m_readPos, getUnreadSize());
uint32 checksum = stdext::generate_adler_checksum(m_buffer + m_readPos, getUnreadSize());
return receivedCheck == checksum;
}

View File

@ -1,12 +1,34 @@
/*
* Copyright (c) 2010-2012 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 NETWORKEXCEPTION_H
#define NETWORKEXCEPTION_H
#include "declarations.h"
class NetworkException : public Exception
class NetworkException : public stdext::exception
{
public:
NetworkException(const std::string& what) : Exception(what) { }
NetworkException(const std::string& what) : stdext::exception(what) { }
};
#endif

View File

@ -46,7 +46,7 @@ void OutputMessage::addU8(uint8 value)
void OutputMessage::addU16(uint16 value)
{
checkWrite(2);
Fw::writeLE16(m_buffer + m_writePos, value);
stdext::writeLE16(m_buffer + m_writePos, value);
m_writePos += 2;
m_messageSize += 2;
}
@ -54,7 +54,7 @@ void OutputMessage::addU16(uint16 value)
void OutputMessage::addU32(uint32 value)
{
checkWrite(4);
Fw::writeLE32(m_buffer + m_writePos, value);
stdext::writeLE32(m_buffer + m_writePos, value);
m_writePos += 4;
m_messageSize += 4;
}
@ -62,7 +62,7 @@ void OutputMessage::addU32(uint32 value)
void OutputMessage::addU64(uint64 value)
{
checkWrite(8);
Fw::writeLE64(m_buffer + m_writePos, value);
stdext::writeLE64(m_buffer + m_writePos, value);
m_writePos += 8;
m_messageSize += 8;
}
@ -96,10 +96,10 @@ void OutputMessage::encryptRSA(int size, const std::string& key)
void OutputMessage::writeChecksum()
{
uint32 checksum = Fw::getAdlerChecksum(m_buffer + m_headerPos, m_messageSize);
uint32 checksum = stdext::generate_adler_checksum(m_buffer + m_headerPos, m_messageSize);
assert(m_headerPos - 4 >= 0);
m_headerPos -= 4;
Fw::writeLE32(m_buffer + m_headerPos, checksum);
stdext::writeLE32(m_buffer + m_headerPos, checksum);
m_messageSize += 4;
}
@ -107,7 +107,7 @@ void OutputMessage::writeMessageSize()
{
assert(m_headerPos - 2 >= 0);
m_headerPos -= 2;
Fw::writeLE16(m_buffer + m_headerPos, m_messageSize);
stdext::writeLE16(m_buffer + m_headerPos, m_messageSize);
m_messageSize += 2;
}

View File

@ -26,7 +26,7 @@
#include "declarations.h"
/// All OTML errors throw this exception
class OTMLException : public Exception
class OTMLException : public stdext::exception
{
public:
OTMLException(const OTMLNodePtr& node, const std::string& error);

View File

@ -77,14 +77,14 @@ OTMLNodePtr OTMLNode::at(const std::string& childTag)
}
}
if(!res)
throw OTMLException(shared_from_this(), Fw::mkstr("child node with tag '", childTag, "' not found"));
throw OTMLException(shared_from_this(), stdext::mkstr("child node with tag '", childTag, "' not found"));
return res;
}
OTMLNodePtr OTMLNode::atIndex(int childIndex)
{
if(childIndex >= size() || childIndex < 0)
throw OTMLException(shared_from_this(), Fw::mkstr("child node with index '", childIndex, "' not found"));
throw OTMLException(shared_from_this(), stdext::mkstr("child node with index '", childIndex, "' not found"));
return m_children[childIndex];
}

View File

@ -107,8 +107,8 @@ protected:
template<typename T>
T OTMLNode::value() {
T ret;
if(!Fw::cast(m_value, ret))
throw OTMLException(shared_from_this(), Fw::mkstr("failed to cast node value to type '", Fw::demangleType<T>(), "'"));
if(!stdext::cast(m_value, ret))
throw OTMLException(shared_from_this(), stdext::mkstr("failed to cast node value to type '", stdext::demangle_type<T>(), "'"));
return ret;
}
@ -141,7 +141,7 @@ T OTMLNode::valueAtIndex(int childIndex, const T& def) {
template<typename T>
void OTMLNode::write(const T& v) {
m_value = Fw::safeCast<std::string>(v);
m_value = stdext::safe_cast<std::string>(v);
}
template<typename T>

View File

@ -181,7 +181,7 @@ void OTMLParser::parseNode(const std::string& data)
node->setUnique(dotsPos != std::string::npos);
node->setTag(tag);
node->setSource(doc->source() + ":" + Fw::unsafeCast<std::string>(nodeLine));
node->setSource(doc->source() + ":" + stdext::unsafe_cast<std::string>(nodeLine));
// ~ is considered the null value
if(value == "~")

View File

@ -85,7 +85,7 @@ public:
bool isFullscreen() { return m_fullscreen; }
bool hasFocus() { return m_focused; }
void setOnClose(const SimpleCallback& onClose) { m_onClose = onClose; }
void setOnClose(const std::function<void()>& onClose) { m_onClose = onClose; }
void setOnResize(const OnResizeCallback& onResize) { m_onResize = onResize; }
void setOnInputEvent(const OnInputEventCallback& onInputEvent) { m_onInputEvent = onInputEvent; }
@ -116,7 +116,7 @@ protected:
Boolean<false> m_fullscreen;
Boolean<false> m_maximized;
SimpleCallback m_onClose;
std::function<void()> m_onClose;
OnResizeCallback m_onResize;
OnInputEventCallback m_onInputEvent;
};

View File

@ -39,13 +39,13 @@ void crashHandler(int signum, siginfo_t* info, void* secret)
logError("Application crashed");
std::stringstream ss;
ss << Fw::formatString("app name: %s\n", g_app->getName().c_str());
ss << Fw::formatString("app version: %s\n", g_app->getVersion().c_str());
ss << Fw::formatString("build compiler: %s\n", BUILD_COMPILER);
ss << Fw::formatString("build date: %s\n", BUILD_DATE);
ss << Fw::formatString("build type: %s\n", BUILD_TYPE);
ss << Fw::formatString("build revision: %s\n", BUILD_REVISION);
ss << Fw::formatString("crash date: %s\n", Fw::dateTimeString().c_str());
ss << stdext::format("app name: %s\n", g_app->getName());
ss << stdext::format("app version: %s\n", g_app->getVersion());
ss << stdext::format("build compiler: %s\n", BUILD_COMPILER);
ss << stdext::format("build date: %s\n", BUILD_DATE);
ss << stdext::format("build type: %s\n", BUILD_TYPE);
ss << stdext::format("build revision: %s\n", BUILD_REVISION);
ss << stdext::format("crash date: %s\n", stdext::date_time_string());
ss.flags(std::ios::hex | std::ios::showbase);
ucontext_t context = *(ucontext_t*)secret;
@ -92,7 +92,7 @@ void crashHandler(int signum, siginfo_t* info, void* secret)
demanglePos++;
int len = std::min(line.find_first_of("+", demanglePos), line.find_first_of(")", demanglePos)) - demanglePos;
std::string funcName = line.substr(demanglePos, len);
line.replace(demanglePos, len, Fw::demangleName(funcName.c_str()));
line.replace(demanglePos, len, stdext::demangle_name(funcName.c_str()));
}
#endif
ss << " " << i-1 << ": " << line << std::endl;

View File

@ -95,9 +95,9 @@ void Stacktrace(LPEXCEPTION_POINTERS e, std::stringstream& ss)
pSym->MaxNameLength = MAX_PATH;
if(SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym))
ss << Fw::formatString(" %d: %s(%s+%#0lx) [0x%08lX]\n", count, modname, pSym->Name, Disp, sf.AddrPC.Offset);
ss << stdext::format(" %d: %s(%s+%#0lx) [0x%08lX]\n", count, modname, pSym->Name, Disp, sf.AddrPC.Offset);
else
ss << Fw::formatString(" %d: %s [0x%08lX]\n", count, modname, sf.AddrPC.Offset);
ss << stdext::format(" %d: %s [0x%08lX]\n", count, modname, sf.AddrPC.Offset);
++count;
}
GlobalFree(pSym);
@ -109,16 +109,16 @@ LONG CALLBACK ExceptionHandler(LPEXCEPTION_POINTERS e)
SymInitialize(GetCurrentProcess(), 0, TRUE);
std::stringstream ss;
ss << "== application crashed\n";
ss << Fw::formatString("app name: %s\n", g_app->getName().c_str());
ss << Fw::formatString("app version: %s\n", g_app->getVersion().c_str());
ss << Fw::formatString("build compiler: %s\n", BUILD_COMPILER);
ss << Fw::formatString("build date: %s\n", BUILD_DATE);
ss << Fw::formatString("build type: %s\n", BUILD_TYPE);
ss << Fw::formatString("build revision: %s\n", BUILD_REVISION);
ss << Fw::formatString("crash date: %s\n", Fw::dateTimeString().c_str());
ss << Fw::formatString("exception: %s (0x%08lx)\n", getExceptionName(e->ExceptionRecord->ExceptionCode), e->ExceptionRecord->ExceptionCode);
ss << Fw::formatString("exception address: 0x%08lx\n", (long unsigned int)e->ExceptionRecord->ExceptionAddress);
ss << Fw::formatString(" backtrace:\n");
ss << stdext::format("app name: %s\n", g_app->getName().c_str());
ss << stdext::format("app version: %s\n", g_app->getVersion().c_str());
ss << stdext::format("build compiler: %s\n", BUILD_COMPILER);
ss << stdext::format("build date: %s\n", BUILD_DATE);
ss << stdext::format("build type: %s\n", BUILD_TYPE);
ss << stdext::format("build revision: %s\n", BUILD_REVISION);
ss << stdext::format("crash date: %s\n", stdext::date_time_string().c_str());
ss << stdext::format("exception: %s (0x%08lx)\n", getExceptionName(e->ExceptionRecord->ExceptionCode), e->ExceptionRecord->ExceptionCode);
ss << stdext::format("exception address: 0x%08lx\n", (long unsigned int)e->ExceptionRecord->ExceptionAddress);
ss << stdext::format(" backtrace:\n");
Stacktrace(e, ss);
ss << "\n";
SymCleanup(GetCurrentProcess());
@ -129,7 +129,7 @@ LONG CALLBACK ExceptionHandler(LPEXCEPTION_POINTERS e)
// write stacktrace to crash_report.txt
char dir[MAX_PATH];
GetCurrentDirectory(sizeof(dir) - 1, dir);
std::string fileName = Fw::formatString("%s\\crash_report.txt", dir);
std::string fileName = stdext::format("%s\\crash_report.txt", dir);
std::ofstream fout(fileName.c_str(), std::ios::out | std::ios::app);
if(fout.is_open() && fout.good()) {
fout << ss.str();
@ -139,7 +139,7 @@ LONG CALLBACK ExceptionHandler(LPEXCEPTION_POINTERS e)
logError("Failed to save crash report!");
// inform the user
std::string msg = Fw::formatString("The application has crashed.\n\n"
std::string msg = stdext::format("The application has crashed.\n\n"
"A crash report has been written to:\n"
"%s", fileName.c_str());
MessageBox(NULL, msg.c_str(), "Application crashed", 0);

View File

@ -708,7 +708,7 @@ void WIN32Window::setMouseCursor(const std::string& file, const Point& hotSpot)
std::vector<uchar> xorMask(numbytes, 0);
for(int i=0;i<numbits;++i) {
uint32 rgba = Fw::readLE32(apng.pdata + i*4);
uint32 rgba = stdext::readLE32(apng.pdata + i*4);
if(rgba == 0xffffffff) { //white
HSB_BIT_SET(xorMask, i);
} else if(rgba == 0x00000000) { //alpha
@ -846,7 +846,7 @@ std::string WIN32Window::getClipboardText()
if(hglb) {
LPTSTR lptstr = (LPTSTR)GlobalLock(hglb);
if(lptstr) {
text = Fw::utf8StringToLatin1((uchar*)lptstr);
text = stdext::utf8StringToLatin1((uchar*)lptstr);
GlobalUnlock(hglb);
}
}

View File

@ -23,7 +23,6 @@
#include "x11window.h"
#include <framework/core/resourcemanager.h>
#include <framework/thirdparty/apngloader.h>
#include <framework/util/utf8.h>
#define LSB_BIT_SET(p, n) (p[(n)/8] |= (1 <<((n)%8)))
@ -878,7 +877,7 @@ void X11Window::setMouseCursor(const std::string& file, const Point& hotSpot)
std::vector<uchar> maskBits(numbytes, 0);
for(int i=0;i<numbits;++i) {
uint32 rgba = Fw::readLE32(apng.pdata + i*4);
uint32 rgba = stdext::readLE32(apng.pdata + i*4);
if(rgba == 0xffffffff) { //white, background
LSB_BIT_SET(maskBits, i);
} else if(rgba == 0xff000000) { //black, foreground
@ -1031,7 +1030,7 @@ std::string X11Window::getClipboardText()
&bytesLeft,
&data);
if(len > 0) {
clipboardText = Fw::utf8StringToLatin1(data);
clipboardText = stdext::utf8StringToLatin1(data);
}
}

121
src/framework/stdext/cast.h Normal file
View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2010-2012 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 STDEXT_CAST_H
#define STDEXT_CAST_H
#include "string.h"
#include "exception.h"
#include "demangle.h"
namespace stdext {
// cast a type to another type
template<typename T, typename R>
bool cast(const T& in, R& out) {
std::stringstream ss;
ss << in;
ss >> out;
return !!ss && ss.eof();
}
// cast a type to string
template<typename T>
bool cast(const T& in, std::string& out) {
std::stringstream ss;
ss << in;
out = ss.str();
return true;
}
// cast string to string
template<>
inline bool cast(const std::string& in, std::string& out) {
out = in;
return true;
}
// special cast from string to boolean
template<>
inline bool cast(const std::string& in, bool& b) {
static std::string validNames[2][4] = {{"true","yes","on","1"}, {"false","no","off","0"}};
bool ret = false;
for(int i=0;i<4;++i) {
if(in == validNames[0][i]) {
b = true;
ret = true;
break;
} else if(in == validNames[1][i]) {
b = false;
ret = true;
break;
}
}
return ret;
}
// special cast from boolean to string
template<>
inline bool cast(const bool& in, std::string& out) {
out = (in ? "true" : "false");
return true;
}
// used by safe_cast
class cast_exception : public exception {
public:
virtual ~cast_exception() throw() { }
template<class T, class R>
void update_what() {
m_what = format("failed to cast value of type '%s' to type '%s'", demangle_type<T>(), demangle_type<R>());
}
virtual const char* what() { return m_what.c_str(); }
private:
std::string m_what;
};
// cast a type to another type, any error throws a cast_exception
template<typename R, typename T>
R safe_cast(const T& t) {
R r;
if(!cast(t, r)) {
cast_exception e;
e.update_what<T,R>();
throw e;
}
return r;
}
// cast a type to another type, cast errors are ignored
template<typename R, typename T>
R unsafe_cast(const T& t, R def = R()) {
try {
return safe_cast<R,T>(t);
} catch(cast_exception& e) {
std::cout << "CAST ERROR: " << e.what() << std::endl;
return def;
}
}
}
#endif

View File

@ -20,8 +20,8 @@
* THE SOFTWARE.
*/
#ifndef __COMPILER_H__
#define __COMPILER_H__
#ifndef STDEXT_COMPILER_H
#define STDEXT_COMPILER_H
#if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#error "sorry, you need gcc 4.6 or greater to compile"

View File

@ -20,39 +20,33 @@
* THE SOFTWARE.
*/
#include "utf8.h"
#ifndef STDEXT_DEMANGLE_H
#define STDEXT_DEMANGLE_H
#include <cxxabi.h>
#include <string>
#include <cstring>
char Fw::utf8CharToLatin1(uchar *utf8, int *read)
{
char c = '?';
uchar opt1 = utf8[0];
*read = 1;
if(opt1 == 0xc3) {
*read = 2;
uchar opt2 = utf8[1];
c = 64 + opt2;
} else if(opt1 == 0xc2) {
*read = 2;
uchar opt2 = utf8[1];
if(opt2 > 0xa1 && opt2 < 0xbb)
c = opt2;
} else if(opt1 < 0xc2) {
c = opt1;
namespace stdext {
/// Demangle names for GNU g++ compiler
inline std::string demangle_name(const char* name) {
size_t len;
int status;
std::string ret;
char* demangled = abi::__cxa_demangle(name, 0, &len, &status);
if(demangled) {
ret = demangled;
free(demangled);
}
return c;
return ret;
}
std::string Fw::utf8StringToLatin1(uchar *utf8) {
std::string out;
int len = strlen((char*)utf8);
for(int i=0; i<len;) {
int read = 0;
uchar *utf8char = &utf8[i];
out += Fw::utf8CharToLatin1(utf8char, &read);
i += read;
}
return out;
/// Returns the name of a type
template<typename T>
std::string demangle_type() {
return demangle_name(typeid(T).name());
}
}
#endif

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2010-2012 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 STDEXT_DUMPER_H
#define STDEXT_DUMPER_H
#include <iostream>
namespace stdext {
namespace dumper {
struct dumper_dummy {
~dumper_dummy() { std::cout << std::endl; }
template<class T>
dumper_dummy& operator<<(const T& v) {
std::cout << v << " ";
return *this;
}
};
struct dumper_util {
dumper_util() { }
template<class T>
dumper_dummy operator<<(const T& v) const {
dumper_dummy d;
d << v;
return d;
}
};
}
const static dumper::dumper_util dump;
}
#endif

View File

@ -20,17 +20,20 @@
* THE SOFTWARE.
*/
#ifndef EXCEPTION_H
#define EXCEPTION_H
#ifndef STDEXT_EXCEPTION_H
#define STDEXT_EXCEPTION_H
#include <exception>
#include <string>
class Exception : public std::exception
namespace stdext {
class exception : public std::exception
{
public:
Exception() { }
Exception(const std::string& what) : m_what(what) { }
virtual ~Exception() throw() { };
exception() { }
exception(const std::string& what) : m_what(what) { }
virtual ~exception() throw() { };
virtual const char* what() const throw() { return m_what.c_str(); }
@ -38,4 +41,12 @@ protected:
std::string m_what;
};
/// Throws a generic exception
template<typename... T>
void throw_exception(const std::string& what) {
throw exception(what);
}
}
#endif

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2010-2012 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 STDEXT_MATH_H
#define STDEXT_MATH_H
#include "types.h"
#include <random>
namespace stdext {
inline uint32 generate_adler_checksum(uint8 *buffer, uint16 size) {
register uint32 a = 1, b = 0, tlen;
while(size > 0) {
tlen = size > 5552 ? 5552 : size;
size -= tlen;
do {
a += *buffer++;
b += a;
} while (--tlen);
a %= 65521;
b %= 65521;
}
return (b << 16) | a;
}
inline bool is_power_of_two(uint32 v) {
return ((v != 0) && !(v & (v - 1)));
}
inline uint32 to_power_of_two(uint32 v) {
if(v == 0)
return 0;
uint32 r = 1;
while(r < v && r != 0xffffffff)
r <<= 1;
return r;
}
inline uint16 readLE16(uchar *addr) { return (uint16)addr[1] << 8 | addr[0]; }
inline uint32 readLE32(uchar *addr) { return (uint32)readLE16(addr + 2) << 16 | readLE16(addr); }
inline uint64 readLE64(uchar *addr) { return (uint64)readLE32(addr + 4) << 32 | readLE32(addr); }
inline void writeLE16(uchar *addr, uint16 value) { addr[1] = value >> 8; addr[0] = (uint8)value; }
inline void writeLE32(uchar *addr, uint32 value) { writeLE16(addr + 2, value >> 16); writeLE16(addr, (uint16)value); }
inline void writeLE64(uchar *addr, uint64 value) { writeLE16(addr + 4, value >> 32); writeLE32(addr, (uint32)value); }
template<typename T>
T random_range(T min, T max);
template<>
inline int random_range<int>(int min, int max) {
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_int_distribution<int> dis(0, 2147483647);
return min + (dis(gen) % (max - min + 1));
}
template<>
inline float random_range<float>(float min, float max) {
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_real_distribution<float> dis(0.0, 1.0);
return min + (max - min)*dis(gen);
}
}
#endif

View File

@ -20,17 +20,16 @@
* THE SOFTWARE.
*/
#ifndef UTF8_H
#define UTF8_H
#ifndef STDEXT_H
#define STDEXT_H
#include "compiler.h"
#include "types.h"
#include <string>
namespace Fw {
char utf8CharToLatin1(uchar *utf8, int *read);
std::string utf8StringToLatin1(uchar *utf8);
};
#include "exception.h"
#include "demangle.h"
#include "cast.h"
#include "math.h"
#include "string.h"
#include "dumper.h"
#endif

View File

@ -0,0 +1,235 @@
/*
* Copyright (c) 2010-2012 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 STDEXT_STRING_H
#define STDEXT_STRING_H
#include <string>
#include <cstring>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <boost/algorithm/string.hpp>
#include "types.h"
#include "cast.h"
#include "exception.h"
namespace stdext {
// casts declaration, definition will be included at the end of the file
template<typename R, typename T> R safe_cast(const T& t);
template<typename R, typename T> R unsafe_cast(const T& t, R def = R());
/// Convert any type to std::string
template<typename T>
std::string to_string(const T& t) { return unsafe_cast<std::string, T>(t); }
/// Convert any type from std::string
template<typename T>
T from_string(const std::string& str, T def = T()) { return unsafe_cast<T, std::string>(str, def); }
/// Cast non-class types like int, char, float, double and pointers
template<typename T>
typename std::enable_if<std::is_integral<T>::value || std::is_pointer<T>::value || std::is_floating_point<T>::value, T>::type sprintf_cast(const T& t) { return t; }
/// Cast any class or struct convertible to std::string
inline const char *sprintf_cast(const std::string& s) { return s.c_str(); }
template<int N>
struct expand_snprintf{
template<typename Tuple, typename... Args>
static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) {
return expand_snprintf<N-1>::call(s, maxlen, format, tuple, sprintf_cast(std::get<N-1>(tuple)), args...);
}
};
template<>
struct expand_snprintf<0> {
template<typename Tuple, typename... Args>
static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) {
return snprintf(s, maxlen, format, args...);
}
};
template<class T>
struct replace_extent { typedef T type; };
template<class T>
struct replace_extent<T[]> { typedef const T* type; };
template<class T, std::size_t N>
struct replace_extent<T[N]> { typedef const T* type;};
/// Improved sprintf that accepts std::string and other types
template<typename... Args>
int snprintf(char *s, size_t maxlen, const char *format, const Args&... args) {
typedef typename std::tuple<typename replace_extent<Args>::type...> Tuple;
enum { N = std::tuple_size<Tuple>::value };
Tuple tuple(args...);
return expand_snprintf<N>::call(s, maxlen, format, tuple);
}
/// Format strings with the sprintf style, accepting std::string and string convertible types for %s
template<typename... Args>
std::string format(const std::string& format, const Args&... args) {
int n, size = 1024;
std::string str;
while(true) {
str.resize(size);
n = snprintf(&str[0], size, format.c_str(), args...);
assert(n != -1);
if(n < size) {
str.resize(n);
return str;
}
size *= 2;
}
}
inline void fill_ostream(std::ostringstream&) { }
/// Fills an ostream by concatenating args
template<class T, class... Args>
void fill_ostream(std::ostringstream& stream, const T& first, const Args&... rest) {
stream << first;
fill_ostream(stream, rest...);
}
/// Makes a std::string by concatenating args
template<class... T>
std::string mkstr(const T&... args) {
std::ostringstream buf;
fill_ostream(buf, args...);
return buf.str();
}
/// Easy of use split
template<typename T = std::string>
std::vector<T> split(const std::string& str, const std::string& separators = " ") {
std::vector<std::string> splitted;
boost::split(splitted, str, boost::is_any_of(std::string(separators)));
std::vector<T> results(splitted.size());
for(uint i=0;i<splitted.size();++i)
results[i] = safe_cast<T>(splitted[i]);
return results;
}
/// Resolve a file path by combining sourcePath with filePath
inline std::string resolve_path(const std::string& filePath, std::string sourcePath) {
if(boost::starts_with(filePath, "/"))
return filePath;
if(!boost::ends_with(sourcePath, "/")) {
std::size_t slashPos = sourcePath.find_last_of("/");
if(slashPos == std::string::npos)
throw_exception(format("invalid source path '%s', for file '%s'", sourcePath, filePath));
sourcePath = sourcePath.substr(0, slashPos + 1);
}
return sourcePath + filePath;
}
/// Get current date and time in a std::string
inline std::string date_time_string() {
char date[32];
std::time_t tnow;
std::time(&tnow);
std::tm *ts = std::localtime(&tnow);
std::strftime(date, 32, "%b %d %Y %H:%M:%S", ts);
return std::string(date);
}
/// Convert decimal to hexadecimal
inline std::string dec_to_hex(unsigned int num) {
std::string str;
std::ostringstream o;
o << std::hex << num;
str = o.str();
return str;
}
/// Convert hexadecimal to decimal
inline unsigned int hex_to_dec(const std::string& str) {
unsigned int num;
std::istringstream i(str);
i >> std::hex >> num;
return num;
}
/// Convert ip to string
inline std::string ip_to_string(uint32 ip) {
char host[16];
sprintf(host, "%d.%d.%d.%d", (uint8)ip, (uint8)(ip >> 8), (uint8)(ip >> 16), (uint8)(ip >> 24));
return std::string(host);
}
/// Convert utf8 characters to latin1
inline char utf8CharToLatin1(uchar *utf8, int *read) {
char c = '?';
uchar opt1 = utf8[0];
*read = 1;
if(opt1 == 0xc3) {
*read = 2;
uchar opt2 = utf8[1];
c = 64 + opt2;
} else if(opt1 == 0xc2) {
*read = 2;
uchar opt2 = utf8[1];
if(opt2 > 0xa1 && opt2 < 0xbb)
c = opt2;
} else if(opt1 < 0xc2) {
c = opt1;
}
return c;
}
/// Convert utf8 strings to latin1
inline std::string utf8StringToLatin1(uchar *utf8) {
std::string out;
int len = strlen((char*)utf8);
for(int i=0; i<len;) {
int read = 0;
uchar *utf8char = &utf8[i];
out += utf8CharToLatin1(utf8char, &read);
i += read;
}
return out;
}
// utility for printing messages into stdout
template<class... T>
void print(const T&... args) {
std::ostringstream buf;
fill_ostream(buf, args...);
std::cout << buf.str();
}
template<class... T>
void println(const T&... args) {
print(args...);
std::cout << std::endl;
}
}
#include "cast.h"
#endif

View File

@ -20,11 +20,10 @@
* THE SOFTWARE.
*/
#ifndef TYPES_H
#define TYPES_H
#ifndef STDEXT_TYPES_H
#define STDEXT_TYPES_H
#include <stdint.h>
#include <functional>
// easy handwriting types
typedef unsigned char uchar;
@ -44,17 +43,4 @@ typedef int8_t int8;
// thus this means that the app may cause unknown behavior after running 24 days without restarting
typedef long ticks_t;
typedef std::function<void()> SimpleCallback;
// boolean with default value initializer
template<bool def>
struct Boolean {
Boolean() : v(def) { }
operator bool &() { return v; }
operator bool const &() const { return v; }
bool& operator=(const bool& o) { v = o; return v; }
private:
bool v;
};
#endif

View File

@ -41,7 +41,7 @@ void UIFrameCounter::drawSelf()
UIWidget::drawSelf();
if(g_clock.ticksElapsed(m_lastFrameTicks) >= 1000) {
m_fpsText = Fw::formatString("FPS: %d", m_frameCount);
m_fpsText = stdext::format("FPS: %d", m_frameCount);
m_lastFrameTicks = g_clock.ticks();
m_frameCount = 0;
}

View File

@ -300,7 +300,7 @@ bool UIManager::importStyle(const std::string& file)
for(const OTMLNodePtr& styleNode : doc->children())
importStyleFromOTML(styleNode);
return true;
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("Failed to import UI styles from '", file, "': ", e.what());
return false;
}
@ -330,7 +330,7 @@ void UIManager::importStyleFromOTML(const OTMLNodePtr& styleNode)
OTMLNodePtr originalStyle = getStyle(base);
if(!originalStyle)
Fw::throwException("base style '", base, "' is not defined");
stdext::throw_exception(stdext::format("base style '%s', is not defined", base));
OTMLNodePtr style = originalStyle->clone();
style->merge(styleNode);
style->setTag(name);
@ -375,13 +375,13 @@ UIWidgetPtr UIManager::loadUI(const std::string& file, const UIWidgetPtr& parent
importStyleFromOTML(node);
else {
if(widget)
Fw::throwException("cannot have multiple main widgets in otui files");
stdext::throw_exception("cannot have multiple main widgets in otui files");
widget = createWidgetFromOTML(node, parent);
}
}
return widget;
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("failed to load UI from '", file, "': ", e.what());
return nullptr;
}
@ -392,7 +392,7 @@ UIWidgetPtr UIManager::createWidgetFromStyle(const std::string& styleName, const
OTMLNodePtr node = OTMLNode::create(styleName);
try {
return createWidgetFromOTML(node, parent);
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("failed to create widget from style '", styleName, "': ", e.what());
return nullptr;
}
@ -402,7 +402,7 @@ UIWidgetPtr UIManager::createWidgetFromOTML(const OTMLNodePtr& widgetNode, const
{
OTMLNodePtr originalStyleNode = getStyle(widgetNode->tag());
if(!originalStyleNode)
Fw::throwException("'", widgetNode->tag(), "' is not a defined style");
stdext::throw_exception(stdext::format("'%s' is not a defined style", widgetNode->tag()));
OTMLNodePtr styleNode = originalStyleNode->clone();
styleNode->merge(widgetNode);
@ -424,7 +424,7 @@ UIWidgetPtr UIManager::createWidgetFromOTML(const OTMLNodePtr& widgetNode, const
}
}
} else
Fw::throwException("unable to create widget of type '", widgetType, "'");
stdext::throw_exception(stdext::format("unable to create widget of type '%s'", widgetType));
return widget;
}

View File

@ -479,7 +479,7 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
for(const OTMLNodePtr& node : styleNode->children()) {
if(node->tag()[0] == '!') {
std::string tag = node->tag().substr(1);
std::string code = Fw::formatString("tostring(%s)", node->value().c_str());
std::string code = stdext::format("tostring(%s)", node->value().c_str());
std::string origin = "@" + node->source() + "[" + node->tag() + "]";
g_lua.evaluateExpression(code, origin);
std::string value = g_lua.popString();
@ -499,7 +499,7 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
focus();
}
m_firstOnStyle = false;
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("Failed to apply style to widget '", m_id, "' style: ", e.what());
}
m_loadingStyle = false;

View File

@ -41,7 +41,7 @@ void UIWidget::initBaseStyle()
// generate an unique id, this is need because anchored layouts find widgets by id
static unsigned long id = 1;
m_id = Fw::mkstr("widget", id++);
m_id = stdext::mkstr("widget", id++);
}
void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
@ -81,9 +81,9 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
else if(node->tag() == "background-rect")
setBackgroundRect(node->value<Rect>());
else if(node->tag() == "icon")
setIcon(Fw::resolvePath(node->value(), node->source()));
setIcon(stdext::resolve_path(node->value(), node->source()));
else if(node->tag() == "icon-source")
setIcon(Fw::resolvePath(node->value(), node->source()));
setIcon(stdext::resolve_path(node->value(), node->source()));
else if(node->tag() == "icon-color")
setIconColor(node->value<Color>());
else if(node->tag() == "icon-offset-x")
@ -123,10 +123,10 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
else if(node->tag() == "clipping")
setClipping(node->value<bool>());
else if(node->tag() == "border") {
auto split = Fw::split(node->value(), " ");
auto split = stdext::split(node->value(), " ");
if(split.size() == 2) {
setBorderWidth(Fw::safeCast<int>(split[0]));
setBorderColor(Fw::safeCast<Color>(split[1]));
setBorderWidth(stdext::safe_cast<int>(split[0]));
setBorderColor(stdext::safe_cast<Color>(split[1]));
} else
throw OTMLException(node, "border param must have its width followed by its color");
}
@ -163,27 +163,27 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
std::vector<std::string> split;
boost::split(split, marginDesc, boost::is_any_of(std::string(" ")));
if(split.size() == 4) {
setMarginTop(Fw::safeCast<int>(split[0]));
setMarginRight(Fw::safeCast<int>(split[1]));
setMarginBottom(Fw::safeCast<int>(split[2]));
setMarginLeft(Fw::safeCast<int>(split[3]));
setMarginTop(stdext::safe_cast<int>(split[0]));
setMarginRight(stdext::safe_cast<int>(split[1]));
setMarginBottom(stdext::safe_cast<int>(split[2]));
setMarginLeft(stdext::safe_cast<int>(split[3]));
} else if(split.size() == 3) {
int marginTop = Fw::safeCast<int>(split[0]);
int marginHorizontal = Fw::safeCast<int>(split[1]);
int marginBottom = Fw::safeCast<int>(split[2]);
int marginTop = stdext::safe_cast<int>(split[0]);
int marginHorizontal = stdext::safe_cast<int>(split[1]);
int marginBottom = stdext::safe_cast<int>(split[2]);
setMarginTop(marginTop);
setMarginRight(marginHorizontal);
setMarginBottom(marginBottom);
setMarginLeft(marginHorizontal);
} else if(split.size() == 2) {
int marginVertical = Fw::safeCast<int>(split[0]);
int marginHorizontal = Fw::safeCast<int>(split[1]);
int marginVertical = stdext::safe_cast<int>(split[0]);
int marginHorizontal = stdext::safe_cast<int>(split[1]);
setMarginTop(marginVertical);
setMarginRight(marginHorizontal);
setMarginBottom(marginVertical);
setMarginLeft(marginHorizontal);
} else if(split.size() == 1) {
int margin = Fw::safeCast<int>(split[0]);
int margin = stdext::safe_cast<int>(split[0]);
setMarginTop(margin);
setMarginRight(margin);
setMarginBottom(margin);
@ -203,27 +203,27 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
std::vector<std::string> split;
boost::split(split, paddingDesc, boost::is_any_of(std::string(" ")));
if(split.size() == 4) {
setPaddingTop(Fw::safeCast<int>(split[0]));
setPaddingRight(Fw::safeCast<int>(split[1]));
setPaddingBottom(Fw::safeCast<int>(split[2]));
setPaddingLeft(Fw::safeCast<int>(split[3]));
setPaddingTop(stdext::safe_cast<int>(split[0]));
setPaddingRight(stdext::safe_cast<int>(split[1]));
setPaddingBottom(stdext::safe_cast<int>(split[2]));
setPaddingLeft(stdext::safe_cast<int>(split[3]));
} else if(split.size() == 3) {
int paddingTop = Fw::safeCast<int>(split[0]);
int paddingHorizontal = Fw::safeCast<int>(split[1]);
int paddingBottom = Fw::safeCast<int>(split[2]);
int paddingTop = stdext::safe_cast<int>(split[0]);
int paddingHorizontal = stdext::safe_cast<int>(split[1]);
int paddingBottom = stdext::safe_cast<int>(split[2]);
setPaddingTop(paddingTop);
setPaddingRight(paddingHorizontal);
setPaddingBottom(paddingBottom);
setPaddingLeft(paddingHorizontal);
} else if(split.size() == 2) {
int paddingVertical = Fw::safeCast<int>(split[0]);
int paddingHorizontal = Fw::safeCast<int>(split[1]);
int paddingVertical = stdext::safe_cast<int>(split[0]);
int paddingHorizontal = stdext::safe_cast<int>(split[1]);
setPaddingTop(paddingVertical);
setPaddingRight(paddingHorizontal);
setPaddingBottom(paddingVertical);
setPaddingLeft(paddingHorizontal);
} else if(split.size() == 1) {
int padding = Fw::safeCast<int>(split[0]);
int padding = stdext::safe_cast<int>(split[0]);
setPaddingTop(padding);
setPaddingRight(padding);
setPaddingBottom(padding);
@ -281,7 +281,7 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
if(node->value() == "none") {
removeAnchor(anchoredEdge);
} else {
std::vector<std::string> split = Fw::split(node->value(), ".");
std::vector<std::string> split = stdext::split(node->value(), ".");
if(split.size() != 2)
throw OTMLException(node, "invalid anchor description");

View File

@ -35,7 +35,7 @@ void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode)
{
for(const OTMLNodePtr& node : styleNode->children()) {
if(node->tag() == "image-source")
setImageSource(Fw::resolvePath(node->value(), node->source()));
setImageSource(stdext::resolve_path(node->value(), node->source()));
else if(node->tag() == "image-offset-x")
setImageOffsetX(node->value<int>());
else if(node->tag() == "image-offset-y")

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2010-2012 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 BOOLEAN_H
#define BOOLEAN_H
/// Boolean with default value
template<bool def>
struct Boolean {
Boolean() : v(def) { }
operator bool &() { return v; }
operator bool const &() const { return v; }
bool& operator=(const bool& o) { v = o; return v; }
private:
bool v;
};
#endif

View File

@ -23,8 +23,8 @@
#ifndef COLOR_H
#define COLOR_H
#include "../util/types.h"
#include "../util/tools.h"
#include "../stdext/types.h"
#include "../stdext/cast.h"
#include "../const.h"
class Color
@ -126,11 +126,11 @@ inline std::istream& operator>>(std::istream& in, Color& color)
in >> tmp;
if(tmp.length() == 6 || tmp.length() == 8) {
color.setRed((uint8)Fw::hex2dec(tmp.substr(0, 2)));
color.setGreen((uint8)Fw::hex2dec(tmp.substr(2, 2)));
color.setBlue((uint8)Fw::hex2dec(tmp.substr(4, 2)));
color.setRed((uint8)stdext::hex_to_dec(tmp.substr(0, 2)));
color.setGreen((uint8)stdext::hex_to_dec(tmp.substr(2, 2)));
color.setBlue((uint8)stdext::hex_to_dec(tmp.substr(4, 2)));
if(tmp.length() == 8)
color.setAlpha((uint8)Fw::hex2dec(tmp.substr(6, 2)));
color.setAlpha((uint8)stdext::hex_to_dec(tmp.substr(6, 2)));
else
color.setAlpha(255);
} else

View File

@ -23,7 +23,7 @@
#ifndef POINT_H
#define POINT_H
#include "../util/types.h"
#include "../stdext/types.h"
#include <sstream>
#include <cmath>

View File

@ -23,7 +23,7 @@
#ifndef RECT_H
#define RECT_H
#include "../util/types.h"
#include "../stdext/types.h"
#include <sstream>
template<class T>

View File

@ -1,350 +0,0 @@
/*
* Copyright (c) 2010-2012 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 TOOLS_H
#define TOOLS_H
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <exception>
#include <cxxabi.h>
#include <vector>
#include <boost/algorithm/string.hpp>
#include "types.h"
#include "exception.h"
namespace Fw {
// read utilities for istream
inline uint8 getU8(std::istream& in) {
uint8 tmp;
in.read((char*)&tmp, 1);
return tmp;
}
inline uint16 getU16(std::istream& in) {
uint16 tmp;
in.read((char*)&tmp, 2);
return tmp;
}
inline uint32 getU32(std::istream& in) {
uint32 tmp;
in.read((char*)&tmp, 4);
return tmp;
}
inline uint16 readLE16(uchar *addr) { return (uint16)addr[1] << 8 | addr[0]; }
inline uint32 readLE32(uchar *addr) { return (uint32)readLE16(addr + 2) << 16 | readLE16(addr); }
inline uint64 readLE64(uchar *addr) { return (uint64)readLE32(addr + 4) << 32 | readLE32(addr); }
inline void writeLE16(uchar *addr, uint16 value) { addr[1] = value >> 8; addr[0] = (uint8)value; }
inline void writeLE32(uchar *addr, uint32 value) { writeLE16(addr + 2, value >> 16); writeLE16(addr, (uint16)value); }
inline void writeLE64(uchar *addr, uint64 value) { writeLE16(addr + 4, value >> 32); writeLE32(addr, (uint32)value); }
// fills an ostream by concatenating args
inline void fillOstream(std::ostringstream&) { }
template<class T, class... Args>
void fillOstream(std::ostringstream& stream, const T& first, const Args&... rest) {
stream << first;
fillOstream(stream, rest...);
}
// makes a std::string by concatenating args
template<class... T>
std::string mkstr(const T&... args) {
std::ostringstream buf;
fillOstream(buf, args...);
return buf.str();
}
// throw a generic expcetion
template<typename... T>
void throwException(const T&... args) {
throw Exception(mkstr(args...));
}
// used by dumper
struct dump_util {
~dump_util() { std::cout << std::endl; }
template<class T>
dump_util& operator<<(const T& v) {
std::cout << v << " ";
return *this;
}
};
// utility for dumping variables
struct dumper {
dumper() { }
template<class T>
dump_util operator<<(const T& v) const {
dump_util d;
d << v;
return d;
}
};
// utility for printing messages into stdout
template<class... T>
void print(const T&... args) {
std::ostringstream buf;
fillOstream(buf, args...);
std::cout << buf.str();
}
template<class... T>
void println(const T&... args) {
print(args...);
std::cout << std::endl;
}
// useful std::string version of sprintf :)
template<typename... Args>
std::string formatString(const std::string& format, Args... args) {
int n, size = 1024;
std::string str;
while(true) {
str.resize(size);
n = snprintf(&str[0], size, format.c_str(), args...);
assert(n != -1);
if(n < size) {
str.resize(n);
return str;
}
size *= 2;
}
}
// demangle names for GNU g++ compiler
inline std::string demangleName(const char* name) {
size_t len;
int status;
std::string ret;
char* demangled = abi::__cxa_demangle(name, 0, &len, &status);
if(demangled) {
ret = demangled;
free(demangled);
}
return ret;
}
// returns the name of a type
template<typename T>
std::string demangleType() {
return demangleName(typeid(T).name());
}
// cast a type to another type
template<typename T, typename R>
bool cast(const T& in, R& out) {
std::stringstream ss;
ss << in;
ss >> out;
return !!ss && ss.eof();
}
// cast a type to string
template<typename T>
bool cast(const T& in, std::string& out) {
std::stringstream ss;
ss << in;
out = ss.str();
return true;
}
// cast string to string
template<>
inline bool cast(const std::string& in, std::string& out) {
out = in;
return true;
}
// special cast from string to boolean
template<>
inline bool cast(const std::string& in, bool& b) {
static std::string validNames[2][4] = {{"true","yes","on","1"}, {"false","no","off","0"}};
bool ret = false;
for(int i=0;i<4;++i) {
if(in == validNames[0][i]) {
b = true;
ret = true;
break;
} else if(in == validNames[1][i]) {
b = false;
ret = true;
break;
}
}
return ret;
}
// special cast from boolean to string
template<>
inline bool cast(const bool& in, std::string& out) {
out = (in ? "true" : "false");
return true;
}
// used by safe_cast
class cast_exception : public Exception {
public:
virtual ~cast_exception() throw() { }
template<class T, class R>
void setWhat() {
m_what = mkstr("failed to cast value of type '", demangleType<T>(),
"' to type '", demangleType<R>(), "'");
}
virtual const char* what() { return m_what.c_str(); }
private:
std::string m_what;
};
// cast a type to another type, any error throws a cast_exception
template<typename R, typename T>
R safeCast(const T& t) {
R r;
if(!cast(t, r)) {
cast_exception e;
e.setWhat<T,R>();
throw e;
}
return r;
}
// cast a type to another type, cast errors are ignored
template<typename R, typename T>
R unsafeCast(const T& t, R def = R()) {
try {
return safeCast<R,T>(t);
} catch(cast_exception& e) {
println("CAST ERROR: ", e.what());
return def;
}
}
template<typename T>
std::string tostring(const T& t) {
return unsafeCast<std::string, T>(t);
}
template<typename T>
T fromstring(const std::string& str, T def = T()) {
return unsafeCast<T, std::string>(str, def);
}
inline std::string dec2hex(unsigned int num) {
std::string str;
std::ostringstream o;
o << std::hex << num;
str = o.str();
return str;
}
inline unsigned int hex2dec(const std::string& str) {
unsigned int num;
std::istringstream i(str);
i >> std::hex >> num;
return num;
}
inline std::string ip2str(uint32 ip) {
char host[16];
sprintf(host, "%d.%d.%d.%d", (uint8)ip, (uint8)(ip >> 8), (uint8)(ip >> 16), (uint8)(ip >> 24));
return std::string(host);
}
template<typename T = std::string>
std::vector<T> split(const std::string& str, const std::string& separators = " ") {
std::vector<std::string> splitted;
boost::split(splitted, str, boost::is_any_of(std::string(separators)));
std::vector<T> results(splitted.size());
for(uint i=0;i<splitted.size();++i)
results[i] = safeCast<T>(splitted[i]);
return results;
}
inline std::string resolvePath(const std::string& file, std::string sourcePath) {
if(boost::starts_with(file, "/"))
return file;
if(!boost::ends_with(sourcePath, "/")) {
std::size_t slashPos = sourcePath.find_last_of("/");
if(slashPos == std::string::npos)
throwException("invalid source path '", sourcePath, "' for file '", file, "'");
sourcePath = sourcePath.substr(0, slashPos + 1);
}
return sourcePath + file;
}
inline std::string dateTimeString() {
char date[32];
std::time_t tnow;
std::time(&tnow);
std::tm *ts = std::localtime(&tnow);
std::strftime(date, 32, "%b %d %Y %H:%M:%S", ts);
return std::string(date);
}
template<typename T>
T randomRange(T min, T max);
template<>
inline int randomRange<int>(int min, int max) {
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_int_distribution<int> dis(0, 2147483647);
return min + (dis(gen) % (max - min + 1));
}
template<>
inline float randomRange<float>(float min, float max) {
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_real_distribution<float> dis(0.0, 1.0);
return min + (max - min)*dis(gen);
}
inline uint32 getAdlerChecksum(uint8* buffer, uint16 size) {
register uint32 a = 1, b = 0, tlen;
while(size > 0) {
tlen = size > 5552 ? 5552 : size;
size -= tlen;
do {
a += *buffer++;
b += a;
} while (--tlen);
a %= 65521;
b %= 65521;
}
return (b << 16) | a;
}
}
// shortcut for Fw::dump
const static Fw::dumper dump;
#endif

View File

@ -23,8 +23,6 @@
#ifndef OTCLIENT_CONST_H
#define OTCLIENT_CONST_H
#include <framework/math/color.h>
namespace Otc
{
constexpr const char* AppName = "OTClient";

View File

@ -23,7 +23,7 @@
#ifndef OUTFIT_H
#define OUTFIT_H
#include <framework/math/color.h>
#include <framework/util/color.h>
#include <otclient/core/thingstype.h>
class Outfit

View File

@ -47,7 +47,7 @@ bool SpriteManager::load(const std::string& file)
m_spritesCount = m_spritesFile->getU16();
m_loaded = true;
return true;
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("Failed to load sprites from '", file, "': ", e.what());
return false;
}

View File

@ -307,12 +307,12 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
parseExtendedOpcode(msg);
break;
default:
Fw::throwException("unknown opcode");
stdext::throw_exception("unknown opcode");
break;
}
prevOpcode = opcode;
}
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("Network exception (", msg->getUnreadSize(), " bytes unread, last opcode is ", opcode, ", prev opcode is ", prevOpcode, "): ", e.what());
}
}
@ -954,7 +954,7 @@ void ProtocolGame::parseCreatureSpeak(const InputMessagePtr& msg)
//case Proto::ServerSpeakChannelManagement:
//case Proto::ServerSpeakSpell:
default:
Fw::throwException("unknown speak type ", speakType);
stdext::throw_exception(stdext::format("unknown speak type %d", speakType));
break;
}
@ -1218,7 +1218,7 @@ void ProtocolGame::parseExtendedOpcode(const InputMessagePtr& msg)
else {
try {
callLuaField("onExtendedOpcode", opcode, buffer);
} catch(Exception& e) {
} catch(stdext::exception& e) {
logError("Network exception in extended opcode ", opcode, ": ", e.what());
}
}
@ -1340,7 +1340,7 @@ ThingPtr ProtocolGame::getThing(const InputMessagePtr& msg)
int id = msg->getU16();
if(id == 0)
Fw::throwException("invalid thing id");
stdext::throw_exception("invalid thing id");
else if(id == Proto::UnknownCreature || id == Proto::OutdatedCreature || id == Proto::Creature)
thing = getCreature(msg, id);
else // item
@ -1457,7 +1457,7 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
else
logTraceError("invalid creature");
} else {
Fw::throwException("invalid creature opcode");
stdext::throw_exception("invalid creature opcode");
}
return creature;
@ -1470,7 +1470,7 @@ ItemPtr ProtocolGame::getItem(const InputMessagePtr& msg, int id)
ItemPtr item = Item::create(id);
if(item->getId() == 0)
Fw::throwException("unable to create item with invalid id");
stdext::throw_exception("unable to create item with invalid id");
if(item->isStackable() || item->isFluidContainer() || item->isFluid())
item->setCountOrSubType(msg->getU8());

View File

@ -39,6 +39,8 @@ void ProtocolGame::sendExtendedOpcode(uint8 opcode, const std::string& buffer)
msg->addU8(opcode);
msg->addString(buffer);
safeSend(msg);
} else {
logError("unable to send extended opcode ", (int)opcode, ", extended opcodes are not enabled");
}
}
@ -77,7 +79,7 @@ void ProtocolGame::sendLoginPacket(uint challangeTimestamp, uint8 challangeRando
msg->addU8(challangeRandom);
paddingBytes -= 5;
#else // PROTOCOL>=810
msg->addU32(Fw::fromstring<uint32>(m_accountName));
msg->addU32(stdext::from_string<uint32>(m_accountName));
msg->addString(m_characterName);
msg->addString(m_accountPassword);

View File

@ -64,11 +64,11 @@ void ProtocolLogin::onRecv(const InputMessagePtr& msg)
parseCharacterList(msg);
break;
default:
Fw::throwException("unknown opt byte ", opcode);
stdext::throw_exception(stdext::format("unknown opcode %d", opcode));
break;
}
}
} catch(Exception& e) {
} catch(stdext::exception& e) {
logTraceError(e.what());
}
disconnect();
@ -112,7 +112,7 @@ void ProtocolLogin::sendLoginPacket()
msg->addString(m_accountPassword);
paddingBytes -= 4 + m_accountName.length() + m_accountPassword.length();
#elif PROTOCOL>=810
msg->addU32(Fw::fromstring<uint32>(m_accountName));
msg->addU32(stdext::from_string<uint32>(m_accountName));
msg->addString(m_accountPassword);
paddingBytes -= 6 + m_accountPassword.length();
#endif
@ -149,7 +149,7 @@ void ProtocolLogin::parseCharacterList(const InputMessagePtr& msg)
std::string world = msg->getString();
uint32 ip = msg->getU32();
uint16 port = msg->getU16();
charList.push_back(CharacterInfo(name, world, Fw::ip2str(ip), port));
charList.push_back(CharacterInfo(name, world, stdext::ip_to_string(ip), port));
}
int premDays = msg->getU16();

View File

@ -44,41 +44,45 @@ void OTClient::init(const std::vector<std::string>& args)
continue;
if(arg == "-version" || arg == "--version" || arg == "-v") {
Fw::print(Otc::AppName, " ", Otc::AppVersion, "\n"
"Buitt on: ", BUILD_DATE, "\n",
"Revision: ", BUILD_REVISION, "\n",
"Compiled by: ", BUILD_COMPILER, "\n",
"Build type: ", BUILD_TYPE, "\n");
stdext::print(
Otc::AppName, " ", Otc::AppVersion, "\n"
"Buitt on: ", BUILD_DATE, "\n",
"Revision: ", BUILD_REVISION, "\n",
"Compiled by: ", BUILD_COMPILER, "\n",
"Build type: ", BUILD_TYPE, "\n");
return;
} else if(arg == "-help" || arg == "--help" || arg == "-h") {
Fw::print("Usage: ", args[0], " [options]\n"
"Options:\n"
" -help Display this information and exit\n"
" -version Display version and exit\n"
"\n"
" -no-fbos Disable usage of opengl framebuffer objects\n"
" -no-mipmapping Disable texture mipmaping\n"
" -no-smoothing Disable texture smoothing (bilinear filter)\n"
" -no-hardware-buffering Disable buffering vertex arrays in hardware\n"
" -realtime-mipmapping Improve framebuffer smoothing quality by\n"
" generating mipmaps in realtime when hardware\n"
" mipmap generation implementation is available\n");
stdext::print(
"Usage: ", args[0], " [options]\n"
"Options:\n"
" -help Display this information and exit\n"
" -version Display version and exit\n"
"\n"
" -no-fbos Disable usage of opengl framebuffer objects\n"
" -no-mipmapping Disable texture mipmaping\n"
" -no-smoothing Disable texture smoothing (bilinear filter)\n"
" -no-hardware-buffering Disable buffering vertex arrays in hardware\n"
" -realtime-mipmapping Improve framebuffer smoothing quality by\n"
" generating mipmaps in realtime when hardware\n"
" mipmap generation implementation is available\n");
return;
} else {
Fw::println("Unrecognized option '", arg, "', please see -help for available options list");
stdext::println("Unrecognized option '", arg, "', please see -help for available options list");
return;
}
}
logInfo(Fw::formatString("%s %s (rev %s) built on %s",
Otc::AppName,
Otc::AppVersion,
BUILD_REVISION,
BUILD_DATE));
logInfo(stdext::format(
"%s %s (rev %s) built on %s",
Otc::AppName,
Otc::AppVersion,
BUILD_REVISION,
BUILD_DATE));
if(startupOptions.length() > 0)
logInfo("Startup options:", startupOptions);
g_logger.setLogFile(Fw::formatString("%s.txt", Otc::AppCompactName));
g_logger.setLogFile(stdext::format("%s.txt", Otc::AppCompactName));
Application::init(args);
g_modules.discoverModules();

View File

@ -49,12 +49,12 @@ void UIItem::drawSelf()
m_item->draw(dest, scaleFactor, true);
if(m_font && m_item->isStackable() && m_item->getCount() > 1) {
std::string count = Fw::tostring(m_item->getCount());
std::string count = stdext::to_string(m_item->getCount());
g_painter->setColor(Color(231, 231, 231));
m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight);
}
// debug, show item id
//m_font->drawText(Fw::tostring(m_item->getId()), m_rect, Fw::AlignBottomRight);
//m_font->drawText(stdext::to_string(m_item->getId()), m_rect, Fw::AlignBottomRight);
}
}

View File

@ -24,8 +24,8 @@
#define POSITION_H
#include <otclient/const.h>
#include <framework/util/types.h>
#include <framework/math/point.h>
#include <framework/stdext/types.h>
#include <framework/util/point.h>
class Position
{