From 029818ba44703c5151f8d916284e307b05d08fa9 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Fri, 1 Nov 2013 00:09:32 +0300 Subject: Add configure option --enable-checks for check some calls (disabled by default) Also add configuration listeners removing in objects. --- build/bmakedebug | 3 ++- configure.ac | 11 +++++++++++ src/Makefile.am | 4 ++++ src/actormanager.cpp | 1 + src/being/being.cpp | 1 + src/client.cpp | 3 +++ src/configuration.cpp | 21 +++++++++++++++++++++ src/configuration.h | 6 ++++++ src/debug.h | 13 +++++++++++++ src/eventsmanager.cpp | 10 ++++++++++ src/eventsmanager.h | 4 ++++ src/gui/gui.cpp | 5 +++++ src/gui/theme.cpp | 1 + src/gui/viewport.cpp | 1 + src/gui/widgets/avatarlistbox.cpp | 1 + src/gui/widgets/tabs/guildchattab.cpp | 1 + src/gui/windowmenu.cpp | 1 + src/gui/windows/botcheckerwindow.cpp | 1 + src/gui/windows/chatwindow.cpp | 1 + src/gui/windows/minimap.cpp | 1 + src/gui/windows/npcdialog.cpp | 1 + src/gui/windows/whoisonline.cpp | 1 + src/map.cpp | 1 + src/maplayer.cpp | 1 + src/net/ea/gui/guildtab.cpp | 1 + src/net/ea/gui/partytab.cpp | 2 ++ src/soundmanager.cpp | 1 + src/touchmanager.cpp | 1 + 28 files changed, 98 insertions(+), 1 deletion(-) diff --git a/build/bmakedebug b/build/bmakedebug index 5532a2b8a..5813e91a0 100755 --- a/build/bmakedebug +++ b/build/bmakedebug @@ -46,7 +46,8 @@ autoreconf -i --with-internalguichan=yes \ --enable-tcmalloc=no \ --enable-googleprofiler=no \ ---enable-eathena=yes +--enable-eathena=yes \ +--enable-checks=yes cd po make -j8 update-gmo 2>../build/make1.log diff --git a/configure.ac b/configure.ac index 73e6e97b3..367fa66cc 100755 --- a/configure.ac +++ b/configure.ac @@ -312,6 +312,17 @@ esac],[with_eathena=false]) AM_CONDITIONAL(ENABLE_EATHENA, test x$with_eathena = xtrue) +# Enable checks +AC_ARG_ENABLE(checks, +[ --enable-checks Turn on internal checks (can be slow)], +[case "${enableval}" in + yes) with_checks=true ;; + no) with_checks=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-checks) ;; +esac],[with_checks=false]) + +AM_CONDITIONAL(ENABLE_CHECKS, test x$with_checks = xtrue) + # Enable portable AC_ARG_ENABLE(portable, [ --enable-portable Turn on portable mode for linux], diff --git a/src/Makefile.am b/src/Makefile.am index ebce034ea..1b2889594 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,10 @@ if USE_MUMBLE manaplus_CXXFLAGS += -DUSE_MUMBLE endif +if ENABLE_CHECKS +manaplus_CXXFLAGS += -DENABLE_CHECKS +endif + if USE_SDL2 manaplus_CXXFLAGS += -I$(srcdir)/sdl2gfx -DUSE_SDL2 manaplus_SOURCES += sdl2gfx/SDL_framerate.c \ diff --git a/src/actormanager.cpp b/src/actormanager.cpp index f37cc9a18..d7a272284 100644 --- a/src/actormanager.cpp +++ b/src/actormanager.cpp @@ -212,6 +212,7 @@ ActorManager::ActorManager() : ActorManager::~ActorManager() { config.removeListeners(this); + CHECKLISTENERS storeAttackList(); clear(); } diff --git a/src/being/being.cpp b/src/being/being.cpp index fdd706bbe..ed794a49a 100644 --- a/src/being/being.cpp +++ b/src/being/being.cpp @@ -214,6 +214,7 @@ Being::Being(const int id, const Type type, const uint16_t subtype, Being::~Being() { config.removeListener("visiblenames", this); + CHECKLISTENERS delete [] mSpriteRemap; mSpriteRemap = nullptr; diff --git a/src/client.cpp b/src/client.cpp index 24ed15987..fa8b860d5 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -768,6 +768,7 @@ Client::~Client() gameClear(); else testsClear(); + CHECKLISTENERS } void Client::bindTextDomain(const char *const name, const char *const path) @@ -810,6 +811,8 @@ void Client::gameClear() logger->log1("Quitting1"); config.removeListeners(this); + eventsManager.shutdown(); + delete setupWindow; setupWindow = nullptr; delete helpWindow; diff --git a/src/configuration.cpp b/src/configuration.cpp index 489755341..d9a9df3ab 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -842,6 +842,27 @@ void Configuration::removeListener(const std::string &key, mListenerMap[key].remove(listener); } +#ifdef ENABLE_CHECKS +void Configuration::checkListeners(ConfigListener *const listener, + const char *const file, + const unsigned line) +{ + FOR_EACH (ListenerMapIterator, it, mListenerMap) + { + Listeners listeners = it->second; + FOR_EACH (ListenerIterator, it2, listeners) + { + if (*it2 == listener) + { + logger->log("detected not cleaned listener: %p, %s:%u", + static_cast(listener), file, line); + exit(1); + } + } + } +} +#endif + void Configuration::removeListeners(ConfigListener *const listener) { FOR_EACH (ListenerMapIterator, it, mListenerMap) diff --git a/src/configuration.h b/src/configuration.h index 54e5e2ca7..774678b50 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -282,6 +282,12 @@ class Configuration final : public ConfigurationObject void removeListeners(ConfigListener *const listener); +#ifdef ENABLE_CHECKS + void checkListeners(ConfigListener *const listener, + const char *const file, + const unsigned line); +#endif + void setValue(const std::string &key, const std::string &value); void incValue(const std::string &key); diff --git a/src/debug.h b/src/debug.h index 31b2b457b..db1989b77 100644 --- a/src/debug.h +++ b/src/debug.h @@ -84,3 +84,16 @@ #define MPHYSFSRWOPS_openRead(name) PHYSFSRWOPS_openRead(name) #endif // DEBUG_PHYSFS + + +#ifdef ENABLE_CHECKS + +#define CHECKLISTENERS \ + config.checkListeners(this, __FILE__, __LINE__); \ + serverConfig.checkListeners(this, __FILE__, __LINE__); + +#else // ENABLE_CHECKS + +#define CHECKLISTENERS + +#endif // ENABLE_CHECKS diff --git a/src/eventsmanager.cpp b/src/eventsmanager.cpp index 4786e4402..17cb11ae6 100644 --- a/src/eventsmanager.cpp +++ b/src/eventsmanager.cpp @@ -44,12 +44,22 @@ EventsManager::EventsManager() : { } +EventsManager::~EventsManager() +{ + CHECKLISTENERS +} + void EventsManager::init() { mLogInput = config.getBoolValue("logInput"); config.addListener("logInput", this); } +void EventsManager::shutdown() +{ + config.removeListeners(this); +} + bool EventsManager::handleCommonEvents(const SDL_Event &event) { if (mLogInput) diff --git a/src/eventsmanager.h b/src/eventsmanager.h index 0cf891729..8ca6aa974 100644 --- a/src/eventsmanager.h +++ b/src/eventsmanager.h @@ -36,8 +36,12 @@ class EventsManager final : public ConfigListener A_DELETE_COPY(EventsManager) + virtual ~EventsManager(); + void init(); + void shutdown(); + bool handleEvents(); bool handleCommonEvents(const SDL_Event &event); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index d32e81fe8..0c75dd4e4 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -69,6 +69,11 @@ class GuiConfigListener final : public ConfigListener A_DELETE_COPY(GuiConfigListener) + virtual ~GuiConfigListener() + { + CHECKLISTENERS + } + void optionChanged(const std::string &name) { if (!mGui) diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp index f523df908..3381b156a 100644 --- a/src/gui/theme.cpp +++ b/src/gui/theme.cpp @@ -234,6 +234,7 @@ Theme::~Theme() { delete_all(mSkins); config.removeListener("guialpha", this); + CHECKLISTENERS delete_all(mProgressColors); } diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 05807126f..d2dddb4d8 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -98,6 +98,7 @@ Viewport::Viewport() : Viewport::~Viewport() { config.removeListeners(this); + CHECKLISTENERS delete mPopupMenu; mPopupMenu = nullptr; delete mBeingPopup; diff --git a/src/gui/widgets/avatarlistbox.cpp b/src/gui/widgets/avatarlistbox.cpp index d4eefe69c..664263518 100644 --- a/src/gui/widgets/avatarlistbox.cpp +++ b/src/gui/widgets/avatarlistbox.cpp @@ -71,6 +71,7 @@ AvatarListBox::AvatarListBox(const Widget2 *const widget, AvatarListBox::~AvatarListBox() { config.removeListeners(this); + CHECKLISTENERS instances--; diff --git a/src/gui/widgets/tabs/guildchattab.cpp b/src/gui/widgets/tabs/guildchattab.cpp index 4188a8843..69a4faaf3 100644 --- a/src/gui/widgets/tabs/guildchattab.cpp +++ b/src/gui/widgets/tabs/guildchattab.cpp @@ -49,6 +49,7 @@ GuildChatTab::GuildChatTab(const Widget2 *const widget) : GuildChatTab::~GuildChatTab() { config.removeListeners(this); + CHECKLISTENERS } bool GuildChatTab::handleCommand(const std::string &type, diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp index 5d7f792d9..332843a86 100644 --- a/src/gui/windowmenu.cpp +++ b/src/gui/windowmenu.cpp @@ -180,6 +180,7 @@ WindowMenu::WindowMenu(const Widget2 *const widget) : WindowMenu::~WindowMenu() { config.removeListener("autohideButtons", this); + CHECKLISTENERS delete mTextPopup; mTextPopup = nullptr; diff --git a/src/gui/windows/botcheckerwindow.cpp b/src/gui/windows/botcheckerwindow.cpp index b502dd01d..61dc7286c 100644 --- a/src/gui/windows/botcheckerwindow.cpp +++ b/src/gui/windows/botcheckerwindow.cpp @@ -344,6 +344,7 @@ BotCheckerWindow::BotCheckerWindow(): BotCheckerWindow::~BotCheckerWindow() { config.removeListener("enableBotCheker", this); + CHECKLISTENERS } void BotCheckerWindow::slowLogic() diff --git a/src/gui/windows/chatwindow.cpp b/src/gui/windows/chatwindow.cpp index eade8b063..79cf0eff3 100644 --- a/src/gui/windows/chatwindow.cpp +++ b/src/gui/windows/chatwindow.cpp @@ -310,6 +310,7 @@ ChatWindow::ChatWindow(): ChatWindow::~ChatWindow() { config.removeListeners(this); + CHECKLISTENERS saveState(); config.setValue("ReturnToggles", mReturnToggles); removeAllWhispers(); diff --git a/src/gui/windows/minimap.cpp b/src/gui/windows/minimap.cpp index 9ac4a9e26..7aefa285b 100644 --- a/src/gui/windows/minimap.cpp +++ b/src/gui/windows/minimap.cpp @@ -87,6 +87,7 @@ Minimap::~Minimap() { config.setValue(getWindowName() + "Show", mShow); config.removeListeners(this); + CHECKLISTENERS if (mMapImage) { diff --git a/src/gui/windows/npcdialog.cpp b/src/gui/windows/npcdialog.cpp index 3b5d0d772..1c2a6cc1d 100644 --- a/src/gui/windows/npcdialog.cpp +++ b/src/gui/windows/npcdialog.cpp @@ -209,6 +209,7 @@ void NpcDialog::postInit() NpcDialog::~NpcDialog() { config.removeListeners(this); + CHECKLISTENERS clearLayout(); if (mPlayerBox) diff --git a/src/gui/windows/whoisonline.cpp b/src/gui/windows/whoisonline.cpp index c4f096c72..2e32e13fe 100644 --- a/src/gui/windows/whoisonline.cpp +++ b/src/gui/windows/whoisonline.cpp @@ -142,6 +142,7 @@ void WhoIsOnline::postInit() WhoIsOnline::~WhoIsOnline() { config.removeListeners(this); + CHECKLISTENERS if (mThread && SDL_GetThreadID(mThread)) SDL_WaitThread(mThread, nullptr); diff --git a/src/map.cpp b/src/map.cpp index e4ab0c60f..6071d22f2 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -199,6 +199,7 @@ Map::Map(const int width, const int height, Map::~Map() { config.removeListeners(this); + CHECKLISTENERS // delete metadata, layers, tilesets and overlays delete [] mMetaTiles; diff --git a/src/maplayer.cpp b/src/maplayer.cpp index 84514cdaa..1f8278304 100644 --- a/src/maplayer.cpp +++ b/src/maplayer.cpp @@ -64,6 +64,7 @@ MapLayer::MapLayer(const int x, const int y, const int width, const int height, MapLayer::~MapLayer() { config.removeListener("highlightAttackRange", this); + CHECKLISTENERS delete [] mTiles; delete_all(mTempRows); mTempRows.clear(); diff --git a/src/net/ea/gui/guildtab.cpp b/src/net/ea/gui/guildtab.cpp index 86f0e65a6..e0a8937d1 100644 --- a/src/net/ea/gui/guildtab.cpp +++ b/src/net/ea/gui/guildtab.cpp @@ -57,6 +57,7 @@ GuildTab::GuildTab(const Widget2 *const widget) : GuildTab::~GuildTab() { config.removeListeners(this); + CHECKLISTENERS } bool GuildTab::handleCommand(const std::string &type, const std::string &args) diff --git a/src/net/ea/gui/partytab.cpp b/src/net/ea/gui/partytab.cpp index 2b93793d3..f3c1d0377 100644 --- a/src/net/ea/gui/partytab.cpp +++ b/src/net/ea/gui/partytab.cpp @@ -58,6 +58,8 @@ PartyTab::PartyTab(const Widget2 *const widget) : PartyTab::~PartyTab() { + config.removeListeners(this); + CHECKLISTENERS } void PartyTab::handleInput(const std::string &msg) diff --git a/src/soundmanager.cpp b/src/soundmanager.cpp index 7ddf5d175..a8dd144cf 100644 --- a/src/soundmanager.cpp +++ b/src/soundmanager.cpp @@ -71,6 +71,7 @@ SoundManager::SoundManager(): SoundManager::~SoundManager() { + CHECKLISTENERS } void SoundManager::shutdown() diff --git a/src/touchmanager.cpp b/src/touchmanager.cpp index bad706867..2620e9a17 100644 --- a/src/touchmanager.cpp +++ b/src/touchmanager.cpp @@ -67,6 +67,7 @@ TouchManager::~TouchManager() clear(); delete mVertexes; mVertexes = nullptr; + CHECKLISTENERS } void TouchManager::shutdown() -- cgit v1.2.3-60-g2f50