Huge engine change, replace all std::shared_ptrs

Create a new shared pointer type stdext::shared_object_ptr and stdext::shared_obj
using boost::intrusive_ptr

Advantages:
 * half memory usage
 * faster and lightweight

Disadvantages:
 * using weak_ptr is not supported anymore
 * compiling seems slower
master
Eduardo Bart 12 years ago
parent 3ca6494343
commit e0431021b5

@ -113,13 +113,13 @@ function doCreatureFitFilters(creature)
local hideSkulls = hideSkullsButton:isChecked() local hideSkulls = hideSkullsButton:isChecked()
local hideParty = hidePartyButton:isChecked() local hideParty = hidePartyButton:isChecked()
if hidePlayers and creature:asPlayer() then if hidePlayers and creature:isPlayer() then
return false return false
elseif hideNPCs and creature:asNpc() then elseif hideNPCs and creature:isNpc() then
return false return false
elseif hideMonsters and creature:asMonster() then elseif hideMonsters and creature:isMonster() then
return false return false
elseif hideSkulls and creature:asPlayer() and creature:getSkull() == SkullNone then elseif hideSkulls and creature:isPlayer() and creature:getSkull() == SkullNone then
return false return false
elseif hideParty and creature:getShield() > ShieldWhiteBlue then elseif hideParty and creature:getShield() > ShieldWhiteBlue then
return false return false

@ -150,7 +150,7 @@ function onChooseItemMouseRelease(self, mousePosition, mouseButton)
if tile then if tile then
local thing = tile:getTopMoveThing() local thing = tile:getTopMoveThing()
if thing then if thing then
item = thing:asItem() item = thing:isItem()
end end
end end
elseif clickedWidget:getClassName() == 'UIItem' and not clickedWidget:isVirtual() then elseif clickedWidget:getClassName() == 'UIItem' and not clickedWidget:isVirtual() then

@ -267,7 +267,7 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
end end
if lookThing and not lookThing:asCreature() and not lookThing:isNotMoveable() and lookThing:isPickupable() then if lookThing and not lookThing:isCreature() and not lookThing:isNotMoveable() and lookThing:isPickupable() then
menu:addSeparator() menu:addSeparator()
menu:addOption(tr('Trade with ...'), function() startTradeWith(lookThing) end) menu:addOption(tr('Trade with ...'), function() startTradeWith(lookThing) end)
end end
@ -282,7 +282,7 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
if creatureThing then if creatureThing then
menu:addSeparator() menu:addSeparator()
if creatureThing:asLocalPlayer() then if creatureThing:isLocalPlayer() then
menu:addOption(tr('Set Outfit'), function() g_game.requestOutfit() end) menu:addOption(tr('Set Outfit'), function() g_game.requestOutfit() end)
if creatureThing:isPartyMember() --[[and not fighting]] then if creatureThing:isPartyMember() --[[and not fighting]] then
@ -310,7 +310,7 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
menu:addOption(tr('Stop Follow'), function() g_game.cancelFollow() end) menu:addOption(tr('Stop Follow'), function() g_game.cancelFollow() end)
end end
if creatureThing:asPlayer() then if creatureThing:isPlayer() then
menu:addSeparator() menu:addSeparator()
local creatureName = creatureThing:getName() local creatureName = creatureThing:getName()
menu:addOption(tr('Message to %s', creatureName), function() g_game.openPrivateChannel(creatureName) end) menu:addOption(tr('Message to %s', creatureName), function() g_game.openPrivateChannel(creatureName) end)
@ -322,7 +322,7 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
menu:addOption(tr('Add to VIP list'), function() g_game.addVip(creatureName) end) menu:addOption(tr('Add to VIP list'), function() g_game.addVip(creatureName) end)
end end
local localPlayerShield = localPlayer:asCreature():getShield() local localPlayerShield = localPlayer:isCreature():getShield()
local creatureShield = creatureThing:getShield() local creatureShield = creatureThing:getShield()
if localPlayerShield == ShieldNone or localPlayerShield == ShieldWhiteBlue then if localPlayerShield == ShieldNone or localPlayerShield == ShieldWhiteBlue then
@ -394,8 +394,8 @@ function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, u
else else
if multiUseThing and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseRightButton and not g_mouse.isPressed(MouseLeftButton) then if multiUseThing and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseRightButton and not g_mouse.isPressed(MouseLeftButton) then
local player = g_game.getLocalPlayer() local player = g_game.getLocalPlayer()
if multiUseThing:asCreature() and multiUseThing:asCreature() ~= player then if multiUseThing:isCreature() and multiUseThing:isCreature() ~= player then
g_game.attack(multiUseThing:asCreature()) g_game.attack(multiUseThing:isCreature())
return true return true
elseif multiUseThing:isContainer() then elseif multiUseThing:isContainer() then
if multiUseThing:getParentContainer() then if multiUseThing:getParentContainer() then

@ -38,7 +38,7 @@ function UIGameMap:onDrop(widget, mousePos)
local thingPos = thing:getPosition() local thingPos = thing:getPosition()
if thingPos.x == toPos.x and thingPos.y == toPos.y and thingPos.z == toPos.z then return false end if thingPos.x == toPos.x and thingPos.y == toPos.y and thingPos.z == toPos.z then return false end
if thing:asItem() and thing:getCount() > 1 then if thing:isItem() and thing:getCount() > 1 then
modules.game_interface.moveStackableItem(thing, toPos) modules.game_interface.moveStackableItem(thing, toPos)
else else
g_game.move(thing, toPos, 1) g_game.move(thing, toPos, 1)

@ -33,7 +33,7 @@ enum {
BINARYTREE_NODE_END = 0xFF BINARYTREE_NODE_END = 0xFF
}; };
class BinaryTree class BinaryTree : public stdext::shared_object
{ {
public: public:
BinaryTree(const FileStreamPtr& fin); BinaryTree(const FileStreamPtr& fin);

@ -33,13 +33,11 @@ class ScheduledEvent;
class FileStream; class FileStream;
class BinaryTree; class BinaryTree;
typedef std::shared_ptr<Module> ModulePtr; typedef stdext::shared_object_ptr<Module> ModulePtr;
typedef std::shared_ptr<Event> EventPtr; typedef stdext::shared_object_ptr<Event> EventPtr;
typedef std::shared_ptr<ScheduledEvent> ScheduledEventPtr; typedef stdext::shared_object_ptr<ScheduledEvent> ScheduledEventPtr;
typedef std::shared_ptr<FileStream> FileStreamPtr; typedef stdext::shared_object_ptr<FileStream> FileStreamPtr;
typedef std::shared_ptr<BinaryTree> BinaryTreePtr; typedef stdext::shared_object_ptr<BinaryTree> BinaryTreePtr;
typedef std::weak_ptr<BinaryTree> BinaryTreeWeakPtr;
typedef std::vector<BinaryTreePtr> BinaryTreeVec; typedef std::vector<BinaryTreePtr> BinaryTreeVec;

@ -61,7 +61,7 @@ public:
void addString(const std::string& v); void addString(const std::string& v);
BinaryTreePtr makeTree(); BinaryTreePtr makeTree();
FileStreamPtr asFileStream() { return std::static_pointer_cast<FileStream>(shared_from_this()); } FileStreamPtr asFileStream() { return self_cast<FileStream>(); }
private: private:
void checkWrite(); void checkWrite();

@ -56,7 +56,7 @@ public:
int getAutoLoadPriority() { return m_autoLoadPriority; } int getAutoLoadPriority() { return m_autoLoadPriority; }
// @dontbind // @dontbind
ModulePtr asModule() { return std::static_pointer_cast<Module>(shared_from_this()); } ModulePtr asModule() { return self_cast<Module>(); }
protected: protected:
void discover(const OTMLNodePtr& moduleNode); void discover(const OTMLNodePtr& moduleNode);

@ -46,7 +46,7 @@ void ModuleManager::discoverModules()
if(boost::ends_with(moduleFile, ".otmod")) { if(boost::ends_with(moduleFile, ".otmod")) {
ModulePtr module = discoverModule("/" + moduleDir + "/" + moduleFile); ModulePtr module = discoverModule("/" + moduleDir + "/" + moduleFile);
if(module && module->isAutoLoad()) if(module && module->isAutoLoad())
m_autoLoadModules.insert(make_pair(module->getAutoLoadPriority(), module)); m_autoLoadModules.insert(std::make_pair(module->getAutoLoadPriority(), module));
} }
} }
} }

@ -70,7 +70,7 @@ void AnimatedTexture::processAnimation()
AnimatedTexturePtr self = asAnimatedTexture(); AnimatedTexturePtr self = asAnimatedTexture();
// continue to animate only if something still referencing this texture // continue to animate only if something still referencing this texture
if(self.use_count() > 1) if(self->ref_count() > 1)
g_dispatcher.scheduleEvent(std::bind(&AnimatedTexture::processAnimation, self), m_framesDelay[m_currentFrame]); g_dispatcher.scheduleEvent(std::bind(&AnimatedTexture::processAnimation, self), m_framesDelay[m_currentFrame]);
} }
*/ */

@ -34,7 +34,7 @@ public:
void enableBilinearFilter(); void enableBilinearFilter();
void processAnimation(); void processAnimation();
AnimatedTexturePtr asAnimatedTexture() { return std::static_pointer_cast<AnimatedTexture>(shared_from_this()); } AnimatedTexturePtr asAnimatedTexture() { return self_cast<AnimatedTexture>(); }
private: private:
std::vector<uint> m_framesTextureId; std::vector<uint> m_framesTextureId;

