From 744b6e62e1252ca50445b21f671ad8d81dd28ea1 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 27 Apr 2014 14:50:47 +0300 Subject: Add AttributeListener. --- src/CMakeLists.txt | 3 + src/Makefile.am | 3 + src/being/localplayer.cpp | 56 +++++++------- src/being/localplayer.h | 8 +- src/being/playerinfo.cpp | 7 +- src/gui/windows/chatwindow.cpp | 56 +++++++------- src/gui/windows/chatwindow.h | 11 ++- src/gui/windows/inventorywindow.cpp | 22 +++--- src/gui/windows/inventorywindow.h | 12 +-- src/gui/windows/killstats.cpp | 25 ++++--- src/gui/windows/killstats.h | 13 ++-- src/gui/windows/ministatuswindow.cpp | 52 +++++++------ src/gui/windows/ministatuswindow.h | 8 +- src/gui/windows/statuswindow.cpp | 137 ++++++++++++++++++----------------- src/gui/windows/statuswindow.h | 11 ++- src/listeners/attributelistener.cpp | 61 ++++++++++++++++ src/listeners/attributelistener.h | 51 +++++++++++++ src/listeners/baselistener.hpp | 36 +++++++++ 18 files changed, 377 insertions(+), 195 deletions(-) create mode 100644 src/listeners/attributelistener.cpp create mode 100644 src/listeners/attributelistener.h create mode 100644 src/listeners/baselistener.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 20500cdcb..2e94548ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -603,6 +603,9 @@ SET(SRCS being/actorsprite.cpp being/actorsprite.h listeners/actorspritelistener.h + listeners/attributelistener.cpp + listeners/attributelistener.h + listeners/baselistener.hpp actormanager.cpp actormanager.h animatedsprite.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 72a28fb0b..409847682 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -685,6 +685,9 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ being/actorsprite.cpp \ being/actorsprite.h \ listeners/actorspritelistener.h \ + listeners/attributelistener.cpp \ + listeners/attributelistener.h \ + listeners/baselistener.hpp \ actormanager.cpp \ actormanager.h \ animatedsprite.cpp \ diff --git a/src/being/localplayer.cpp b/src/being/localplayer.cpp index b75ee0ebd..ad26a15c2 100644 --- a/src/being/localplayer.cpp +++ b/src/being/localplayer.cpp @@ -96,6 +96,7 @@ extern SkillDialog *skillDialog; LocalPlayer::LocalPlayer(const int id, const int subtype) : Being(id, PLAYER, subtype, nullptr), + AttributeListener(), mGMLevel(0), mInvertDirection(0), mCrazyMoveType(config.getIntValue("crazyMoveType")), @@ -1029,33 +1030,7 @@ void LocalPlayer::processEvent(const Channels channel, { if (channel == CHANNEL_ATTRIBUTES) { - if (event.getName() == EVENT_UPDATEATTRIBUTE) - { - switch (event.getInt("id")) - { - case PlayerInfo::EXP: - { - if (event.getInt("oldValue") > event.getInt("newValue")) - break; - - const int change = event.getInt("newValue") - - event.getInt("oldValue"); - - if (change != 0) - { - // TRANSLATORS: get xp message - addMessageToQueue(strprintf("%d %s", change, _("xp"))); - } - break; - } - case PlayerInfo::LEVEL: - mLevel = event.getInt("newValue"); - break; - default: - break; - }; - } - else if (event.getName() == EVENT_UPDATESTAT) + if (event.getName() == EVENT_UPDATESTAT) { if (!mShowJobExp) return; @@ -1107,6 +1082,33 @@ void LocalPlayer::processEvent(const Channels channel, } } +void LocalPlayer::attributeChanged(const int id, + const int oldVal, + const int newVal) +{ + switch (id) + { + case PlayerInfo::EXP: + { + if (oldVal > newVal) + break; + + const int change = newVal - oldVal; + if (change != 0) + { + // TRANSLATORS: get xp message + addMessageToQueue(strprintf("%d %s", change, _("xp"))); + } + break; + } + case PlayerInfo::LEVEL: + mLevel = newVal; + break; + default: + break; + } +} + void LocalPlayer::moveTo(const int x, const int y) { setDestination(x, y); diff --git a/src/being/localplayer.h b/src/being/localplayer.h index 280e245cd..ecf118799 100644 --- a/src/being/localplayer.h +++ b/src/being/localplayer.h @@ -31,6 +31,7 @@ #include "listeners/actionlistener.h" #include "listeners/actorspritelistener.h" +#include "listeners/attributelistener.h" #include @@ -66,7 +67,8 @@ enum */ class LocalPlayer final : public Being, public ActorSpriteListener, - public DepricatedListener + public DepricatedListener, + public AttributeListener { public: /** @@ -509,6 +511,10 @@ class LocalPlayer final : public Being, int getLastAttackY() const override final { return mTarget ? mTarget->getTileY() : mLastAttackY; } + void attributeChanged(const int id, + const int oldVal, + const int newVal) override final; + protected: void updateCoords() override final; diff --git a/src/being/playerinfo.cpp b/src/being/playerinfo.cpp index 12ce1e6d3..d7652abe0 100644 --- a/src/being/playerinfo.cpp +++ b/src/being/playerinfo.cpp @@ -58,11 +58,8 @@ std::set mProtectedItems; void triggerAttr(const int id, const int old) { - DepricatedEvent event(EVENT_UPDATEATTRIBUTE); - event.setInt("id", id); - event.setInt("oldValue", old); - event.setInt("newValue", mData.mAttributes.find(id)->second); - DepricatedEvent::trigger(CHANNEL_ATTRIBUTES, event); + AttributeListener::distributeEvent(id, old, + mData.mAttributes.find(id)->second); } void triggerStat(const int id, const std::string &changed, diff --git a/src/gui/windows/chatwindow.cpp b/src/gui/windows/chatwindow.cpp index be2daf6a9..dbda471c4 100644 --- a/src/gui/windows/chatwindow.cpp +++ b/src/gui/windows/chatwindow.cpp @@ -156,6 +156,7 @@ ChatWindow::ChatWindow(): Window(_("Chat"), false, nullptr, "chat.xml"), ActionListener(), KeyListener(), + AttributeListener(), mItemLinkHandler(new ItemLinkHandler), mChatTabs(new TabbedArea(this)), mChatInput(new ChatInput(this)), @@ -964,34 +965,7 @@ void ChatWindow::processEvent(const Channels channel, if (!mShowBattleEvents) return; - if (event.getName() == EVENT_UPDATEATTRIBUTE) - { - switch (event.getInt("id")) - { - case PlayerInfo::EXP: - { - if (event.getInt("oldValue") > event.getInt("newValue")) - break; - - const int change = event.getInt("newValue") - - event.getInt("oldValue"); - - if (change != 0) - { - battleChatLog(std::string("+").append(toString( - change)).append(" xp")); - } - break; - } - case PlayerInfo::LEVEL: - battleChatLog(std::string("Level: ").append(toString( - event.getInt("newValue")))); - break; - default: - break; - }; - } - else if (event.getName() == EVENT_UPDATESTAT) + if (event.getName() == EVENT_UPDATESTAT) { if (!config.getBoolValue("showJobExp")) return; @@ -1018,6 +992,32 @@ void ChatWindow::processEvent(const Channels channel, } } +void ChatWindow::attributeChanged(const int id, + const int oldVal, + const int newVal) +{ + switch (id) + { + case PlayerInfo::EXP: + { + if (oldVal > newVal) + break; + const int change = newVal - oldVal; + if (change != 0) + { + battleChatLog(std::string("+").append(toString( + change)).append(" xp")); + } + break; + } + case PlayerInfo::LEVEL: + battleChatLog(std::string("Level: ").append(toString(newVal))); + break; + default: + break; + }; +} + void ChatWindow::addInputText(const std::string &text, const bool space) { const int caretPos = mChatInput->getCaretPosition(); diff --git a/src/gui/windows/chatwindow.h b/src/gui/windows/chatwindow.h index e755e43f2..d345b5abc 100644 --- a/src/gui/windows/chatwindow.h +++ b/src/gui/windows/chatwindow.h @@ -23,9 +23,9 @@ #ifndef GUI_WINDOWS_CHATWINDOW_H #define GUI_WINDOWS_CHATWINDOW_H -#include "listeners/depricatedlistener.h" - +#include "listeners/attributelistener.h" #include "listeners/configlistener.h" +#include "listeners/depricatedlistener.h" #include "gui/widgets/window.h" @@ -86,7 +86,8 @@ class ChatWindow final : public Window, public ActionListener, public KeyListener, public DepricatedListener, - public ConfigListener + public ConfigListener, + public AttributeListener { public: /** @@ -294,6 +295,10 @@ class ChatWindow final : public Window, bool isTabPresent(const ChatTab *const tab) const A_WARN_UNUSED; + void attributeChanged(const int id, + const int oldVal, + const int newVal) override final; + static void localPetSay(const std::string &nick, const std::string &text); diff --git a/src/gui/windows/inventorywindow.cpp b/src/gui/windows/inventorywindow.cpp index 01e5e052d..2122fce2f 100644 --- a/src/gui/windows/inventorywindow.cpp +++ b/src/gui/windows/inventorywindow.cpp @@ -73,6 +73,7 @@ InventoryWindow::InventoryWindow(Inventory *const inventory): KeyListener(), SelectionListener(), InventoryListener(), + AttributeListener(), mInventory(inventory), mItems(new ItemContainer(this, mInventory)), mUseButton(nullptr), @@ -131,8 +132,6 @@ InventoryWindow::InventoryWindow(Inventory *const inventory): mSortDropDown->setSelected(0); } - listen(CHANNEL_ATTRIBUTES); - if (setupWindow) setupWindow->registerWindowForReset(this); @@ -690,17 +689,6 @@ void InventoryWindow::close() } } -void InventoryWindow::processEvent(const Channels channel A_UNUSED, - const DepricatedEvent &event) -{ - if (event.getName() == EVENT_UPDATEATTRIBUTE) - { - const int id = event.getInt("id"); - if (id == PlayerInfo::TOTAL_WEIGHT || id == PlayerInfo::MAX_WEIGHT) - updateWeight(); - } -} - void InventoryWindow::updateWeight() { if (!isMainInventory() || !mWeightBar) @@ -821,3 +809,11 @@ void InventoryWindow::unsetInventory() } mInventory = nullptr; } + +void InventoryWindow::attributeChanged(const int id, + const int oldVal A_UNUSED, + const int newVal A_UNUSED) +{ + if (id == PlayerInfo::TOTAL_WEIGHT || id == PlayerInfo::MAX_WEIGHT) + updateWeight(); +} diff --git a/src/gui/windows/inventorywindow.h b/src/gui/windows/inventorywindow.h index 10e1e21e2..538d9a47d 100644 --- a/src/gui/windows/inventorywindow.h +++ b/src/gui/windows/inventorywindow.h @@ -25,11 +25,10 @@ #include "inventory.h" -#include "listeners/depricatedlistener.h" - #include "gui/widgets/window.h" #include "listeners/actionlistener.h" +#include "listeners/attributelistener.h" #include "listeners/keylistener.h" #include "listeners/selectionlistener.h" @@ -54,7 +53,7 @@ class InventoryWindow final : public Window, public KeyListener, public SelectionListener, public InventoryListener, - public DepricatedListener + public AttributeListener { public: /** @@ -137,9 +136,6 @@ class InventoryWindow final : public Window, void updateDropButton(); - void processEvent(const Channels channel, - const DepricatedEvent &event) override final; - void updateButtons(const Item *item = nullptr); bool isInputFocused() const A_WARN_UNUSED; @@ -154,6 +150,10 @@ class InventoryWindow final : public Window, void unsetInventory(); + void attributeChanged(const int id, + const int oldVal, + const int newVal) override final; + static bool isAnyInputFocused(); private: diff --git a/src/gui/windows/killstats.cpp b/src/gui/windows/killstats.cpp index 467d27524..832892fac 100644 --- a/src/gui/windows/killstats.cpp +++ b/src/gui/windows/killstats.cpp @@ -41,6 +41,7 @@ KillStats::KillStats() : // TRANSLATORS: kill stats window name Window(_("Kill stats"), false, nullptr, "killstats.xml"), ActionListener(), + AttributeListener(), mKillTimer(0), // TRANSLATORS: kill stats window button mResetButton(new Button(this, _("Reset stats"), "reset", this)), @@ -108,7 +109,6 @@ KillStats::KillStats() : setStickyButtonLock(true); setDefaultSize(250, 250, 350, 300); - listen(CHANNEL_ATTRIBUTES); const int xp(PlayerInfo::getAttribute(PlayerInfo::EXP)); int xpNextLevel(PlayerInfo::getAttribute(PlayerInfo::EXP_NEEDED)); @@ -489,18 +489,17 @@ void KillStats::validateJacko() } } -void KillStats::processEvent(const Channels channel A_UNUSED, - const DepricatedEvent &event) +void KillStats::attributeChanged(const int id, + const int oldVal, + const int newVal) { - if (event.getName() == EVENT_UPDATEATTRIBUTE) + switch (id) { - const int id = event.getInt("id"); - if (id == PlayerInfo::EXP || id == PlayerInfo::EXP_NEEDED) - { - gainXp(event.getInt("newValue") - event.getInt("oldValue")); - } - else if (id == PlayerInfo::LEVEL) - { + case PlayerInfo::EXP: + case PlayerInfo::EXP_NEEDED: + gainXp(newVal - oldVal); + break; + case PlayerInfo::LEVEL: mKillCounter = 0; mKillTCounter = 0; mExpCounter = 0; @@ -520,6 +519,8 @@ void KillStats::processEvent(const Channels channel A_UNUSED, _("Kills/Min: %s, Exp/Min: %s"), "?", "?")); resetTimes(); - } + break; + default: + break; } } diff --git a/src/gui/windows/killstats.h b/src/gui/windows/killstats.h index 26e30e9eb..1e2da9ada 100644 --- a/src/gui/windows/killstats.h +++ b/src/gui/windows/killstats.h @@ -24,7 +24,7 @@ #define GUI_WINDOWS_KILLSTATS_H #include "listeners/actionlistener.h" -#include "listeners/depricatedlistener.h" +#include "listeners/attributelistener.h" #include "gui/widgets/window.h" @@ -32,8 +32,8 @@ class Label; class Button; class KillStats final : public Window, - private ActionListener, - public DepricatedListener + public ActionListener, + public AttributeListener { public: /** @@ -75,11 +75,12 @@ class KillStats final : public Window, void jackoAlive(const int id); - void processEvent(const Channels channel A_UNUSED, - const DepricatedEvent &event) override; - void resetTimes(); + void attributeChanged(const int id, + const int oldVal, + const int newVal) override final; + private: void validateJacko(); diff --git a/src/gui/windows/ministatuswindow.cpp b/src/gui/windows/ministatuswindow.cpp index 93a6a6a10..6fb330bbf 100644 --- a/src/gui/windows/ministatuswindow.cpp +++ b/src/gui/windows/ministatuswindow.cpp @@ -55,6 +55,7 @@ typedef std::vector ::const_iterator ProgressBarVectorCIter; MiniStatusWindow::MiniStatusWindow() : Window("MiniStatus", false, nullptr, "ministatus.xml"), InventoryListener(), + AttributeListener(), mBars(), mBarNames(), mIcons(), @@ -253,35 +254,40 @@ void MiniStatusWindow::drawIcons(Graphics *const graphics) void MiniStatusWindow::processEvent(const Channels channel A_UNUSED, const DepricatedEvent &event) { - if (event.getName() == EVENT_UPDATEATTRIBUTE) + if (event.getName() == EVENT_UPDATESTAT) { - const int id = event.getInt("id"); - if (id == PlayerInfo::HP || id == PlayerInfo::MAX_HP) - { + statusWindow->updateMPBar(mMpBar); + StatusWindow::updateJobBar(mJobBar); + } +} + +void MiniStatusWindow::attributeChanged(const int id, + const int oldVal A_UNUSED, + const int newVal A_UNUSED) +{ + switch (id) + { + case PlayerInfo::HP: + case PlayerInfo::MAX_HP: StatusWindow::updateHPBar(mHpBar); - } - else if (id == PlayerInfo::MP || id == PlayerInfo::MAX_MP) - { + break; + case PlayerInfo::MP: + case PlayerInfo::MAX_MP: statusWindow->updateMPBar(mMpBar); - } - else if (id == PlayerInfo::EXP || id == PlayerInfo::EXP_NEEDED) - { + break; + case PlayerInfo::EXP: + case PlayerInfo::EXP_NEEDED: StatusWindow::updateXPBar(mXpBar); - } - else if (id == PlayerInfo::TOTAL_WEIGHT - || id == PlayerInfo::MAX_WEIGHT) - { + break; + case PlayerInfo::TOTAL_WEIGHT: + case PlayerInfo::MAX_WEIGHT: StatusWindow::updateWeightBar(mWeightBar); - } - else if (id == PlayerInfo::MONEY) - { + break; + case PlayerInfo::MONEY: StatusWindow::updateMoneyBar(mMoneyBar); - } - } - else if (event.getName() == EVENT_UPDATESTAT) - { - statusWindow->updateMPBar(mMpBar); - StatusWindow::updateJobBar(mJobBar); + break; + default: + break; } } diff --git a/src/gui/windows/ministatuswindow.h b/src/gui/windows/ministatuswindow.h index 6939f8f54..bab117c19 100644 --- a/src/gui/windows/ministatuswindow.h +++ b/src/gui/windows/ministatuswindow.h @@ -25,6 +25,7 @@ #include "inventory.h" +#include "listeners/attributelistener.h" #include "listeners/depricatedlistener.h" #include "gui/widgets/window.h" @@ -44,7 +45,8 @@ class TextPopup; */ class MiniStatusWindow final : public Window, public InventoryListener, - public DepricatedListener + public DepricatedListener, + public AttributeListener { public: MiniStatusWindow(); @@ -90,6 +92,10 @@ class MiniStatusWindow final : public Window, Rect getChildrenArea() override final A_WARN_UNUSED; + void attributeChanged(const int id, + const int oldVal, + const int newVal) override final; + #ifdef USE_PROFILER void logicChildren(); #endif diff --git a/src/gui/windows/statuswindow.cpp b/src/gui/windows/statuswindow.cpp index 98d3ea82e..5897ae64b 100644 --- a/src/gui/windows/statuswindow.cpp +++ b/src/gui/windows/statuswindow.cpp @@ -144,6 +144,7 @@ StatusWindow::StatusWindow() : Window(player_node ? player_node->getName() : "?", false, nullptr, "status.xml"), ActionListener(), + AttributeListener(), // TRANSLATORS: status window label mLvlLabel(new Label(this, strprintf(_("Level: %d"), 0))), // TRANSLATORS: status window label @@ -342,73 +343,7 @@ void StatusWindow::processEvent(const Channels channel A_UNUSED, return; const DepricatedEvents &eventName = event.getName(); - if (eventName == EVENT_UPDATEATTRIBUTE) - { - switch (event.getInt("id")) - { - case PlayerInfo::HP: - case PlayerInfo::MAX_HP: - updateHPBar(mHpBar, true); - break; - - case PlayerInfo::MP: - case PlayerInfo::MAX_MP: - updateMPBar(mMpBar, true); - break; - - case PlayerInfo::EXP: - case PlayerInfo::EXP_NEEDED: - updateXPBar(mXpBar, false); - break; - - case PlayerInfo::MONEY: - // TRANSLATORS: status window label - mMoneyLabel->setCaption(strprintf(_("Money: %s"), - Units::formatCurrency(event.getInt("newValue")).c_str())); - mMoneyLabel->adjustSize(); - break; - - case PlayerInfo::CHAR_POINTS: - mCharacterPointsLabel->setCaption(strprintf( - // TRANSLATORS: status window label - _("Character points: %d"), event.getInt("newValue"))); - - mCharacterPointsLabel->adjustSize(); - // Update all attributes - for (Attrs::const_iterator it = mAttrs.begin(); - it != mAttrs.end(); ++it) - { - if (it->second) - it->second->update(); - } - break; - - case PlayerInfo::CORR_POINTS: - mCorrectionPointsLabel->setCaption(strprintf( - // TRANSLATORS: status window label - _("Correction points: %d"), event.getInt("newValue"))); - mCorrectionPointsLabel->adjustSize(); - // Update all attributes - for (Attrs::const_iterator it = mAttrs.begin(); - it != mAttrs.end(); ++it) - { - if (it->second) - it->second->update(); - } - break; - - case PlayerInfo::LEVEL: - // TRANSLATORS: status window label - mLvlLabel->setCaption(strprintf(_("Level: %d"), - event.getInt("newValue"))); - mLvlLabel->adjustSize(); - break; - - default: - break; - } - } - else if (eventName == EVENT_UPDATESTAT) + if (eventName == EVENT_UPDATESTAT) { const int id = event.getInt("id"); if (id == Net::getPlayerHandler()->getJobLocation()) @@ -465,6 +400,74 @@ void StatusWindow::processEvent(const Channels channel A_UNUSED, } } +void StatusWindow::attributeChanged(const int id, + const int oldVal A_UNUSED, + const int newVal) +{ + switch (id) + { + case PlayerInfo::HP: + case PlayerInfo::MAX_HP: + updateHPBar(mHpBar, true); + break; + + case PlayerInfo::MP: + case PlayerInfo::MAX_MP: + updateMPBar(mMpBar, true); + break; + + case PlayerInfo::EXP: + case PlayerInfo::EXP_NEEDED: + updateXPBar(mXpBar, false); + break; + + case PlayerInfo::MONEY: + // TRANSLATORS: status window label + mMoneyLabel->setCaption(strprintf(_("Money: %s"), + Units::formatCurrency(newVal).c_str())); + mMoneyLabel->adjustSize(); + break; + + case PlayerInfo::CHAR_POINTS: + mCharacterPointsLabel->setCaption(strprintf( + // TRANSLATORS: status window label + _("Character points: %d"), newVal)); + + mCharacterPointsLabel->adjustSize(); + // Update all attributes + for (Attrs::const_iterator it = mAttrs.begin(); + it != mAttrs.end(); ++it) + { + if (it->second) + it->second->update(); + } + break; + + case PlayerInfo::CORR_POINTS: + mCorrectionPointsLabel->setCaption(strprintf( + // TRANSLATORS: status window label + _("Correction points: %d"), newVal)); + mCorrectionPointsLabel->adjustSize(); + // Update all attributes + for (Attrs::const_iterator it = mAttrs.begin(); + it != mAttrs.end(); ++it) + { + if (it->second) + it->second->update(); + } + break; + + case PlayerInfo::LEVEL: + // TRANSLATORS: status window label + mLvlLabel->setCaption(strprintf(_("Level: %d"), newVal)); + mLvlLabel->adjustSize(); + break; + + default: + break; + } +} + void StatusWindow::setPointsNeeded(const int id, const int needed) { const Attrs::const_iterator it = mAttrs.find(id); diff --git a/src/gui/windows/statuswindow.h b/src/gui/windows/statuswindow.h index 35bba74cd..11aa2ad05 100644 --- a/src/gui/windows/statuswindow.h +++ b/src/gui/windows/statuswindow.h @@ -23,11 +23,11 @@ #ifndef GUI_WINDOWS_STATUSWINDOW_H #define GUI_WINDOWS_STATUSWINDOW_H -#include "listeners/depricatedlistener.h" - #include "gui/widgets/window.h" #include "listeners/actionlistener.h" +#include "listeners/attributelistener.h" +#include "listeners/depricatedlistener.h" #include @@ -45,7 +45,8 @@ class VertContainer; */ class StatusWindow final : public Window, public ActionListener, - public DepricatedListener + public DepricatedListener, + public AttributeListener { public: /** @@ -87,6 +88,10 @@ class StatusWindow final : public Window, void clearAttributes(); + void attributeChanged(const int id, + const int oldVal, + const int newVal) override final; + private: static std::string translateLetter(const char *const letters); static std::string translateLetter2(std::string letters); diff --git a/src/listeners/attributelistener.cpp b/src/listeners/attributelistener.cpp new file mode 100644 index 000000000..b547cb219 --- /dev/null +++ b/src/listeners/attributelistener.cpp @@ -0,0 +1,61 @@ +/* + * The ManaPlus Client + * Copyright (C) 2014 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "listeners/attributelistener.h" + +#include "listeners/baselistener.hpp" + +#include "debug.h" + +std::vector AttributeListener::mListeners; + +AttributeListener::AttributeListener() +{ + addListener(this); +} + +AttributeListener::~AttributeListener() +{ + removeListener(this); +} + +void AttributeListener::addListener(AttributeListener *const listener) +{ + mListeners.push_back(listener); +} + +void AttributeListener::removeListener(AttributeListener *const listener) +{ + listenerRemoveListener; +} + +void AttributeListener::distributeEvent(const int id, + const int oldVal, + const int newVal) +{ + FOR_EACH (std::vector::iterator, + it, mListeners) + { + AttributeListener *const listener = *it; + if (listener) + listener->attributeChanged(id, oldVal, newVal); + } +} + diff --git a/src/listeners/attributelistener.h b/src/listeners/attributelistener.h new file mode 100644 index 000000000..83605ffe9 --- /dev/null +++ b/src/listeners/attributelistener.h @@ -0,0 +1,51 @@ +/* + * The ManaPlus Client + * Copyright (C) 2014 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LISTENERS_ATTRIBUTELISTENER_H +#define LISTENERS_ATTRIBUTELISTENER_H + +#include + +#include "localconsts.h" + +class AttributeListener +{ + public: + AttributeListener(); + + virtual ~AttributeListener(); + + virtual void attributeChanged(const int id, + const int oldVal, + const int newVal) = 0; + + static void addListener(AttributeListener *const listener); + + static void removeListener(AttributeListener *const listener); + + static void distributeEvent(const int id, + const int oldVal, + const int newVal); + + private: + static std::vector mListeners; +}; + +#endif // LISTENERS_ATTRIBUTELISTENER_H diff --git a/src/listeners/baselistener.hpp b/src/listeners/baselistener.hpp new file mode 100644 index 000000000..ae3c7112e --- /dev/null +++ b/src/listeners/baselistener.hpp @@ -0,0 +1,36 @@ +/* + * The ManaPlus Client + * Copyright (C) 2014 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LISTENERS_BASELISTENER_HPP +#define LISTENERS_BASELISTENER_HPP + +#define listenerRemoveListener \ + { \ + std::vector::iterator it = mListeners.begin(); \ + while (it != mListeners.end()) \ + { \ + if (*it == listener) \ + it = mListeners.erase(it); \ + else \ + ++ it; \ + } \ + } + +#endif // LISTENERS_BASELISTENER_HPP -- cgit v1.2.3-60-g2f50