From dce9880d161605e0a8006d1b14319dd4b1e3c0c0 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 12 Nov 2014 22:45:48 +0200 Subject: [PATCH] Minor refactoring of FunctionList using variadic templates. Please make sure that all supported compilers are OK with this code --- client/CPreGame.cpp | 4 +-- client/widgets/Buttons.cpp | 4 +-- client/windows/CHeroWindow.cpp | 9 ++--- client/windows/GUIClasses.cpp | 4 +-- client/windows/InfoWindows.cpp | 7 ++-- lib/FunctionList.h | 62 ++++++++++++---------------------- 6 files changed, 32 insertions(+), 58 deletions(-) diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index a21468903..6eb0a6725 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -1240,7 +1240,7 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const std::functionfilters.add(CTextInput::filenameFilter); + txt->filters += CTextInput::filenameFilter; } break; @@ -4236,7 +4236,7 @@ CSimpleJoinScreen::CSimpleJoinScreen() port = new CTextInput(Rect(25, 115, 175, 16), *bg); port->cb += std::bind(&CSimpleJoinScreen::onChange, this, _1); - port->filters.add(std::bind(&CTextInput::numberFilter, _1, _2, 0, 65535)); + port->filters += std::bind(&CTextInput::numberFilter, _1, _2, 0, 65535); ok = new CButton(Point( 26, 142), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CSimpleJoinScreen::enterSelectionScreen, this), SDLK_RETURN); cancel = new CButton(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CGuiHandler::popIntTotally, std::ref(GH), this), SDLK_ESCAPE); diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index 00ac52ae9..6a2956cf0 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -150,7 +150,7 @@ void CButton::block(bool on) void CButton::onButtonClicked() { // debug logging to figure out pressed button (and as result - player actions) in case of crash - logAnim->traceStream() << "Button clicked at " << pos.x << "x" << pos.y << ", " << callback.funcs.size() << " functions"; + logAnim->traceStream() << "Button clicked at " << pos.x << "x" << pos.y; CIntObject * parent = this->parent; std::string prefix = "Parent is"; while (parent) @@ -352,7 +352,7 @@ bool CToggleBase::canActivate() void CToggleBase::addCallback(std::function function) { - callback.add(function); + callback += function; } CToggleButton::CToggleButton(Point position, const std::string &defName, const std::pair &help, diff --git a/client/windows/CHeroWindow.cpp b/client/windows/CHeroWindow.cpp index 35612b412..803184a32 100644 --- a/client/windows/CHeroWindow.cpp +++ b/client/windows/CHeroWindow.cpp @@ -295,13 +295,8 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals void CHeroWindow::dismissCurrent() { - CFunctionList ony = std::bind(&CHeroWindow::close,this); - //ony += std::bind(&CCallback::dismissHero, LOCPLINT->cb.get(), curHero); //can't assign bool function to void function list :( - auto dismiss = [=]() -> void - { - LOCPLINT->cb.get()->dismissHero(curHero); - }; - ony += dismiss; + CFunctionList ony = [=] { close(); }; + ony += [=] { LOCPLINT->cb->dismissHero(curHero); }; LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[22], ony, 0, false); } diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 77a7d7b4f..bd106291b 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -382,8 +382,8 @@ CSplitWindow::CSplitWindow(const CCreature * creature, std::functionfilters.add(std::bind(&CTextInput::numberFilter, _1, _2, leftMin, leftMax)); - rightInput->filters.add(std::bind(&CTextInput::numberFilter, _1, _2, rightMin, rightMax)); + leftInput->filters += std::bind(&CTextInput::numberFilter, _1, _2, leftMin, leftMax); + rightInput->filters += std::bind(&CTextInput::numberFilter, _1, _2, rightMin, rightMax); leftInput->setText(boost::lexical_cast(leftAmount), false); rightInput->setText(boost::lexical_cast(rightAmount), false); diff --git a/client/windows/InfoWindows.cpp b/client/windows/InfoWindows.cpp index 57887e7c7..2ce8bec10 100644 --- a/client/windows/InfoWindows.cpp +++ b/client/windows/InfoWindows.cpp @@ -202,10 +202,9 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector >("IOKAY.DEF",0)); pom.push_back(std::pair >("ICANCEL.DEF",0)); CInfoWindow * temp = new CInfoWindow(text, player, components ? *components : std::vector(), pom, DelComps); - for(auto & elem : onYes.funcs) - temp->buttons[0]->addCallback(elem); - for(auto & elem : onNo.funcs) - temp->buttons[1]->addCallback(elem); + + temp->buttons[0]->addCallback( onYes ); + temp->buttons[1]->addCallback( onNo ); GH.pushInt(temp); } diff --git a/lib/FunctionList.h b/lib/FunctionList.h index 9c7a0ecdd..4b1cb283e 100644 --- a/lib/FunctionList.h +++ b/lib/FunctionList.h @@ -15,71 +15,51 @@ template class CFunctionList { -public: std::vector > funcs; +public: + CFunctionList( std::nullptr_t ) { } + CFunctionList( int ) { } + CFunctionList( ){ } - CFunctionList(int){}; - CFunctionList(){}; template CFunctionList(const Functor &f) { funcs.push_back(std::function(f)); } + CFunctionList(const std::function &first) { if (first) funcs.push_back(first); } - CFunctionList(std::nullptr_t) - {} - CFunctionList & operator+=(const std::function &first) + + CFunctionList & operator+=(const CFunctionList &first) { - funcs.push_back(first); + for( auto & fun : first.funcs) + { + funcs.push_back(fun); + } return *this; } - void add(const CFunctionList &first) - { - for (size_t i = 0; i < first.funcs.size(); i++) - { - funcs.push_back(first.funcs[i]); - } - } + void clear() { funcs.clear(); } + operator bool() const { - return funcs.size(); + return !funcs.empty(); } - void operator()() const + + template + void operator()(Args ... args) const { - std::vector > funcs2 = funcs; //backup - for(size_t i=0;i > funcs_copy = funcs; + for( auto & fun : funcs_copy) { - if (funcs2[i]) - funcs2[i](); - } - } - template - void operator()(const Arg & a) const - { - std::vector > funcs2 = funcs; //backup - for(int i=0;i - void operator()(Arg1 & a, Arg2 & b) const - { - std::vector > funcs2 = funcs; //backup - for(int i=0;i