@ -24,11 +24,12 @@
#define BITMAPFONT_H #define BITMAPFONT_H
#include "declarations.h" #include "declarations.h"
#include "texture.h"
#include <framework/otml/declarations.h> #include <framework/otml/declarations.h>
#include <framework/graphics/coordsbuffer.h> #include <framework/graphics/coordsbuffer.h>
class BitmapFont class BitmapFont : public stdext::shared_object
{ {
public: public:
BitmapFont(const std::string& name) : m_name(name) { } BitmapFont(const std::string& name) : m_name(name) { }

@ -44,24 +44,21 @@ class ParticleSystem;
class ParticleEffect; class ParticleEffect;
class ParticleEffectType; class ParticleEffectType;
typedef std::weak_ptr<Texture> TextureWeakPtr; typedef stdext::shared_object_ptr<Image> ImagePtr;
typedef std::weak_ptr<ParticleSystem> ParticleSystemWeakPtr; typedef stdext::shared_object_ptr<Texture> TexturePtr;
typedef stdext::shared_object_ptr<AnimatedTexture> AnimatedTexturePtr;
typedef std::shared_ptr<Image> ImagePtr; typedef stdext::shared_object_ptr<BitmapFont> BitmapFontPtr;
typedef std::shared_ptr<Texture> TexturePtr; typedef stdext::shared_object_ptr<CachedText> CachedTextPtr;
typedef std::shared_ptr<AnimatedTexture> AnimatedTexturePtr; typedef stdext::shared_object_ptr<FrameBuffer> FrameBufferPtr;
typedef std::shared_ptr<BitmapFont> BitmapFontPtr; typedef stdext::shared_object_ptr<Shader> ShaderPtr;
typedef std::shared_ptr<CachedText> CachedTextPtr; typedef stdext::shared_object_ptr<ShaderProgram> ShaderProgramPtr;
typedef std::shared_ptr<FrameBuffer> FrameBufferPtr; typedef stdext::shared_object_ptr<PainterShaderProgram> PainterShaderProgramPtr;
typedef std::shared_ptr<Shader> ShaderPtr; typedef stdext::shared_object_ptr<Particle> ParticlePtr;
typedef std::shared_ptr<ShaderProgram> ShaderProgramPtr; typedef stdext::shared_object_ptr<ParticleEmitter> ParticleEmitterPtr;
typedef std::shared_ptr<PainterShaderProgram> PainterShaderProgramPtr; typedef stdext::shared_object_ptr<ParticleAffector> ParticleAffectorPtr;
typedef std::shared_ptr<Particle> ParticlePtr; typedef stdext::shared_object_ptr<ParticleSystem> ParticleSystemPtr;
typedef std::shared_ptr<ParticleEmitter> ParticleEmitterPtr; typedef stdext::shared_object_ptr<ParticleEffect> ParticleEffectPtr;
typedef std::shared_ptr<ParticleAffector> ParticleAffectorPtr; typedef stdext::shared_object_ptr<ParticleEffectType> ParticleEffectTypePtr;
typedef std::shared_ptr<ParticleSystem> ParticleSystemPtr;
typedef std::shared_ptr<ParticleEffect> ParticleEffectPtr;
typedef std::shared_ptr<ParticleEffectType> ParticleEffectTypePtr;
typedef std::vector<ShaderPtr> ShaderList; typedef std::vector<ShaderPtr> ShaderList;
#endif #endif

@ -21,6 +21,7 @@
*/ */
#include "fontmanager.h" #include "fontmanager.h"
#include "texture.h"
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <framework/otml/otml.h> #include <framework/otml/otml.h>

@ -26,7 +26,7 @@
#include "declarations.h" #include "declarations.h"
#include "texture.h" #include "texture.h"
class FrameBuffer class FrameBuffer : public stdext::shared_object
{ {
protected: protected:
FrameBuffer(); FrameBuffer();

@ -26,7 +26,7 @@
#include "declarations.h" #include "declarations.h"
#include <framework/util/databuffer.h> #include <framework/util/databuffer.h>
class Image class Image : public stdext::shared_object
{ {
public: public:
Image(const Size& size, int bpp = 4, uint8 *pixels = nullptr); Image(const Size& size, int bpp = 4, uint8 *pixels = nullptr);

@ -27,7 +27,8 @@
#include "painter.h" #include "painter.h"
#include <framework/global.h> #include <framework/global.h>
class Particle { class Particle : public stdext::shared_object
{
public: public:
Particle(const Point& pos, const Size& startSize, const Size& finalSize, const PointF& velocity, const PointF& acceleration, float duration, float ignorePhysicsAfter, const std::vector<Color>& colors, const std::vector<float>& colorsStops, Painter::CompositionMode compositionMode = Painter::CompositionMode_Normal, TexturePtr texture = nullptr); Particle(const Point& pos, const Size& startSize, const Size& finalSize, const PointF& velocity, const PointF& acceleration, float duration, float ignorePhysicsAfter, const std::vector<Color>& colors, const std::vector<float>& colorsStops, Painter::CompositionMode compositionMode = Painter::CompositionMode_Normal, TexturePtr texture = nullptr);

@ -26,7 +26,8 @@
#include "declarations.h" #include "declarations.h"
#include <framework/otml/otml.h> #include <framework/otml/otml.h>
class ParticleAffector { class ParticleAffector : public stdext::shared_object
{
public: public:
ParticleAffector(); ParticleAffector();

@ -26,10 +26,8 @@
#include <framework/core/clock.h> #include <framework/core/clock.h>
#include <framework/graphics/texturemanager.h> #include <framework/graphics/texturemanager.h>
ParticleEmitter::ParticleEmitter(const ParticleSystemPtr& parent) ParticleEmitter::ParticleEmitter()
{ {
m_parent = parent;
m_position = Point(0, 0); m_position = Point(0, 0);
m_duration = -1; m_duration = -1;
m_delay = 0; m_delay = 0;
@ -179,7 +177,7 @@ bool ParticleEmitter::load(const OTMLNodePtr& node)
return true; return true;
} }
void ParticleEmitter::update(float elapsedTime) void ParticleEmitter::update(float elapsedTime, const ParticleSystemPtr& system)
{ {
// check if finished // check if finished
if(m_duration >= 0 && m_elapsedTime >= m_duration + m_delay) { if(m_duration >= 0 && m_elapsedTime >= m_duration + m_delay) {
@ -214,8 +212,7 @@ void ParticleEmitter::update(float elapsedTime)
float pAccelerationAngle = stdext::random_range(m_pMinAccelerationAngle, m_pMaxAccelerationAngle); float pAccelerationAngle = stdext::random_range(m_pMinAccelerationAngle, m_pMaxAccelerationAngle);
PointF pAcceleration(pAccelerationAbs * cos(pAccelerationAngle), pAccelerationAbs * sin(pAccelerationAngle)); PointF pAcceleration(pAccelerationAbs * cos(pAccelerationAngle), pAccelerationAbs * sin(pAccelerationAngle));
ParticleSystemPtr particleSystem = m_parent.lock(); system->addParticle(ParticlePtr(new Particle(pPosition, m_pStartSize, m_pFinalSize, pVelocity, pAcceleration, pDuration, m_pIgnorePhysicsAfter, m_pColors, m_pColorsStops, m_pCompositionMode, m_pTexture)));
particleSystem->addParticle(ParticlePtr(new Particle(pPosition, m_pStartSize, m_pFinalSize, pVelocity, pAcceleration, pDuration, m_pIgnorePhysicsAfter, m_pColors, m_pColorsStops, m_pCompositionMode, m_pTexture)));
} }
} }

@ -29,20 +29,18 @@
#include <framework/graphics/texture.h> #include <framework/graphics/texture.h>
#include <framework/otml/otml.h> #include <framework/otml/otml.h>
class ParticleEmitter { class ParticleEmitter : public stdext::shared_object
{
public: public:
ParticleEmitter();
ParticleEmitter(const ParticleSystemPtr& parent);
bool load(const OTMLNodePtr& node); bool load(const OTMLNodePtr& node);
void update(float elapsedTime); void update(float elapsedTime, const ParticleSystemPtr& system);
bool hasFinished() { return m_finished; } bool hasFinished() { return m_finished; }
private: private:
ParticleSystemWeakPtr m_parent;
// self related // self related
Point m_position; Point m_position;
float m_duration, m_delay; float m_duration, m_delay;

@ -34,7 +34,7 @@ bool ParticleSystem::load(const OTMLNodePtr& node)
{ {
for(const OTMLNodePtr& childNode : node->children()) { for(const OTMLNodePtr& childNode : node->children()) {
if(childNode->tag() == "Emitter") { if(childNode->tag() == "Emitter") {
ParticleEmitterPtr emitter = ParticleEmitterPtr(new ParticleEmitter(shared_from_this())); ParticleEmitterPtr emitter = ParticleEmitterPtr(new ParticleEmitter());
if(!emitter->load(childNode)) if(!emitter->load(childNode))
return false; return false;
m_emitters.push_back(emitter); m_emitters.push_back(emitter);
@ -84,6 +84,7 @@ void ParticleSystem::update()
return; return;
m_lastUpdateTime = g_clock.seconds() - std::fmod(elapsedTime, delay); m_lastUpdateTime = g_clock.seconds() - std::fmod(elapsedTime, delay);
auto self = self_cast<ParticleSystem>();
for(int i = 0; i < elapsedTime / delay; ++i) { for(int i = 0; i < elapsedTime / delay; ++i) {
// update emitters // update emitters
@ -93,7 +94,7 @@ void ParticleSystem::update()
it = m_emitters.erase(it); it = m_emitters.erase(it);
continue; continue;
} }
emitter->update(delay); emitter->update(delay, self);
++it; ++it;
} }

@ -27,7 +27,7 @@
#include "particleemitter.h" #include "particleemitter.h"
#include "particleaffector.h" #include "particleaffector.h"
class ParticleSystem : public std::enable_shared_from_this<ParticleSystem> { class ParticleSystem : public stdext::shared_object {
public: public:
ParticleSystem(); ParticleSystem();

@ -25,7 +25,7 @@
#include "declarations.h" #include "declarations.h"
class Shader class Shader : public stdext::shared_object
{ {
public: public:
enum ShaderType { enum ShaderType {

@ -25,7 +25,7 @@
#include "declarations.h" #include "declarations.h"
class Texture : public std::enable_shared_from_this<Texture> class Texture : public stdext::shared_object
{ {
public: public:
Texture(); Texture();

@ -41,7 +41,7 @@ void TextureManager::terminate()
// check for leaks // check for leaks
int refs = 0; int refs = 0;
for(const auto& it : m_textures) for(const auto& it : m_textures)
if(it.second.use_count() > 1) if(it.second->ref_count() > 1)
refs++; refs++;
if(refs > 0) if(refs > 0)
g_logger.debug(stdext::format("%d textures references left", refs)); g_logger.debug(stdext::format("%d textures references left", refs));
@ -65,10 +65,7 @@ TexturePtr TextureManager::getTexture(const std::string& fileName)
// check if the texture is already loaded // check if the texture is already loaded
auto it = m_textures.find(filePath); auto it = m_textures.find(filePath);
if(it != m_textures.end()) { if(it != m_textures.end()) {
if(it->second.expired()) texture = it->second;
m_textures.erase(it);
else
texture = it->second.lock();
} }
// texture not found, load it // texture not found, load it

@ -38,7 +38,7 @@ public:
private: private:
TexturePtr loadPNG(std::stringstream& file); TexturePtr loadPNG(std::stringstream& file);
std::unordered_map<std::string, TextureWeakPtr> m_textures; std::unordered_map<std::string, TexturePtr> m_textures;
TexturePtr m_emptyTexture; TexturePtr m_emptyTexture;
}; };

@ -30,6 +30,6 @@ class LuaObject;
typedef std::function<int(LuaInterface*)> LuaCppFunction; typedef std::function<int(LuaInterface*)> LuaCppFunction;
typedef std::unique_ptr<LuaCppFunction> LuaCppFunctionPtr; typedef std::unique_ptr<LuaCppFunction> LuaCppFunctionPtr;
typedef std::shared_ptr<LuaObject> LuaObjectPtr; typedef stdext::shared_object_ptr<LuaObject> LuaObjectPtr;
#endif #endif

@ -152,18 +152,18 @@ namespace luabinder
/// Create member function lambdas /// Create member function lambdas
template<typename Ret, typename C, typename... Args> template<typename Ret, typename C, typename... Args>
std::function<Ret(const std::shared_ptr<C>&, const Args&...)> make_mem_func(Ret (C::* f)(Args...)) { std::function<Ret(const stdext::shared_object_ptr<C>&, const Args&...)> make_mem_func(Ret (C::* f)(Args...)) {
auto mf = std::mem_fn(f); auto mf = std::mem_fn(f);
return [=](const std::shared_ptr<C>& obj, const Args&... args) mutable -> Ret { return [=](const stdext::shared_object_ptr<C>& obj, const Args&... args) mutable -> Ret {
if(!obj) if(!obj)
throw LuaException("failed to call a member function because the passed object is nil"); throw LuaException("failed to call a member function because the passed object is nil");
return mf(obj.get(), args...); return mf(obj.get(), args...);
}; };
} }
template<typename C, typename... Args> template<typename C, typename... Args>
std::function<void(const std::shared_ptr<C>&, const Args&...)> make_mem_func(void (C::* f)(Args...)) { std::function<void(const stdext::shared_object_ptr<C>&, const Args&...)> make_mem_func(void (C::* f)(Args...)) {
auto mf = std::mem_fn(f); auto mf = std::mem_fn(f);
return [=](const std::shared_ptr<C>& obj, const Args&... args) mutable -> void { return [=](const stdext::shared_object_ptr<C>& obj, const Args&... args) mutable -> void {
if(!obj) if(!obj)
throw LuaException("failed to call a member function because the passed object is nil"); throw LuaException("failed to call a member function because the passed object is nil");
mf(obj.get(), args...); mf(obj.get(), args...);
@ -186,7 +186,7 @@ namespace luabinder
/// Bind member functions /// Bind member functions
template<typename C, typename Ret, class FC, typename... Args> template<typename C, typename Ret, class FC, typename... Args>
LuaCppFunction bind_mem_fun(Ret (FC::* f)(Args...)) { LuaCppFunction bind_mem_fun(Ret (FC::* f)(Args...)) {
typedef typename std::tuple<std::shared_ptr<FC>, typename remove_const_ref<Args>::type...> Tuple; typedef typename std::tuple<stdext::shared_object_ptr<FC>, typename remove_const_ref<Args>::type...> Tuple;
auto lambda = make_mem_func<Ret,FC>(f); auto lambda = make_mem_func<Ret,FC>(f);
return bind_fun_specializer<typename remove_const_ref<Ret>::type, return bind_fun_specializer<typename remove_const_ref<Ret>::type,
decltype(lambda), decltype(lambda),
@ -209,7 +209,7 @@ namespace luabinder
LuaCppFunction bind_mem_fun(int (C::*f)(LuaInterface*)) { LuaCppFunction bind_mem_fun(int (C::*f)(LuaInterface*)) {
auto mf = std::mem_fn(f); auto mf = std::mem_fn(f);
return [=](LuaInterface* lua) -> int { return [=](LuaInterface* lua) -> int {
auto obj = lua->castValue<std::shared_ptr<C>>(1); auto obj = lua->castValue<stdext::shared_object_ptr<C>>(1);
lua->remove(1); lua->remove(1);
return mf(obj, lua); return mf(obj, lua);
}; };

@ -108,5 +108,5 @@ void LuaObject::luaGetFieldsTable()
int LuaObject::getUseCount() int LuaObject::getUseCount()
{ {
return shared_from_this().use_count() - 1; return ref_count();
} }

@ -27,8 +27,7 @@
/// LuaObject, all script-able classes have it as base /// LuaObject, all script-able classes have it as base
// @bindclass // @bindclass
#pragma pack(push,1) // disable memory alignment class LuaObject : public stdext::shared_object
class LuaObject : public std::enable_shared_from_this<LuaObject>
{ {
public: public:
LuaObject(); LuaObject();
@ -81,7 +80,7 @@ public:
return stdext::demangle_name(typeid(*this).name()); return stdext::demangle_name(typeid(*this).name());
} }
LuaObjectPtr asLuaObject() { return shared_from_this(); } LuaObjectPtr asLuaObject() { return self_cast<LuaObject>(); }
void operator=(const LuaObject& other) { } void operator=(const LuaObject& other) { }
@ -89,7 +88,6 @@ private:
int m_fieldsTableRef; int m_fieldsTableRef;
int m_metatableRef; int m_metatableRef;
}; };
#pragma pack(pop)
#include "luainterface.h" #include "luainterface.h"

@ -111,7 +111,7 @@ bool luavalue_cast(int index, LuaObjectPtr& obj);
template<class T> template<class T>
typename std::enable_if<std::is_base_of<LuaObject, T>::value, bool>::type typename std::enable_if<std::is_base_of<LuaObject, T>::value, bool>::type
luavalue_cast(int index, std::shared_ptr<T>& ptr); luavalue_cast(int index, stdext::shared_object_ptr<T>& ptr);
// std::function // std::function
template<typename Ret, typename... Args> template<typename Ret, typename... Args>
@ -156,7 +156,7 @@ int push_internal_luavalue(const std::tuple<Args...>& tuple);
#include "luaexception.h" #include "luaexception.h"
#include "luainterface.h" #include "luainterface.h"
#include "luaobject.h"
template<typename T> template<typename T>
int push_internal_luavalue(T v) { int push_internal_luavalue(T v) {
@ -181,11 +181,14 @@ push_luavalue(const T& obj) {
template<class T> template<class T>
typename std::enable_if<std::is_base_of<LuaObject, T>::value, bool>::type typename std::enable_if<std::is_base_of<LuaObject, T>::value, bool>::type
luavalue_cast(int index, std::shared_ptr<T>& ptr) { luavalue_cast(int index, stdext::shared_object_ptr<T>& ptr) {
LuaObjectPtr obj; LuaObjectPtr obj;
if(!luavalue_cast(index, obj)) if(!luavalue_cast(index, obj))
return false; return false;
ptr = std::dynamic_pointer_cast<T>(obj); if(obj)
ptr = obj->dynamic_self_cast<T>();
else
ptr = nullptr;
return true; return true;
} }

@ -340,7 +340,6 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildrenByPos", &UIWidget::recursiveGetChildrenByPos); g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildrenByPos", &UIWidget::recursiveGetChildrenByPos);
g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildrenByMarginPos", &UIWidget::recursiveGetChildrenByMarginPos); g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildrenByMarginPos", &UIWidget::recursiveGetChildrenByMarginPos);
g_lua.bindClassMemberFunction<UIWidget>("backwardsGetWidgetById", &UIWidget::backwardsGetWidgetById); g_lua.bindClassMemberFunction<UIWidget>("backwardsGetWidgetById", &UIWidget::backwardsGetWidgetById);
g_lua.bindClassMemberFunction<UIWidget>("asUIWidget", &UIWidget::asUIWidget);
g_lua.bindClassMemberFunction<UIWidget>("resize", &UIWidget::resize); g_lua.bindClassMemberFunction<UIWidget>("resize", &UIWidget::resize);
g_lua.bindClassMemberFunction<UIWidget>("move", &UIWidget::move); g_lua.bindClassMemberFunction<UIWidget>("move", &UIWidget::move);
g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide); g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide);
@ -541,12 +540,11 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UILayout>("getParentWidget", &UILayout::getParentWidget); g_lua.bindClassMemberFunction<UILayout>("getParentWidget", &UILayout::getParentWidget);
g_lua.bindClassMemberFunction<UILayout>("isUpdateDisabled", &UILayout::isUpdateDisabled); g_lua.bindClassMemberFunction<UILayout>("isUpdateDisabled", &UILayout::isUpdateDisabled);
g_lua.bindClassMemberFunction<UILayout>("isUpdating", &UILayout::isUpdating); g_lua.bindClassMemberFunction<UILayout>("isUpdating", &UILayout::isUpdating);
g_lua.bindClassMemberFunction<UILayout>("asUILayout", &UILayout::asUILayout); g_lua.bindClassMemberFunction<UILayout>("isUIAnchorLayout", &UILayout::isUIAnchorLayout);
g_lua.bindClassMemberFunction<UILayout>("asUIAnchorLayout", &UILayout::asUIAnchorLayout); g_lua.bindClassMemberFunction<UILayout>("isUIBoxLayout", &UILayout::isUIBoxLayout);
g_lua.bindClassMemberFunction<UILayout>("asUIBoxLayout", &UILayout::asUIBoxLayout); g_lua.bindClassMemberFunction<UILayout>("isUIHorizontalLayout", &UILayout::isUIHorizontalLayout);
g_lua.bindClassMemberFunction<UILayout>("asUIHorizontalLayout", &UILayout::asUIHorizontalLayout); g_lua.bindClassMemberFunction<UILayout>("isUIVerticalLayout", &UILayout::isUIVerticalLayout);
g_lua.bindClassMemberFunction<UILayout>("asUIVerticalLayout", &UILayout::asUIVerticalLayout); g_lua.bindClassMemberFunction<UILayout>("isUIGridLayout", &UILayout::isUIGridLayout);
g_lua.bindClassMemberFunction<UILayout>("asUIGridLayout", &UILayout::asUIGridLayout);
// UIBoxLayout // UIBoxLayout
g_lua.registerClass<UIBoxLayout, UILayout>(); g_lua.registerClass<UIBoxLayout, UILayout>();
@ -573,7 +571,7 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIGridLayout>("setFlow", &UIGridLayout::setFlow); g_lua.bindClassMemberFunction<UIGridLayout>("setFlow", &UIGridLayout::setFlow);
g_lua.bindClassMemberFunction<UIGridLayout>("setNumColumns", &UIGridLayout::setNumColumns); g_lua.bindClassMemberFunction<UIGridLayout>("setNumColumns", &UIGridLayout::setNumColumns);
g_lua.bindClassMemberFunction<UIGridLayout>("setNumLines", &UIGridLayout::setNumLines); g_lua.bindClassMemberFunction<UIGridLayout>("setNumLines", &UIGridLayout::setNumLines);
g_lua.bindClassMemberFunction<UIGridLayout>("asUIGridLayout", &UIGridLayout::asUIGridLayout); g_lua.bindClassMemberFunction<UIGridLayout>("isUIGridLayout", &UIGridLayout::isUIGridLayout);
// UIAnchorLayout // UIAnchorLayout
g_lua.registerClass<UIAnchorLayout, UILayout>(); g_lua.registerClass<UIAnchorLayout, UILayout>();

@ -65,23 +65,23 @@ void Connection::connect(const std::string& host, uint16 port, const std::functi
asio::ip::tcp::resolver::query query(host, stdext::unsafe_cast<std::string>(port)); asio::ip::tcp::resolver::query query(host, stdext::unsafe_cast<std::string>(port));
auto weakSelf = ConnectionWeakPtr(shared_from_this()); auto self = asConnection();
m_resolver.async_resolve(query, [=](const boost::system::error_code& error, asio::ip::tcp::resolver::iterator endpointIterator) { m_resolver.async_resolve(query, [=](const boost::system::error_code& error, asio::ip::tcp::resolver::iterator endpointIterator) {
if(!weakSelf.lock()) if(self->is_unique_ref())
return; return;
m_readTimer.cancel(); m_readTimer.cancel();
if(!error) { if(!error) {
m_socket.async_connect(*endpointIterator, std::bind(&Connection::onConnect, shared_from_this(), std::placeholders::_1)); m_socket.async_connect(*endpointIterator, std::bind(&Connection::onConnect, asConnection(), std::placeholders::_1));
m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT)); m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT));
m_readTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1)); m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
} else } else
handleError(error); handleError(error);
}); });
m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT)); m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT));
m_readTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1)); m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
} }
void Connection::close() void Connection::close()
@ -124,20 +124,20 @@ void Connection::write(uint8* buffer, uint16 size)
m_sendBufferSize += size; m_sendBufferSize += size;
if(!m_sendEvent || m_sendEvent->isExecuted() || m_sendEvent->isCanceled()) { if(!m_sendEvent || m_sendEvent->isExecuted() || m_sendEvent->isCanceled()) {
auto weakSelf = ConnectionWeakPtr(shared_from_this()); auto self = asConnection();
// wait 1 ms to do the real send // wait 1 ms to do the real send
m_sendEvent = g_dispatcher.scheduleEvent([=] { m_sendEvent = g_dispatcher.scheduleEvent([=] {
if(!weakSelf.lock()) if(self->is_unique_ref())
return; return;
//m_writeTimer.cancel(); //m_writeTimer.cancel();
asio::async_write(m_socket, asio::async_write(m_socket,
asio::buffer(m_sendBuffer, m_sendBufferSize), asio::buffer(m_sendBuffer, m_sendBufferSize),
std::bind(&Connection::onWrite, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); std::bind(&Connection::onWrite, asConnection(), std::placeholders::_1, std::placeholders::_2));
m_writeTimer.expires_from_now(boost::posix_time::seconds(WRITE_TIMEOUT)); m_writeTimer.expires_from_now(boost::posix_time::seconds(WRITE_TIMEOUT));
m_writeTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1)); m_writeTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
m_sendBufferSize = 0; m_sendBufferSize = 0;
}, SEND_INTERVAL); }, SEND_INTERVAL);
@ -155,10 +155,10 @@ void Connection::read(uint16 bytes, const RecvCallback& callback)
asio::async_read(m_socket, asio::async_read(m_socket,
asio::buffer(m_recvBuffer, bytes), asio::buffer(m_recvBuffer, bytes),
std::bind(&Connection::onRecv, shared_from_this(), std::placeholders::_1, bytes)); std::bind(&Connection::onRecv, asConnection(), std::placeholders::_1, bytes));
m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT)); m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT));
m_readTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1)); m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
} }
void Connection::read_some(const RecvCallback& callback) void Connection::read_some(const RecvCallback& callback)
@ -171,10 +171,10 @@ void Connection::read_some(const RecvCallback& callback)
m_recvCallback = callback; m_recvCallback = callback;
m_socket.async_read_some(asio::buffer(m_recvBuffer, RECV_BUFFER_SIZE), m_socket.async_read_some(asio::buffer(m_recvBuffer, RECV_BUFFER_SIZE),
std::bind(&Connection::onRecv, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); std::bind(&Connection::onRecv, asConnection(), std::placeholders::_1, std::placeholders::_2));
m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT)); m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT));
m_readTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1)); m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1));
} }
void Connection::onConnect(const boost::system::error_code& error) void Connection::onConnect(const boost::system::error_code& error)

@ -28,7 +28,7 @@
#include <framework/core/timer.h> #include <framework/core/timer.h>
#include <framework/core/declarations.h> #include <framework/core/declarations.h>
class Connection : public std::enable_shared_from_this<Connection>, boost::noncopyable class Connection : public stdext::shared_object
{ {
typedef std::function<void(const boost::system::error_code&)> ErrorCallback; typedef std::function<void(const boost::system::error_code&)> ErrorCallback;
typedef std::function<void(uint8*, uint16)> RecvCallback; typedef std::function<void(uint8*, uint16)> RecvCallback;
@ -61,6 +61,7 @@ public:
bool isConnecting() { return m_connecting; } bool isConnecting() { return m_connecting; }
bool isConnected() { return m_connected; } bool isConnected() { return m_connected; }
ConnectionPtr asConnection() { return self_cast<Connection>(); }
protected: protected:
void onConnect(const boost::system::error_code& error); void onConnect(const boost::system::error_code& error);
void onWrite(const boost::system::error_code& error, size_t); void onWrite(const boost::system::error_code& error, size_t);

@ -34,11 +34,10 @@ class Connection;
class Protocol; class Protocol;
class Server; class Server;
typedef std::shared_ptr<InputMessage> InputMessagePtr; typedef stdext::shared_object_ptr<InputMessage> InputMessagePtr;
typedef std::shared_ptr<OutputMessage> OutputMessagePtr; typedef stdext::shared_object_ptr<OutputMessage> OutputMessagePtr;
typedef std::shared_ptr<Connection> ConnectionPtr; typedef stdext::shared_object_ptr<Connection> ConnectionPtr;
typedef std::weak_ptr<Connection> ConnectionWeakPtr; typedef stdext::shared_object_ptr<Protocol> ProtocolPtr;
typedef std::shared_ptr<Protocol> ProtocolPtr; typedef stdext::shared_object_ptr<Server> ServerPtr;
typedef std::shared_ptr<Server> ServerPtr;
#endif #endif

@ -51,7 +51,7 @@ public:
virtual void send(const OutputMessagePtr& outputMessage); virtual void send(const OutputMessagePtr& outputMessage);
void recv(); void recv();
ProtocolPtr asProtocol() { return std::static_pointer_cast<Protocol>(shared_from_this()); } ProtocolPtr asProtocol() { return self_cast<Protocol>(); }
protected: protected:
virtual void onConnect(); virtual void onConnect();

@ -30,9 +30,8 @@ class OTMLDocument;
class OTMLParser; class OTMLParser;
class OTMLEmitter; class OTMLEmitter;
typedef std::shared_ptr<OTMLNode> OTMLNodePtr; typedef stdext::shared_object_ptr<OTMLNode> OTMLNodePtr;
typedef std::shared_ptr<OTMLDocument> OTMLDocumentPtr; typedef stdext::shared_object_ptr<OTMLDocument> OTMLDocumentPtr;
typedef std::weak_ptr<OTMLNode> OTMLNodeWeakPtr;
typedef std::vector<OTMLNodePtr> OTMLNodeList; typedef std::vector<OTMLNodePtr> OTMLNodeList;
#endif #endif

@ -52,7 +52,7 @@ OTMLDocumentPtr OTMLDocument::parse(std::istream& in, const std::string& source)
std::string OTMLDocument::emit() std::string OTMLDocument::emit()
{ {
return OTMLEmitter::emitNode(shared_from_this()) + "\n"; return OTMLEmitter::emitNode(asOTMLNode()) + "\n";
} }
bool OTMLDocument::save(const std::string& fileName) bool OTMLDocument::save(const std::string& fileName)

@ -77,14 +77,14 @@ OTMLNodePtr OTMLNode::at(const std::string& childTag)
} }
} }
if(!res) if(!res)
throw OTMLException(shared_from_this(), stdext::format("child node with tag '%s' not found", childTag)); throw OTMLException(asOTMLNode(), stdext::format("child node with tag '%s' not found", childTag));
return res; return res;
} }
OTMLNodePtr OTMLNode::atIndex(int childIndex) OTMLNodePtr OTMLNode::atIndex(int childIndex)
{ {
if(childIndex >= size() || childIndex < 0) if(childIndex >= size() || childIndex < 0)
throw OTMLException(shared_from_this(), stdext::mkstr("child node with index '%d' not found", childIndex)); throw OTMLException(asOTMLNode(), stdext::mkstr("child node with index '%d' not found", childIndex));
return m_children[childIndex]; return m_children[childIndex];
} }
@ -109,7 +109,6 @@ void OTMLNode::addChild(const OTMLNodePtr& newChild)
while(it != m_children.end()) { while(it != m_children.end()) {
OTMLNodePtr node = (*it); OTMLNodePtr node = (*it);
if(node != newChild && node->tag() == newChild->tag()) { if(node != newChild && node->tag() == newChild->tag()) {
node->setParent(nullptr);
it = m_children.erase(it); it = m_children.erase(it);
} else } else
++it; ++it;
@ -120,7 +119,6 @@ void OTMLNode::addChild(const OTMLNodePtr& newChild)
} }
m_children.push_back(newChild); m_children.push_back(newChild);
newChild->setParent(shared_from_this());
} }
bool OTMLNode::removeChild(const OTMLNodePtr& oldChild) bool OTMLNode::removeChild(const OTMLNodePtr& oldChild)
@ -128,7 +126,6 @@ bool OTMLNode::removeChild(const OTMLNodePtr& oldChild)
auto it = std::find(m_children.begin(), m_children.end(), oldChild); auto it = std::find(m_children.begin(), m_children.end(), oldChild);
if(it != m_children.end()) { if(it != m_children.end()) {
m_children.erase(it); m_children.erase(it);
oldChild->setParent(nullptr);
return true; return true;
} }
return false; return false;
@ -138,8 +135,6 @@ bool OTMLNode::replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newC
{ {
auto it = std::find(m_children.begin(), m_children.end(), oldChild); auto it = std::find(m_children.begin(), m_children.end(), oldChild);
if(it != m_children.end()) { if(it != m_children.end()) {
oldChild->setParent(nullptr);
newChild->setParent(shared_from_this());
it = m_children.erase(it); it = m_children.erase(it);
m_children.insert(it, newChild); m_children.insert(it, newChild);
return true; return true;
@ -169,8 +164,6 @@ void OTMLNode::merge(const OTMLNodePtr& node)
void OTMLNode::clear() void OTMLNode::clear()
{ {
for(const OTMLNodePtr& child : m_children)
child->setParent(nullptr);
m_children.clear(); m_children.clear();
} }
@ -198,6 +191,6 @@ OTMLNodePtr OTMLNode::clone()
std::string OTMLNode::emit() std::string OTMLNode::emit()
{ {
return OTMLEmitter::emitNode(shared_from_this(), 0); return OTMLEmitter::emitNode(asOTMLNode(), 0);
} }

@ -25,7 +25,7 @@
#include "declarations.h" #include "declarations.h"
class OTMLNode : public std::enable_shared_from_this<OTMLNode> class OTMLNode : public stdext::shared_object
{ {
public: public:
virtual ~OTMLNode() { } virtual ~OTMLNode() { }
@ -35,7 +35,6 @@ public:
std::string tag() { return m_tag; } std::string tag() { return m_tag; }
int size() { return m_children.size(); } int size() { return m_children.size(); }
OTMLNodePtr parent() { return m_parent.lock(); }
std::string source() { return m_source; } std::string source() { return m_source; }
std::string rawValue() { return m_value; } std::string rawValue() { return m_value; }
@ -52,7 +51,6 @@ public:
void setValue(const std::string& value) { m_value = value; } void setValue(const std::string& value) { m_value = value; }
void setNull(bool null) { m_null = null; } void setNull(bool null) { m_null = null; }
void setUnique(bool unique) { m_unique = unique; } void setUnique(bool unique) { m_unique = unique; }
void setParent(const OTMLNodePtr& parent) { m_parent = parent; }
void setSource(const std::string& source) { m_source = source; } void setSource(const std::string& source) { m_source = source; }
OTMLNodePtr get(const std::string& childTag); OTMLNodePtr get(const std::string& childTag);
@ -91,11 +89,12 @@ public:
virtual std::string emit(); virtual std::string emit();
OTMLNodePtr asOTMLNode() { return self_cast<OTMLNode>(); }
protected: protected:
OTMLNode() : m_unique(false), m_null(false) { } OTMLNode() : m_unique(false), m_null(false) { }
OTMLNodeList m_children; OTMLNodeList m_children;
OTMLNodeWeakPtr m_parent;
std::string m_tag; std::string m_tag;
std::string m_value; std::string m_value;
std::string m_source; std::string m_source;
@ -123,7 +122,7 @@ template<typename T>
T OTMLNode::value() { T OTMLNode::value() {
T ret; T ret;
if(!stdext::cast(m_value, ret)) if(!stdext::cast(m_value, ret))
throw OTMLException(shared_from_this(), stdext::format("failed to cast node value '%s' to type '%s'", m_value, stdext::demangle_type<T>())); throw OTMLException(asOTMLNode(), stdext::format("failed to cast node value '%s' to type '%s'", m_value, stdext::demangle_type<T>()));
return ret; return ret;
} }

@ -96,7 +96,7 @@ void OTMLParser::parseLine(std::string line)
// a depth below, change parent to previous parent // a depth below, change parent to previous parent
} else if(depth < currentDepth) { } else if(depth < currentDepth) {
for(int i=0;i<currentDepth-depth;++i) for(int i=0;i<currentDepth-depth;++i)
currentParent = currentParent->parent(); currentParent = parentMap[currentParent];
// if it isn't the current depth, it's a syntax error // if it isn't the current depth, it's a syntax error
} else if(depth != currentDepth) } else if(depth != currentDepth)
throw OTMLException(doc, "invalid indentation depth, are you indenting correctly?", currentLine); throw OTMLException(doc, "invalid indentation depth, are you indenting correctly?", currentLine);
@ -198,5 +198,6 @@ void OTMLParser::parseNode(const std::string& data)
} }
currentParent->addChild(node); currentParent->addChild(node);
parentMap[node] = currentParent;
previousNode = node; previousNode = node;
} }

@ -48,6 +48,7 @@ private:
int currentLine; int currentLine;
OTMLDocumentPtr doc; OTMLDocumentPtr doc;
OTMLNodePtr currentParent; OTMLNodePtr currentParent;
std::unordered_map<OTMLNodePtr, OTMLNodePtr> parentMap;
OTMLNodePtr previousNode; OTMLNodePtr previousNode;
std::istream& in; std::istream& in;
}; };

@ -38,11 +38,11 @@ class StreamSoundSource;
class CombinedSoundSource; class CombinedSoundSource;
class OggSoundFile; class OggSoundFile;
typedef std::shared_ptr<SoundSource> SoundSourcePtr; typedef stdext::shared_object_ptr<SoundSource> SoundSourcePtr;
typedef std::shared_ptr<SoundFile> SoundFilePtr; typedef stdext::shared_object_ptr<SoundFile> SoundFilePtr;
typedef std::shared_ptr<SoundBuffer> SoundBufferPtr; typedef stdext::shared_object_ptr<SoundBuffer> SoundBufferPtr;
typedef std::shared_ptr<StreamSoundSource> StreamSoundSourcePtr; typedef stdext::shared_object_ptr<StreamSoundSource> StreamSoundSourcePtr;
typedef std::shared_ptr<CombinedSoundSource> CombinedSoundSourcePtr; typedef stdext::shared_object_ptr<CombinedSoundSource> CombinedSoundSourcePtr;
typedef std::shared_ptr<OggSoundFile> OggSoundFilePtr; typedef stdext::shared_object_ptr<OggSoundFile> OggSoundFilePtr;
#endif #endif

@ -27,7 +27,7 @@
#include <framework/util/databuffer.h> #include <framework/util/databuffer.h>
class SoundBuffer class SoundBuffer : public stdext::shared_object
{ {
public: public:
SoundBuffer(); SoundBuffer();

@ -26,7 +26,7 @@
#include "declarations.h" #include "declarations.h"
#include <framework/core/filestream.h> #include <framework/core/filestream.h>
class SoundFile class SoundFile : public stdext::shared_object
{ {
public: public:
SoundFile(const FileStreamPtr& fileStream); SoundFile(const FileStreamPtr& fileStream);

@ -24,8 +24,9 @@
#define SOUNDSOURCE_H #define SOUNDSOURCE_H
#include "declarations.h" #include "declarations.h"
#include "soundbuffer.h"
class SoundSource class SoundSource : public stdext::shared_object
{ {
protected: protected:
SoundSource(uint sourceId) : m_sourceId(sourceId) { } SoundSource(uint sourceId) : m_sourceId(sourceId) { }

@ -32,5 +32,6 @@
#include "string.h" #include "string.h"
#include "dumper.h" #include "dumper.h"
#include "time.h" #include "time.h"
#include "shared_object.h"
#endif #endif

@ -36,17 +36,15 @@ class UIGridLayout;
class UIAnchorLayout; class UIAnchorLayout;
class UIParticles; class UIParticles;
typedef std::shared_ptr<UIWidget> UIWidgetPtr; typedef stdext::shared_object_ptr<UIWidget> UIWidgetPtr;
typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr; typedef stdext::shared_object_ptr<UIParticles> UIParticlesPtr;
typedef stdext::shared_object_ptr<UITextEdit> UITextEditPtr;
typedef std::shared_ptr<UIParticles> UIParticlesPtr; typedef stdext::shared_object_ptr<UILayout> UILayoutPtr;
typedef std::shared_ptr<UITextEdit> UITextEditPtr; typedef stdext::shared_object_ptr<UIBoxLayout> UIBoxLayoutPtr;
typedef std::shared_ptr<UILayout> UILayoutPtr; typedef stdext::shared_object_ptr<UIHorizontalLayout> UIHorizontalLayoutPtr;
typedef std::shared_ptr<UIBoxLayout> UIBoxLayoutPtr; typedef stdext::shared_object_ptr<UIVerticalLayout> UIVerticalLayoutPtr;
typedef std::shared_ptr<UIHorizontalLayout> UIHorizontalLayoutPtr; typedef stdext::shared_object_ptr<UIGridLayout> UIGridLayoutPtr;
typedef std::shared_ptr<UIVerticalLayout> UIVerticalLayoutPtr; typedef stdext::shared_object_ptr<UIAnchorLayout> UIAnchorLayoutPtr;
typedef std::shared_ptr<UIGridLayout> UIGridLayoutPtr;
typedef std::shared_ptr<UIAnchorLayout> UIAnchorLayoutPtr;
typedef std::deque<UIWidgetPtr> UIWidgetList; typedef std::deque<UIWidgetPtr> UIWidgetList;

@ -74,7 +74,7 @@ public:
void addWidget(const UIWidgetPtr& widget); void addWidget(const UIWidgetPtr& widget);
void removeWidget(const UIWidgetPtr& widget); void removeWidget(const UIWidgetPtr& widget);
UIAnchorLayoutPtr asUIAnchorLayout() { return std::static_pointer_cast<UIAnchorLayout>(shared_from_this()); } bool isUIAnchorLayout() { return true; }
protected: protected:
bool internalUpdate(); bool internalUpdate();

@ -38,7 +38,7 @@ public:
void setSpacing(int spacing) { m_spacing = spacing; update(); } void setSpacing(int spacing) { m_spacing = spacing; update(); }
void setFitChildren(bool fitParent) { m_fitChildren = fitParent; update(); } void setFitChildren(bool fitParent) { m_fitChildren = fitParent; update(); }
UIBoxLayoutPtr asUIBoxLayout() { return std::static_pointer_cast<UIBoxLayout>(shared_from_this()); } bool isUIBoxLayout() { return true; }
protected: protected:
Boolean<false> m_fitChildren; Boolean<false> m_fitChildren;

@ -23,7 +23,7 @@
#ifndef UIGRIDLAYOUT_H #ifndef UIGRIDLAYOUT_H
#define UIGRIDLAYOUT_H #define UIGRIDLAYOUT_H
#include <framework/ui/uilayout.h> #include "uilayout.h"
// @bindclass // @bindclass
class UIGridLayout : public UILayout class UIGridLayout : public UILayout
@ -45,7 +45,7 @@ public:
void setFitChildren(bool enable) { m_fitChildren = enable; update(); } void setFitChildren(bool enable) { m_fitChildren = enable; update(); }
void setFlow(bool enable) { m_flow = enable; update(); } void setFlow(bool enable) { m_flow = enable; update(); }
virtual UIGridLayoutPtr asUIGridLayout() { return nullptr; } virtual bool isUIGridLayout() { return true; }
protected: protected:
bool internalUpdate(); bool internalUpdate();

@ -34,7 +34,7 @@ public:
void setAlignRight(bool aliginRight) { m_alignRight = aliginRight; update(); } void setAlignRight(bool aliginRight) { m_alignRight = aliginRight; update(); }
UIHorizontalLayoutPtr asUIHorizontalLayout() { return std::static_pointer_cast<UIHorizontalLayout>(shared_from_this()); } bool isUIHorizontalLayout() { return true; }
protected: protected:
bool internalUpdate(); bool internalUpdate();

@ -28,8 +28,7 @@
void UILayout::update() void UILayout::update()
{ {
//logTraceCounter(); //logTraceCounter();
UIWidgetPtr parentWidget = getParentWidget(); if(!m_parentWidget)
if(!parentWidget || parentWidget->isDestroyed())
return; return;
/* /*
@ -52,7 +51,7 @@ void UILayout::update()
m_updating = true; m_updating = true;
internalUpdate(); internalUpdate();
parentWidget->onLayoutUpdate(); m_parentWidget->onLayoutUpdate();
m_updating = false; m_updating = false;
} }
@ -64,7 +63,7 @@ void UILayout::updateLater()
if(!getParentWidget()) if(!getParentWidget())
return; return;
auto self = asUILayout(); auto self = self_cast<UILayout>();
g_dispatcher.addEvent([self] { g_dispatcher.addEvent([self] {
self->m_updateScheduled = false; self->m_updateScheduled = false;
self->update(); self->update();

@ -43,17 +43,16 @@ public:
void enableUpdates() { m_updateDisabled = std::max(m_updateDisabled-1,0); } void enableUpdates() { m_updateDisabled = std::max(m_updateDisabled-1,0); }
void setParent(UIWidgetPtr parentWidget) { m_parentWidget = parentWidget; } void setParent(UIWidgetPtr parentWidget) { m_parentWidget = parentWidget; }
UIWidgetPtr getParentWidget() { return m_parentWidget.lock(); } UIWidgetPtr getParentWidget() { return m_parentWidget; }
bool isUpdateDisabled() { return m_updateDisabled > 0; } bool isUpdateDisabled() { return m_updateDisabled > 0; }
bool isUpdating() { return m_updating; } bool isUpdating() { return m_updating; }
UILayoutPtr asUILayout() { return std::static_pointer_cast<UILayout>(shared_from_this()); } virtual bool isUIAnchorLayout() { return false; }
virtual UIAnchorLayoutPtr asUIAnchorLayout() { return nullptr; } virtual bool isUIBoxLayout() { return false; }
virtual UIBoxLayoutPtr asUIBoxLayout() { return nullptr; } virtual bool isUIHorizontalLayout() { return false; }
virtual UIHorizontalLayoutPtr asUIHorizontalLayout() { return nullptr; } virtual bool isUIVerticalLayout() { return false; }
virtual UIVerticalLayoutPtr asUIVerticalLayout() { return nullptr; } virtual bool isUIGridLayout() { return false; }
virtual UIGridLayoutPtr asUIGridLayout() { return nullptr; }
protected: protected:
virtual bool internalUpdate() = 0; virtual bool internalUpdate() = 0;
@ -61,7 +60,7 @@ protected:
int m_updateDisabled; int m_updateDisabled;
Boolean<false> m_updating; Boolean<false> m_updating;
Boolean<false> m_updateScheduled; Boolean<false> m_updateScheduled;
UIWidgetWeakPtr m_parentWidget; UIWidgetPtr m_parentWidget;
}; };
#endif #endif

@ -285,7 +285,7 @@ void UIManager::onWidgetDestroy(const UIWidgetPtr& widget)
g_dispatcher.scheduleEvent([backupList] { g_dispatcher.scheduleEvent([backupList] {
g_lua.collectGarbage(); g_lua.collectGarbage();
for(const UIWidgetPtr& widget : backupList) { for(const UIWidgetPtr& widget : backupList) {
if(widget->getUseCount() != 1) if(widget->ref_count() != 1)
g_logger.warning(stdext::format("widget '%s' destroyed but still have %d reference(s) left", widget->getId(), widget->getUseCount()-1)); g_logger.warning(stdext::format("widget '%s' destroyed but still have %d reference(s) left", widget->getId(), widget->getUseCount()-1));
} }
}, 1); }, 1);

@ -24,6 +24,7 @@
#define UIMANAGER_H #define UIMANAGER_H
#include "declarations.h" #include "declarations.h"
#include "uiwidget.h"
#include <framework/core/inputevent.h> #include <framework/core/inputevent.h>
#include <framework/otml/declarations.h> #include <framework/otml/declarations.h>

@ -35,7 +35,7 @@ public:
void setAlignBottom(bool aliginBottom) { m_alignBottom = aliginBottom; update(); } void setAlignBottom(bool aliginBottom) { m_alignBottom = aliginBottom; update(); }
UIVerticalLayoutPtr asUIVerticalLayout() { return std::static_pointer_cast<UIVerticalLayout>(shared_from_this()); } bool isUIVerticalLayout() { return true; }
protected: protected:
bool internalUpdate(); bool internalUpdate();

@ -141,11 +141,11 @@ void UIWidget::addChild(const UIWidgetPtr& child)
UIWidgetPtr oldLastChild = getLastChild(); UIWidgetPtr oldLastChild = getLastChild();
m_children.push_back(child); m_children.push_back(child);
child->setParent(asUIWidget()); child->setParent(self_cast<UIWidget>());
// create default layout // create default layout
if(!m_layout) if(!m_layout)
m_layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget())); m_layout = UIAnchorLayoutPtr(new UIAnchorLayout(self_cast<UIWidget>()));
// add to layout and updates it // add to layout and updates it
m_layout->addWidget(child); m_layout->addWidget(child);
@ -184,11 +184,11 @@ void UIWidget::insertChild(int index, const UIWidgetPtr& child)
// retrieve child by index // retrieve child by index
auto it = m_children.begin() + index; auto it = m_children.begin() + index;
m_children.insert(it, child); m_children.insert(it, child);
child->setParent(asUIWidget()); child->setParent(self_cast<UIWidget>());
// create default layout if needed // create default layout if needed
if(!m_layout) if(!m_layout)
m_layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget())); m_layout = UIAnchorLayoutPtr(new UIAnchorLayout(self_cast<UIWidget>()));
// add to layout and updates it // add to layout and updates it
m_layout->addWidget(child); m_layout->addWidget(child);
@ -218,7 +218,7 @@ void UIWidget::removeChild(UIWidgetPtr child)
m_children.erase(it); m_children.erase(it);
// reset child parent // reset child parent
assert(child->getParent() == asUIWidget()); assert(child->getParent() == self_cast<UIWidget>());
child->setParent(nullptr); child->setParent(nullptr);
m_layout->removeWidget(child); m_layout->removeWidget(child);
@ -504,7 +504,7 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
callLuaField("onStyleApply", styleNode->tag(), styleNode); callLuaField("onStyleApply", styleNode->tag(), styleNode);
if(m_firstOnStyle) { if(m_firstOnStyle) {
auto self = asUIWidget(); auto self = self_cast<UIWidget>();
g_dispatcher.addEvent([self] { g_dispatcher.addEvent([self] {
self->callLuaField("onSetup"); self->callLuaField("onSetup");
}); });
@ -525,7 +525,7 @@ void UIWidget::addAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedW
return; return;
if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout())
anchorLayout->addAnchor(asUIWidget(), anchoredEdge, hookedWidgetId, hookedEdge); anchorLayout->addAnchor(self_cast<UIWidget>(), anchoredEdge, hookedWidgetId, hookedEdge);
else else
g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id));
} }
@ -541,8 +541,8 @@ void UIWidget::centerIn(const std::string& hookedWidgetId)
return; return;
if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) { if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) {
anchorLayout->addAnchor(asUIWidget(), Fw::AnchorHorizontalCenter, hookedWidgetId, Fw::AnchorHorizontalCenter); anchorLayout->addAnchor(self_cast<UIWidget>(), Fw::AnchorHorizontalCenter, hookedWidgetId, Fw::AnchorHorizontalCenter);
anchorLayout->addAnchor(asUIWidget(), Fw::AnchorVerticalCenter, hookedWidgetId, Fw::AnchorVerticalCenter); anchorLayout->addAnchor(self_cast<UIWidget>(), Fw::AnchorVerticalCenter, hookedWidgetId, Fw::AnchorVerticalCenter);
} else } else
g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id));
} }
@ -553,10 +553,10 @@ void UIWidget::fill(const std::string& hookedWidgetId)
return; return;
if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) { if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) {
anchorLayout->addAnchor(asUIWidget(), Fw::AnchorLeft, hookedWidgetId, Fw::AnchorLeft); anchorLayout->addAnchor(self_cast<UIWidget>(), Fw::AnchorLeft, hookedWidgetId, Fw::AnchorLeft);
anchorLayout->addAnchor(asUIWidget(), Fw::AnchorRight, hookedWidgetId, Fw::AnchorRight); anchorLayout->addAnchor(self_cast<UIWidget>(), Fw::AnchorRight, hookedWidgetId, Fw::AnchorRight);
anchorLayout->addAnchor(asUIWidget(), Fw::AnchorTop, hookedWidgetId, Fw::AnchorTop); anchorLayout->addAnchor(self_cast<UIWidget>(), Fw::AnchorTop, hookedWidgetId, Fw::AnchorTop);
anchorLayout->addAnchor(asUIWidget(), Fw::AnchorBottom, hookedWidgetId, Fw::AnchorBottom); anchorLayout->addAnchor(self_cast<UIWidget>(), Fw::AnchorBottom, hookedWidgetId, Fw::AnchorBottom);
} else } else
g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); g_logger.error(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id));
} }
@ -567,7 +567,7 @@ void UIWidget::breakAnchors()
return; return;
if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout())
anchorLayout->removeAnchors(asUIWidget()); anchorLayout->removeAnchors(self_cast<UIWidget>());
} }
void UIWidget::updateParentLayout() void UIWidget::updateParentLayout()
@ -601,7 +601,7 @@ void UIWidget::lock()
return; return;
if(UIWidgetPtr parent = getParent()) if(UIWidgetPtr parent = getParent())
parent->lockChild(asUIWidget()); parent->lockChild(self_cast<UIWidget>());
} }
void UIWidget::unlock() void UIWidget::unlock()
@ -610,7 +610,7 @@ void UIWidget::unlock()
return; return;
if(UIWidgetPtr parent = getParent()) if(UIWidgetPtr parent = getParent())
parent->unlockChild(asUIWidget()); parent->unlockChild(self_cast<UIWidget>());
} }
void UIWidget::focus() void UIWidget::focus()
@ -622,7 +622,7 @@ void UIWidget::focus()
return; return;
if(UIWidgetPtr parent = getParent()) if(UIWidgetPtr parent = getParent())
parent->focusChild(asUIWidget(), Fw::ActiveFocusReason); parent->focusChild(self_cast<UIWidget>(), Fw::ActiveFocusReason);
} }
void UIWidget::recursiveFocus(Fw::FocusReason reason) void UIWidget::recursiveFocus(Fw::FocusReason reason)
@ -632,7 +632,7 @@ void UIWidget::recursiveFocus(Fw::FocusReason reason)
if(UIWidgetPtr parent = getParent()) { if(UIWidgetPtr parent = getParent()) {
if(m_focusable) if(m_focusable)
parent->focusChild(asUIWidget(), reason); parent->focusChild(self_cast<UIWidget>(), reason);
parent->recursiveFocus(reason); parent->recursiveFocus(reason);
} }
} }
@ -644,7 +644,7 @@ void UIWidget::lower()
UIWidgetPtr parent = getParent(); UIWidgetPtr parent = getParent();
if(parent) if(parent)
parent->lowerChild(asUIWidget()); parent->lowerChild(self_cast<UIWidget>());
} }
void UIWidget::raise() void UIWidget::raise()
@ -654,7 +654,7 @@ void UIWidget::raise()
UIWidgetPtr parent = getParent(); UIWidgetPtr parent = getParent();
if(parent) if(parent)
parent->raiseChild(asUIWidget()); parent->raiseChild(self_cast<UIWidget>());
} }
void UIWidget::grabMouse() void UIWidget::grabMouse()
@ -662,12 +662,12 @@ void UIWidget::grabMouse()
if(m_destroyed) if(m_destroyed)
return; return;
g_ui.setMouseReceiver(asUIWidget()); g_ui.setMouseReceiver(self_cast<UIWidget>());
} }
void UIWidget::ungrabMouse() void UIWidget::ungrabMouse()
{ {
if(g_ui.getMouseReceiver() == asUIWidget()) if(g_ui.getMouseReceiver() == self_cast<UIWidget>())
g_ui.resetMouseReceiver(); g_ui.resetMouseReceiver();
} }
@ -676,12 +676,12 @@ void UIWidget::grabKeyboard()
if(m_destroyed) if(m_destroyed)
return; return;
g_ui.setKeyboardReceiver(asUIWidget()); g_ui.setKeyboardReceiver(self_cast<UIWidget>());
} }
void UIWidget::ungrabKeyboard() void UIWidget::ungrabKeyboard()
{ {
if(g_ui.getKeyboardReceiver() == asUIWidget()) if(g_ui.getKeyboardReceiver() == self_cast<UIWidget>())
g_ui.resetKeyboardReceiver(); g_ui.resetKeyboardReceiver();
} }
@ -705,9 +705,12 @@ void UIWidget::internalDestroy()
m_destroyed = true; m_destroyed = true;
m_visible = false; m_visible = false;
m_enabled = false; m_enabled = false;
m_parent.reset();
m_focusedChild = nullptr; m_focusedChild = nullptr;
m_layout = nullptr; if(m_layout) {
m_layout->setParent(nullptr);
m_layout = nullptr;
}
m_parent = nullptr;
m_lockedChildren.clear(); m_lockedChildren.clear();
for(const UIWidgetPtr& child : m_children) for(const UIWidgetPtr& child : m_children)
@ -718,7 +721,7 @@ void UIWidget::internalDestroy()
releaseLuaFieldsTable(); releaseLuaFieldsTable();
g_ui.onWidgetDestroy(asUIWidget()); g_ui.onWidgetDestroy(self_cast<UIWidget>());
} }
void UIWidget::destroy() void UIWidget::destroy()
@ -727,7 +730,7 @@ void UIWidget::destroy()
g_logger.warning(stdext::format("attempt to destroy widget '%s' two times", m_id)); g_logger.warning(stdext::format("attempt to destroy widget '%s' two times", m_id));
// hold itself reference // hold itself reference
UIWidgetPtr self = asUIWidget(); UIWidgetPtr self = self_cast<UIWidget>();
m_destroyed = true; m_destroyed = true;
// remove itself from parent // remove itself from parent
@ -772,7 +775,7 @@ void UIWidget::setParent(const UIWidgetPtr& parent)
if(oldParent == parent) if(oldParent == parent)
return; return;
UIWidgetPtr self = asUIWidget(); UIWidgetPtr self = self_cast<UIWidget>();
if(oldParent && oldParent->hasChild(self)) if(oldParent && oldParent->hasChild(self))
oldParent->removeChild(self); oldParent->removeChild(self);
@ -794,7 +797,7 @@ void UIWidget::setLayout(const UILayoutPtr& layout)
if(m_layout) if(m_layout)
m_layout->disableUpdates(); m_layout->disableUpdates();
layout->setParent(asUIWidget()); layout->setParent(self_cast<UIWidget>());
layout->disableUpdates(); layout->disableUpdates();
for(const UIWidgetPtr& child : m_children) { for(const UIWidgetPtr& child : m_children) {
@ -833,7 +836,7 @@ bool UIWidget::setRect(const Rect& rect)
// avoid massive update events // avoid massive update events
if(!m_updateEventScheduled) { if(!m_updateEventScheduled) {
UIWidgetPtr self = asUIWidget(); UIWidgetPtr self = self_cast<UIWidget>();
g_dispatcher.addEvent([self, oldRect]() { g_dispatcher.addEvent([self, oldRect]() {
self->m_updateEventScheduled = false; self->m_updateEventScheduled = false;
if(oldRect != self->getRect()) if(oldRect != self->getRect())
@ -893,9 +896,9 @@ void UIWidget::setVisible(bool visible)
// visibility can change the current hovered widget // visibility can change the current hovered widget
if(visible) if(visible)
g_ui.onWidgetAppear(asUIWidget()); g_ui.onWidgetAppear(self_cast<UIWidget>());
else else
g_ui.onWidgetDisappear(asUIWidget()); g_ui.onWidgetDisappear(self_cast<UIWidget>());
callLuaField("onVisibilityChange", visible); callLuaField("onVisibilityChange", visible);
} }
@ -960,14 +963,14 @@ bool UIWidget::isVisible()
else if(UIWidgetPtr parent = getParent()) else if(UIWidgetPtr parent = getParent())
return parent->isVisible(); return parent->isVisible();
else else
return asUIWidget() == g_ui.getRootWidget(); return self_cast<UIWidget>() == g_ui.getRootWidget();
} }
bool UIWidget::isAnchored() bool UIWidget::isAnchored()
{ {
if(UIWidgetPtr parent = getParent()) if(UIWidgetPtr parent = getParent())
if(UIAnchorLayoutPtr anchorLayout = parent->getAnchoredLayout()) if(UIAnchorLayoutPtr anchorLayout = parent->getAnchoredLayout())
return anchorLayout->hasAnchors(asUIWidget()); return anchorLayout->hasAnchors(self_cast<UIWidget>());
return false; return false;
} }
@ -1041,7 +1044,10 @@ UIAnchorLayoutPtr UIWidget::getAnchoredLayout()
if(!parent) if(!parent)
return nullptr; return nullptr;
return parent->getLayout()->asUIAnchorLayout(); UILayoutPtr layout = parent->getLayout();
if(layout->isUIAnchorLayout())
return layout->self_cast<UIAnchorLayout>();
return nullptr;
} }
UIWidgetPtr UIWidget::getRootParent() UIWidgetPtr UIWidget::getRootParent()
@ -1049,7 +1055,7 @@ UIWidgetPtr UIWidget::getRootParent()
if(UIWidgetPtr parent = getParent()) if(UIWidgetPtr parent = getParent())
return parent->getRootParent(); return parent->getRootParent();
else else
return asUIWidget(); return self_cast<UIWidget>();
} }
UIWidgetPtr UIWidget::getChildAfter(const UIWidgetPtr& relativeChild) UIWidgetPtr UIWidget::getChildAfter(const UIWidgetPtr& relativeChild)
@ -1225,7 +1231,7 @@ void UIWidget::updateState(Fw::WidgetState state)
switch(state) { switch(state) {
case Fw::ActiveState: { case Fw::ActiveState: {
UIWidgetPtr widget = asUIWidget(); UIWidgetPtr widget = self_cast<UIWidget>();
UIWidgetPtr parent; UIWidgetPtr parent;
do { do {
parent = widget->getParent(); parent = widget->getParent();
@ -1240,24 +1246,24 @@ void UIWidget::updateState(Fw::WidgetState state)
break; break;
} }
case Fw::FocusState: { case Fw::FocusState: {
newStatus = (getParent() && getParent()->getFocusedChild() == asUIWidget()); newStatus = (getParent() && getParent()->getFocusedChild() == self_cast<UIWidget>());
break; break;
} }
case Fw::HoverState: { case Fw::HoverState: {
newStatus = (g_ui.getHoveredWidget() == asUIWidget() && isEnabled()); newStatus = (g_ui.getHoveredWidget() == self_cast<UIWidget>() && isEnabled());
break; break;
} }
case Fw::PressedState: { case Fw::PressedState: {
newStatus = (g_ui.getPressedWidget() == asUIWidget()); newStatus = (g_ui.getPressedWidget() == self_cast<UIWidget>());
break; break;
} }
case Fw::DraggingState: { case Fw::DraggingState: {
newStatus = (g_ui.getDraggingWidget() == asUIWidget()); newStatus = (g_ui.getDraggingWidget() == self_cast<UIWidget>());
break; break;
} }
case Fw::DisabledState: { case Fw::DisabledState: {
bool enabled = true; bool enabled = true;
UIWidgetPtr widget = asUIWidget(); UIWidgetPtr widget = self_cast<UIWidget>();
do { do {
if(!widget->isExplicitlyEnabled()) { if(!widget->isExplicitlyEnabled()) {
enabled = false; enabled = false;
@ -1269,19 +1275,19 @@ void UIWidget::updateState(Fw::WidgetState state)
break; break;
} }
case Fw::FirstState: { case Fw::FirstState: {
newStatus = (getParent() && getParent()->getFirstChild() == asUIWidget()); newStatus = (getParent() && getParent()->getFirstChild() == self_cast<UIWidget>());
break; break;
} }
case Fw::MiddleState: { case Fw::MiddleState: {
newStatus = (getParent() && getParent()->getFirstChild() != asUIWidget() && getParent()->getLastChild() != asUIWidget()); newStatus = (getParent() && getParent()->getFirstChild() != self_cast<UIWidget>() && getParent()->getLastChild() != self_cast<UIWidget>());
break; break;
} }
case Fw::LastState: { case Fw::LastState: {
newStatus = (getParent() && getParent()->getLastChild() == asUIWidget()); newStatus = (getParent() && getParent()->getLastChild() == self_cast<UIWidget>());
break; break;
} }
case Fw::AlternateState: { case Fw::AlternateState: {
newStatus = (getParent() && (getParent()->getChildIndex(asUIWidget()) % 2) == 1); newStatus = (getParent() && (getParent()->getChildIndex(self_cast<UIWidget>()) % 2) == 1);
break; break;
} }
default: default:
@ -1331,7 +1337,7 @@ void UIWidget::updateStyle()
return; return;
if(m_loadingStyle && !m_updateStyleScheduled) { if(m_loadingStyle && !m_updateStyleScheduled) {
UIWidgetPtr self = asUIWidget(); UIWidgetPtr self = self_cast<UIWidget>();
g_dispatcher.addEvent([self] { g_dispatcher.addEvent([self] {
self->m_updateStyleScheduled = false; self->m_updateStyleScheduled = false;
self->updateStyle(); self->updateStyle();
@ -1636,7 +1642,7 @@ bool UIWidget::propagateOnMouseEvent(const Point& mousePos, UIWidgetList& widget
} }
} }
widgetList.push_back(asUIWidget()); widgetList.push_back(self_cast<UIWidget>());
if(!isPhantom()) if(!isPhantom())
ret = true; ret = true;
@ -1651,6 +1657,6 @@ bool UIWidget::propagateOnMouseMove(const Point& mousePos, const Point& mouseMov
child->propagateOnMouseMove(mousePos, mouseMoved, widgetList); child->propagateOnMouseMove(mousePos, mouseMoved, widgetList);
} }
widgetList.push_back(asUIWidget()); widgetList.push_back(self_cast<UIWidget>());
return true; return true;
} }

@ -24,6 +24,8 @@
#define UIWIDGET_H #define UIWIDGET_H
#include "declarations.h" #include "declarations.h"
#include "uilayout.h"
#include <framework/luaengine/luaobject.h> #include <framework/luaengine/luaobject.h>
#include <framework/graphics/declarations.h> #include <framework/graphics/declarations.h>
#include <framework/otml/otmlnode.h> #include <framework/otml/otmlnode.h>
@ -68,7 +70,7 @@ protected:
Boolean<false> m_destroyed; Boolean<false> m_destroyed;
Boolean<false> m_clipping; Boolean<false> m_clipping;
UILayoutPtr m_layout; UILayoutPtr m_layout;
UIWidgetWeakPtr m_parent; UIWidgetPtr m_parent;
UIWidgetList m_children; UIWidgetList m_children;
UIWidgetList m_lockedChildren; UIWidgetList m_lockedChildren;
UIWidgetPtr m_focusedChild; UIWidgetPtr m_focusedChild;
@ -152,8 +154,6 @@ public:
UIWidgetList recursiveGetChildrenByMarginPos(const Point& childPos); UIWidgetList recursiveGetChildrenByMarginPos(const Point& childPos);
UIWidgetPtr backwardsGetWidgetById(const std::string& id); UIWidgetPtr backwardsGetWidgetById(const std::string& id);
UIWidgetPtr asUIWidget() { return std::static_pointer_cast<UIWidget>(shared_from_this()); }
private: private:
Boolean<false> m_updateEventScheduled; Boolean<false> m_updateEventScheduled;
Boolean<false> m_loadingStyle; Boolean<false> m_loadingStyle;
@ -248,7 +248,7 @@ public:
bool containsPoint(const Point& point) { return m_rect.contains(point); } bool containsPoint(const Point& point) { return m_rect.contains(point); }
std::string getId() { return m_id; } std::string getId() { return m_id; }
UIWidgetPtr getParent() { return m_parent.lock(); } UIWidgetPtr getParent() { return m_parent; }
UIWidgetPtr getFocusedChild() { return m_focusedChild; } UIWidgetPtr getFocusedChild() { return m_focusedChild; }
UIWidgetList getChildren() { return m_children; } UIWidgetList getChildren() { return m_children; }
UIWidgetPtr getFirstChild() { return getChildByIndex(1); } UIWidgetPtr getFirstChild() { return getChildByIndex(1); }

@ -243,13 +243,13 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
if(!layoutType.empty()) { if(!layoutType.empty()) {
UILayoutPtr layout; UILayoutPtr layout;
if(layoutType == "horizontalBox") if(layoutType == "horizontalBox")
layout = UIHorizontalLayoutPtr(new UIHorizontalLayout(asUIWidget())); layout = UIHorizontalLayoutPtr(new UIHorizontalLayout(self_cast<UIWidget>()));
else if(layoutType == "verticalBox") else if(layoutType == "verticalBox")
layout = UIVerticalLayoutPtr(new UIVerticalLayout(asUIWidget())); layout = UIVerticalLayoutPtr(new UIVerticalLayout(self_cast<UIWidget>()));
else if(layoutType == "grid") else if(layoutType == "grid")
layout = UIGridLayoutPtr(new UIGridLayout(asUIWidget())); layout = UIGridLayoutPtr(new UIGridLayout(self_cast<UIWidget>()));
else if(layoutType == "anchor") else if(layoutType == "anchor")
layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget())); layout = UIAnchorLayoutPtr(new UIAnchorLayout(self_cast<UIWidget>()));
else else
throw OTMLException(node, "cannot determine layout type"); throw OTMLException(node, "cannot determine layout type");
setLayout(layout); setLayout(layout);
@ -268,7 +268,11 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
continue; continue;
} }
UIAnchorLayoutPtr anchorLayout = parent->getLayout()->asUIAnchorLayout(); UILayoutPtr layout = parent->getLayout();
UIAnchorLayoutPtr anchorLayout;
if(layout->isUIAnchorLayout())
anchorLayout = layout->self_cast<UIAnchorLayout>();
if(!anchorLayout) if(!anchorLayout)
throw OTMLException(node, "cannot create anchor, the parent widget doesn't use anchor layout!"); throw OTMLException(node, "cannot create anchor, the parent widget doesn't use anchor layout!");

@ -25,11 +25,6 @@
#include <framework/luaengine/luainterface.h> #include <framework/luaengine/luainterface.h>
#include <otclient/otclient.h> #include <otclient/otclient.h>
#include <framework/core/binarytree.h>
#include <otclient/item.h>
#include <otclient/tile.h>
#include <boost/any.hpp>
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
std::vector<std::string> args(argv, argv + argc); std::vector<std::string> args(argv, argv + argc);

@ -40,7 +40,7 @@ public:
void setColor(int color); void setColor(int color);
void setText(const std::string& text); void setText(const std::string& text);
AnimatedTextPtr asAnimatedText() { return std::static_pointer_cast<AnimatedText>(shared_from_this()); } AnimatedTextPtr asAnimatedText() { return self_cast<AnimatedText>(); }
bool isAnimatedText() { return true; } bool isAnimatedText() { return true; }
private: private:

@ -353,9 +353,9 @@ void Creature::updateWalkingTile()
if(newWalkingTile != m_walkingTile) { if(newWalkingTile != m_walkingTile) {
if(m_walkingTile) if(m_walkingTile)
m_walkingTile->removeWalkingCreature(asCreature()); m_walkingTile->removeWalkingCreature(self_cast<Creature>());
if(newWalkingTile) if(newWalkingTile)
newWalkingTile->addWalkingCreature(asCreature()); newWalkingTile->addWalkingCreature(self_cast<Creature>());
m_walkingTile = newWalkingTile; m_walkingTile = newWalkingTile;
} }
} }
@ -371,7 +371,7 @@ void Creature::nextWalkUpdate()
// schedules next update // schedules next update
if(m_walking) { if(m_walking) {
auto self = asCreature(); auto self = self_cast<Creature>();
m_walkUpdateEvent = g_dispatcher.scheduleEvent([self] { m_walkUpdateEvent = g_dispatcher.scheduleEvent([self] {
self->m_walkUpdateEvent = nullptr; self->m_walkUpdateEvent = nullptr;
self->nextWalkUpdate(); self->nextWalkUpdate();
@ -409,7 +409,7 @@ void Creature::terminateWalk()
} }
if(m_walkingTile) { if(m_walkingTile) {
m_walkingTile->removeWalkingCreature(asCreature()); m_walkingTile->removeWalkingCreature(self_cast<Creature>());
m_walkingTile = nullptr; m_walkingTile = nullptr;
} }
@ -496,7 +496,7 @@ void Creature::setShieldTexture(const std::string& filename, bool blink)
m_showShieldTexture = true; m_showShieldTexture = true;
if(blink && !m_shieldBlink) { if(blink && !m_shieldBlink) {
auto self = asCreature(); auto self = self_cast<Creature>();
g_dispatcher.scheduleEvent([self]() { g_dispatcher.scheduleEvent([self]() {
self->updateShield(); self->updateShield();
}, SHIELD_BLINK_TICKS); }, SHIELD_BLINK_TICKS);
@ -516,7 +516,7 @@ void Creature::addTimedSquare(uint8 color)
m_timedSquareColor = Color::from8bit(color); m_timedSquareColor = Color::from8bit(color);
// schedule removal // schedule removal
auto self = asCreature(); auto self = self_cast<Creature>();
g_dispatcher.scheduleEvent([self]() { g_dispatcher.scheduleEvent([self]() {
self->removeTimedSquare(); self->removeTimedSquare();
}, VOLATILE_SQUARE_DURATION); }, VOLATILE_SQUARE_DURATION);
@ -527,7 +527,7 @@ void Creature::updateShield()
m_showShieldTexture = !m_showShieldTexture; m_showShieldTexture = !m_showShieldTexture;
if(m_shield != Otc::ShieldNone && m_shieldBlink) { if(m_shield != Otc::ShieldNone && m_shieldBlink) {
auto self = asCreature(); auto self = self_cast<Creature>();
g_dispatcher.scheduleEvent([self]() { g_dispatcher.scheduleEvent([self]() {
self->updateShield(); self->updateShield();
}, SHIELD_BLINK_TICKS); }, SHIELD_BLINK_TICKS);

@ -25,6 +25,8 @@
#include "thing.h" #include "thing.h"
#include "outfit.h" #include "outfit.h"
#include "tile.h"
#include <framework/core/scheduledevent.h>
#include <framework/core/declarations.h> #include <framework/core/declarations.h>
#include <framework/core/timer.h> #include <framework/core/timer.h>
#include <framework/graphics/fontmanager.h> #include <framework/graphics/fontmanager.h>
@ -93,7 +95,6 @@ public:
bool isWalking() { return m_walking; } bool isWalking() { return m_walking; }
bool isRemoved() { return m_removed; } bool isRemoved() { return m_removed; }
CreaturePtr asCreature() { return std::static_pointer_cast<Creature>(shared_from_this()); }
bool isCreature() { return true; } bool isCreature() { return true; }
const ThingTypePtr& getThingType(); const ThingTypePtr& getThingType();
@ -150,7 +151,6 @@ protected:
class Npc : public Creature class Npc : public Creature
{ {
public: public:
NpcPtr asNpc() { return std::static_pointer_cast<Npc>(shared_from_this()); }
bool isNpc() { return true; } bool isNpc() { return true; }
}; };
@ -158,7 +158,6 @@ public:
class Monster : public Creature class Monster : public Creature
{ {
public: public:
MonsterPtr asMonster() { return std::static_pointer_cast<Monster>(shared_from_this()); }
bool isMonster() { return true; } bool isMonster() { return true; }
}; };

@ -50,25 +50,25 @@ class House;
class Town; class Town;
class CreatureType; class CreatureType;
typedef std::shared_ptr<MapView> MapViewPtr; typedef stdext::shared_object_ptr<MapView> MapViewPtr;
typedef std::shared_ptr<Tile> TilePtr; typedef stdext::shared_object_ptr<Tile> TilePtr;
typedef std::shared_ptr<Thing> ThingPtr; typedef stdext::shared_object_ptr<Thing> ThingPtr;
typedef std::shared_ptr<Item> ItemPtr; typedef stdext::shared_object_ptr<Item> ItemPtr;
typedef std::shared_ptr<Container> ContainerPtr; typedef stdext::shared_object_ptr<Container> ContainerPtr;
typedef std::shared_ptr<Creature> CreaturePtr; typedef stdext::shared_object_ptr<Creature> CreaturePtr;
typedef std::shared_ptr<Monster> MonsterPtr; typedef stdext::shared_object_ptr<Monster> MonsterPtr;
typedef std::shared_ptr<Npc> NpcPtr; typedef stdext::shared_object_ptr<Npc> NpcPtr;
typedef std::shared_ptr<Player> PlayerPtr; typedef stdext::shared_object_ptr<Player> PlayerPtr;
typedef std::shared_ptr<LocalPlayer> LocalPlayerPtr; typedef stdext::shared_object_ptr<LocalPlayer> LocalPlayerPtr;
typedef std::shared_ptr<Effect> EffectPtr; typedef stdext::shared_object_ptr<Effect> EffectPtr;
typedef std::shared_ptr<Missile> MissilePtr; typedef stdext::shared_object_ptr<Missile> MissilePtr;
typedef std::shared_ptr<AnimatedText> AnimatedTextPtr; typedef stdext::shared_object_ptr<AnimatedText> AnimatedTextPtr;
typedef std::shared_ptr<StaticText> StaticTextPtr; typedef stdext::shared_object_ptr<StaticText> StaticTextPtr;
typedef std::shared_ptr<ThingType> ThingTypePtr; typedef stdext::shared_object_ptr<ThingType> ThingTypePtr;
typedef std::shared_ptr<ItemType> ItemTypePtr; typedef stdext::shared_object_ptr<ItemType> ItemTypePtr;
typedef std::shared_ptr<House> HousePtr; typedef stdext::shared_object_ptr<House> HousePtr;
typedef std::shared_ptr<Town> TownPtr; typedef stdext::shared_object_ptr<Town> TownPtr;
typedef std::shared_ptr<CreatureType> CreatureTypePtr; typedef stdext::shared_object_ptr<CreatureType> CreatureTypePtr;
typedef std::vector<ThingPtr> ThingList; typedef std::vector<ThingPtr> ThingList;
typedef std::vector<ThingTypePtr> ThingTypeList; typedef std::vector<ThingTypePtr> ThingTypeList;
@ -81,8 +81,8 @@ typedef std::unordered_map<Position, TilePtr, PositionHasher> TileMap;
class ProtocolLogin; class ProtocolLogin;
class ProtocolGame; class ProtocolGame;
typedef std::shared_ptr<ProtocolGame> ProtocolGamePtr; typedef stdext::shared_object_ptr<ProtocolGame> ProtocolGamePtr;
typedef std::shared_ptr<ProtocolLogin> ProtocolLoginPtr; typedef stdext::shared_object_ptr<ProtocolLogin> ProtocolLoginPtr;
// ui // ui
class UIItem; class UIItem;
@ -90,9 +90,9 @@ class UICreature;
class UIMap; class UIMap;
class UIProgressRect; class UIProgressRect;
typedef std::shared_ptr<UIItem> UIItemPtr; typedef stdext::shared_object_ptr<UIItem> UIItemPtr;
typedef std::shared_ptr<UICreature> UICreaturePtr; typedef stdext::shared_object_ptr<UICreature> UICreaturePtr;
typedef std::shared_ptr<UIMap> UIMapPtr; typedef stdext::shared_object_ptr<UIMap> UIMapPtr;
typedef std::shared_ptr<UIProgressRect> UIProgressRectPtr; typedef stdext::shared_object_ptr<UIProgressRect> UIProgressRectPtr;
#endif #endif

@ -41,7 +41,7 @@ public:
uint32 getId() { return m_id; } uint32 getId() { return m_id; }
EffectPtr asEffect() { return std::static_pointer_cast<Effect>(shared_from_this()); } EffectPtr asEffect() { return self_cast<Effect>(); }
bool isEffect() { return true; } bool isEffect() { return true; }
const ThingTypePtr& getThingType(); const ThingTypePtr& getThingType();

@ -659,8 +659,8 @@ void Game::useWith(const ItemPtr& item, const ThingPtr& toThing)
m_localPlayer->lockWalk(); m_localPlayer->lockWalk();
if(CreaturePtr creature = toThing->asCreature()) if(toThing->isCreature())
m_protocolGame->sendUseOnCreature(pos, item->getId(), item->getStackpos(), creature->getId()); m_protocolGame->sendUseOnCreature(pos, item->getId(), item->getStackpos(), toThing->getId());
else else
m_protocolGame->sendUseItemWith(pos, item->getId(), item->getStackpos(), toThing->getPosition(), toThing->getId(), toThing->getStackpos()); m_protocolGame->sendUseItemWith(pos, item->getId(), item->getStackpos(), toThing->getPosition(), toThing->getId(), toThing->getStackpos());
} }
@ -674,8 +674,8 @@ void Game::useInventoryItemWith(int itemId, const ThingPtr& toThing)
Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory
if(CreaturePtr creature = toThing->asCreature()) if(toThing->isCreature())
m_protocolGame->sendUseOnCreature(pos, itemId, 0, creature->getId()); m_protocolGame->sendUseOnCreature(pos, itemId, 0, toThing->getId());
else else
m_protocolGame->sendUseItemWith(pos, itemId, 0, toThing->getPosition(), toThing->getId(), toThing->getStackpos()); m_protocolGame->sendUseItemWith(pos, itemId, 0, toThing->getPosition(), toThing->getId(), toThing->getStackpos());
} }

@ -25,6 +25,10 @@
#include "declarations.h" #include "declarations.h"
#include "item.h" #include "item.h"
#include "creature.h"
#include "container.h"
#include "protocolgame.h"
#include "localplayer.h"
#include "outfit.h" #include "outfit.h"
#include <framework/core/timer.h> #include <framework/core/timer.h>

@ -115,7 +115,7 @@ public:
bool isTeleport() { return m_attribs.has(ATTR_TELE_DEST); } bool isTeleport() { return m_attribs.has(ATTR_TELE_DEST); }
bool isMoveable(); bool isMoveable();
ItemPtr asItem() { return std::static_pointer_cast<Item>(shared_from_this()); } ItemPtr asItem() { return self_cast<Item>(); }
bool isItem() { return true; } bool isItem() { return true; }
const ThingTypePtr& getThingType(); const ThingTypePtr& getThingType();

@ -78,7 +78,7 @@ public:
bool isAutoWalking() { return m_autoWalking; } bool isAutoWalking() { return m_autoWalking; }
bool isPremium() { return m_premium; } bool isPremium() { return m_premium; }
LocalPlayerPtr asLocalPlayer() { return std::static_pointer_cast<LocalPlayer>(shared_from_this()); } LocalPlayerPtr asLocalPlayer() { return self_cast<LocalPlayer>(); }
bool isLocalPlayer() { return true; } bool isLocalPlayer() { return true; }
protected: protected:

@ -248,15 +248,6 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<Thing>("getPosition", &Thing::getPosition); g_lua.bindClassMemberFunction<Thing>("getPosition", &Thing::getPosition);
g_lua.bindClassMemberFunction<Thing>("getStackPriority", &Thing::getStackPriority); g_lua.bindClassMemberFunction<Thing>("getStackPriority", &Thing::getStackPriority);
g_lua.bindClassMemberFunction<Thing>("getAnimationPhases", &Thing::getAnimationPhases); g_lua.bindClassMemberFunction<Thing>("getAnimationPhases", &Thing::getAnimationPhases);
g_lua.bindClassMemberFunction<Thing>("asThing", &Thing::asThing);
g_lua.bindClassMemberFunction<Thing>("asItem", &Thing::asItem);
g_lua.bindClassMemberFunction<Thing>("asCreature", &Thing::asCreature);
g_lua.bindClassMemberFunction<Thing>("asEffect", &Thing::asEffect);
g_lua.bindClassMemberFunction<Thing>("asMissile", &Thing::asMissile);
g_lua.bindClassMemberFunction<Thing>("asPlayer", &Thing::asPlayer);
g_lua.bindClassMemberFunction<Thing>("asLocalPlayer", &Thing::asLocalPlayer);
g_lua.bindClassMemberFunction<Thing>("asAnimatedText", &Thing::asAnimatedText);
g_lua.bindClassMemberFunction<Thing>("asStaticText", &Thing::asStaticText);
g_lua.bindClassMemberFunction<Thing>("isItem", &Thing::isItem); g_lua.bindClassMemberFunction<Thing>("isItem", &Thing::isItem);
g_lua.bindClassMemberFunction<Thing>("isCreature", &Thing::isCreature); g_lua.bindClassMemberFunction<Thing>("isCreature", &Thing::isCreature);
g_lua.bindClassMemberFunction<Thing>("isEffect", &Thing::isEffect); g_lua.bindClassMemberFunction<Thing>("isEffect", &Thing::isEffect);
@ -331,8 +322,6 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<Creature>("showStaticSquare", &Creature::showStaticSquare); g_lua.bindClassMemberFunction<Creature>("showStaticSquare", &Creature::showStaticSquare);
g_lua.bindClassMemberFunction<Creature>("hideStaticSquare", &Creature::hideStaticSquare); g_lua.bindClassMemberFunction<Creature>("hideStaticSquare", &Creature::hideStaticSquare);
g_lua.bindClassMemberFunction<Creature>("isWalking", &Creature::isWalking); g_lua.bindClassMemberFunction<Creature>("isWalking", &Creature::isWalking);
g_lua.bindClassMemberFunction<Creature>("asMonster", &Creature::asMonster);
g_lua.bindClassMemberFunction<Creature>("asNpc", &Creature::asNpc);
g_lua.registerClass<ItemType>(); g_lua.registerClass<ItemType>();
g_lua.bindClassMemberFunction<ItemType>("getServerId", &ItemType::getServerId); g_lua.bindClassMemberFunction<ItemType>("getServerId", &ItemType::getServerId);
@ -398,7 +387,6 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<LocalPlayer>("isPremium", &LocalPlayer::isPremium); g_lua.bindClassMemberFunction<LocalPlayer>("isPremium", &LocalPlayer::isPremium);
g_lua.bindClassMemberFunction<LocalPlayer>("isKnown", &LocalPlayer::isKnown); g_lua.bindClassMemberFunction<LocalPlayer>("isKnown", &LocalPlayer::isKnown);
g_lua.bindClassMemberFunction<LocalPlayer>("isPreWalking", &LocalPlayer::isPreWalking); g_lua.bindClassMemberFunction<LocalPlayer>("isPreWalking", &LocalPlayer::isPreWalking);
g_lua.bindClassMemberFunction<LocalPlayer>("asLocalPlayer", &LocalPlayer::asLocalPlayer);
g_lua.registerClass<Tile>(); g_lua.registerClass<Tile>();
g_lua.bindClassMemberFunction<Tile>("clean", &Tile::clean); g_lua.bindClassMemberFunction<Tile>("clean", &Tile::clean);

@ -543,7 +543,9 @@ void Map::saveOtcm(const std::string& fileName)
const auto& list = tile->getThings(); const auto& list = tile->getThings();
auto first = std::find_if(list.begin(), list.end(), [](const ThingPtr& thing) { return thing->isItem(); }); auto first = std::find_if(list.begin(), list.end(), [](const ThingPtr& thing) { return thing->isItem(); });
for(auto it = first, end = list.end(); it != end; ++it) { for(auto it = first, end = list.end(); it != end; ++it) {
if(ItemPtr item = (*it)->asItem()) { const ThingPtr& thing = *it;
if(thing->isItem()) {
ItemPtr item = thing->self_cast<Item>();
fin->addU16(item->getId()); fin->addU16(item->getId());
fin->addU8(item->getCountOrSubType()); fin->addU8(item->getCountOrSubType());
} }
@ -611,11 +613,11 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
if(thing->isItem() || thing->isCreature() || thing->isEffect()) { if(thing->isItem() || thing->isCreature() || thing->isEffect()) {
tile->addThing(thing, stackPos); tile->addThing(thing, stackPos);
} else if(thing->isMissile()) { } else if(thing->isMissile()) {
m_floorMissiles[pos.z].push_back(thing->asMissile()); m_floorMissiles[pos.z].push_back(thing->self_cast<Missile>());
} else if(thing->isAnimatedText()) { } else if(thing->isAnimatedText()) {
m_animatedTexts.push_back(thing->asAnimatedText()); m_animatedTexts.push_back(thing->self_cast<AnimatedText>());
} else if(thing->isStaticText()) { } else if(thing->isStaticText()) {
StaticTextPtr staticText = thing->asStaticText(); StaticTextPtr staticText = thing->self_cast<StaticText>();
bool mustAdd = true; bool mustAdd = true;
for(auto it = m_staticTexts.begin(), end = m_staticTexts.end(); it != end; ++it) { for(auto it = m_staticTexts.begin(), end = m_staticTexts.end(); it != end; ++it) {
StaticTextPtr cStaticText = *it; StaticTextPtr cStaticText = *it;
@ -639,7 +641,7 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
thing->setPosition(pos); thing->setPosition(pos);
if(thing->isCreature()) { if(thing->isCreature()) {
CreaturePtr creature = thing->asCreature(); CreaturePtr creature = thing->self_cast<Creature>();
if(oldPos != pos) { if(oldPos != pos) {
if(oldPos.isInRange(pos,1,1)) if(oldPos.isInRange(pos,1,1))
g_game.processCreatureMove(creature, oldPos, pos); g_game.processCreatureMove(creature, oldPos, pos);
@ -665,20 +667,23 @@ bool Map::removeThing(const ThingPtr& thing)
notificateTileUpdateToMapViews(thing->getPosition()); notificateTileUpdateToMapViews(thing->getPosition());
if(MissilePtr missile = thing->asMissile()) { if(thing->isMissile()) {
MissilePtr missile = thing->self_cast<Missile>();
int z = missile->getPosition().z; int z = missile->getPosition().z;
auto it = std::find(m_floorMissiles[z].begin(), m_floorMissiles[z].end(), missile); auto it = std::find(m_floorMissiles[z].begin(), m_floorMissiles[z].end(), missile);
if(it != m_floorMissiles[z].end()) { if(it != m_floorMissiles[z].end()) {
m_floorMissiles[z].erase(it); m_floorMissiles[z].erase(it);
return true; return true;
} }
} else if(AnimatedTextPtr animatedText = thing->asAnimatedText()) { } else if(thing->isAnimatedText()) {
AnimatedTextPtr animatedText = thing->self_cast<AnimatedText>();
auto it = std::find(m_animatedTexts.begin(), m_animatedTexts.end(), animatedText); auto it = std::find(m_animatedTexts.begin(), m_animatedTexts.end(), animatedText);
if(it != m_animatedTexts.end()) { if(it != m_animatedTexts.end()) {
m_animatedTexts.erase(it); m_animatedTexts.erase(it);
return true; return true;
} }
} else if(StaticTextPtr staticText = thing->asStaticText()) { } else if(thing->isStaticText()) {
StaticTextPtr staticText = thing->self_cast<StaticText>();
auto it = std::find(m_staticTexts.begin(), m_staticTexts.end(), staticText); auto it = std::find(m_staticTexts.begin(), m_staticTexts.end(), staticText);
if(it != m_staticTexts.end()) { if(it != m_staticTexts.end()) {
m_staticTexts.erase(it); m_staticTexts.erase(it);

@ -28,6 +28,7 @@
#include "towns.h" #include "towns.h"
#include "creatures.h" #include "creatures.h"
#include "animatedtext.h" #include "animatedtext.h"
#include "statictext.h"
#include <framework/core/clock.h> #include <framework/core/clock.h>
#include <framework/util/attribstorage.h> #include <framework/util/attribstorage.h>

@ -24,6 +24,7 @@
#define MAPVIEW_H #define MAPVIEW_H
#include "declarations.h" #include "declarations.h"
#include <framework/graphics/paintershaderprogram.h>
#include <framework/graphics/declarations.h> #include <framework/graphics/declarations.h>
#include <framework/luaengine/luaobject.h> #include <framework/luaengine/luaobject.h>
#include <framework/core/declarations.h> #include <framework/core/declarations.h>
@ -113,7 +114,7 @@ public:
// get tile // get tile
TilePtr getTile(const Point& mousePos, const Rect& mapRect); TilePtr getTile(const Point& mousePos, const Rect& mapRect);
MapViewPtr asMapView() { return std::static_pointer_cast<MapView>(shared_from_this()); } MapViewPtr asMapView() { return self_cast<MapView>(); }
private: private:
int calcFirstVisibleFloor(); int calcFirstVisibleFloor();

@ -42,7 +42,7 @@ public:
uint32 getId() { return m_id; } uint32 getId() { return m_id; }
MissilePtr asMissile() { return std::static_pointer_cast<Missile>(shared_from_this()); } MissilePtr asMissile() { return self_cast<Missile>(); }
bool isMissile() { return true; } bool isMissile() { return true; }
const ThingTypePtr& getThingType(); const ThingTypePtr& getThingType();

@ -32,7 +32,7 @@ public:
Player() { } Player() { }
virtual ~Player() { } virtual ~Player() { }
PlayerPtr asPlayer() { return std::static_pointer_cast<Player>(shared_from_this()); } PlayerPtr asPlayer() { return self_cast<Player>(); }
bool isPlayer() { return true; } bool isPlayer() { return true; }
}; };

@ -43,7 +43,7 @@ public:
bool addMessage(const std::string& name, Otc::MessageMode mode, const std::string& text); bool addMessage(const std::string& name, Otc::MessageMode mode, const std::string& text);
StaticTextPtr asStaticText() { return std::static_pointer_cast<StaticText>(shared_from_this()); } StaticTextPtr asStaticText() { return self_cast<StaticText>(); }
bool isStaticText() { return true; } bool isStaticText() { return true; }
private: private:

@ -43,7 +43,7 @@ int Thing::getStackPriority()
return 2; return 2;
else if(isOnTop()) else if(isOnTop())
return 3; return 3;
else if(asCreature()) else if(isCreature())
return 4; return 4;
else // common items else // common items
return 5; return 5;
@ -65,10 +65,10 @@ ContainerPtr Thing::getParentContainer()
int Thing::getStackpos() int Thing::getStackpos()
{ {
if(m_position.x == 65535 && asItem()) // is inside a container if(m_position.x == 65535 && isItem()) // is inside a container
return m_position.z; return m_position.z;
else if(const TilePtr& tile = getTile()) else if(const TilePtr& tile = getTile())
return tile->getThingStackpos(asThing()); return tile->getThingStackpos(self_cast<Thing>());
else { else {
g_logger.traceError("got a thing with invalid stackpos"); g_logger.traceError("got a thing with invalid stackpos");
return -1; return -1;

@ -49,18 +49,6 @@ public:
ContainerPtr getParentContainer(); ContainerPtr getParentContainer();
int getStackpos(); int getStackpos();
ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); }
virtual ItemPtr asItem() { return nullptr; }
virtual EffectPtr asEffect() { return nullptr; }
virtual MissilePtr asMissile() { return nullptr; }
virtual CreaturePtr asCreature() { return nullptr; }
virtual NpcPtr asNpc() { return nullptr; }
virtual MonsterPtr asMonster() { return nullptr; }
virtual PlayerPtr asPlayer() { return nullptr; }
virtual LocalPlayerPtr asLocalPlayer() { return nullptr; }
virtual AnimatedTextPtr asAnimatedText() { return nullptr; }
virtual StaticTextPtr asStaticText() { return nullptr; }
virtual bool isItem() { return false; } virtual bool isItem() { return false; }
virtual bool isEffect() { return false; } virtual bool isEffect() { return false; }
virtual bool isMissile() { return false; } virtual bool isMissile() { return false; }

@ -113,7 +113,7 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
const ThingPtr& thing = *it; const ThingPtr& thing = *it;
if(!thing->isCreature()) if(!thing->isCreature())
continue; continue;
CreaturePtr creature = thing->asCreature(); CreaturePtr creature = thing->self_cast<Creature>();
if(creature && (!creature->isWalking() || !animate)) if(creature && (!creature->isWalking() || !animate))
creature->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate); creature->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate);
} }
@ -158,7 +158,7 @@ void Tile::addThing(const ThingPtr& thing, int stackPos)
return; return;
if(thing->isEffect()) { if(thing->isEffect()) {
m_effects.push_back(thing->asEffect()); m_effects.push_back(thing->self_cast<Effect>());
return; return;
} }
@ -204,7 +204,8 @@ bool Tile::removeThing(ThingPtr thing)
bool removed = false; bool removed = false;
if(EffectPtr effect = thing->asEffect()) { if(thing->isEffect()) {
EffectPtr effect = thing->self_cast<Effect>();
auto it = std::find(m_effects.begin(), m_effects.end(), effect); auto it = std::find(m_effects.begin(), m_effects.end(), effect);
if(it != m_effects.end()) { if(it != m_effects.end()) {
m_effects.erase(it); m_effects.erase(it);
@ -264,8 +265,10 @@ std::vector<ItemPtr> Tile::getItems()
{ {
std::vector<ItemPtr> items; std::vector<ItemPtr> items;
for(const ThingPtr& thing : m_things) { for(const ThingPtr& thing : m_things) {
if(ItemPtr item = thing->asItem()) if(!thing->isItem())
items.push_back(item); continue;
ItemPtr item = thing->self_cast<Item>();
items.push_back(item);
} }
return items; return items;
} }
@ -274,8 +277,8 @@ std::vector<CreaturePtr> Tile::getCreatures()
{ {
std::vector<CreaturePtr> creatures; std::vector<CreaturePtr> creatures;
for(const ThingPtr& thing : m_things) { for(const ThingPtr& thing : m_things) {
if(CreaturePtr creature = thing->asCreature()) if(thing->isCreature())
creatures.push_back(creature); creatures.push_back(thing->self_cast<Creature>());
} }
return creatures; return creatures;
} }
@ -285,8 +288,8 @@ ItemPtr Tile::getGround()
ThingPtr firstObject = getThing(0); ThingPtr firstObject = getThing(0);
if(!firstObject) if(!firstObject)
return nullptr; return nullptr;
if(firstObject->isGround()) if(firstObject->isGround() && firstObject->isItem())
return firstObject->asItem(); return firstObject->self_cast<Item>();
return nullptr; return nullptr;
} }
@ -344,10 +347,10 @@ CreaturePtr Tile::getTopCreature()
CreaturePtr creature; CreaturePtr creature;
for(uint i = 0; i < m_things.size(); ++i) { for(uint i = 0; i < m_things.size(); ++i) {
ThingPtr thing = m_things[i]; ThingPtr thing = m_things[i];
if(thing->asLocalPlayer()) // return local player if there is no other creature if(thing->isLocalPlayer()) // return local player if there is no other creature
creature = thing->asCreature(); creature = thing->self_cast<Creature>();
else if(thing->isCreature() && !thing->isLocalPlayer()) else if(thing->isCreature() && !thing->isLocalPlayer())
return thing->asCreature(); return thing->self_cast<Creature>();
} }
if(!creature && !m_walkingCreatures.empty()) if(!creature && !m_walkingCreatures.empty())
creature = m_walkingCreatures.back(); creature = m_walkingCreatures.back();
@ -404,7 +407,8 @@ bool Tile::isWalkable()
if(thing->isNotWalkable()) if(thing->isNotWalkable())
return false; return false;
if(CreaturePtr creature = thing->asCreature()) { if(thing->isCreature()) {
CreaturePtr creature = thing->self_cast<Creature>();
if(!creature->isPassable()) if(!creature->isPassable())
return false; return false;
} }
@ -491,7 +495,7 @@ bool Tile::mustHookSouth()
bool Tile::hasCreature() bool Tile::hasCreature()
{ {
for(const ThingPtr& thing : m_things) for(const ThingPtr& thing : m_things)
if(thing->asCreature()) if(thing->isCreature())
return true; return true;
return false; return false;
} }

@ -106,7 +106,7 @@ public:
void setHouseId(uint32 hid) { if(m_flags & TILESTATE_HOUSE) m_houseId = hid; } void setHouseId(uint32 hid) { if(m_flags & TILESTATE_HOUSE) m_houseId = hid; }
uint32 getHouseId() { return m_houseId; } uint32 getHouseId() { return m_houseId; }
TilePtr asTile() { return std::static_pointer_cast<Tile>(shared_from_this()); } TilePtr asTile() { return self_cast<Tile>(); }
private: private:
std::vector<CreaturePtr> m_walkingCreatures; std::vector<CreaturePtr> m_walkingCreatures;

Loading…
Cancel
Save