mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Minor refactoring of FunctionList using variadic templates.
Please make sure that all supported compilers are OK with this code
This commit is contained in:
		| @@ -1240,7 +1240,7 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const std::function<void(CM | ||||
| 			if(tabType == CMenuScreen::saveGame) | ||||
| 			{ | ||||
| 				txt = new CTextInput(Rect(32, 539, 350, 20), Point(-32, -25), "GSSTRIP.bmp", 0); | ||||
| 				txt->filters.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); | ||||
|   | ||||
| @@ -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<void(bool)> function) | ||||
| { | ||||
| 	callback.add(function); | ||||
| 	callback += function; | ||||
| } | ||||
|  | ||||
| CToggleButton::CToggleButton(Point position, const std::string &defName, const std::pair<std::string, std::string> &help, | ||||
|   | ||||
| @@ -295,13 +295,8 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals | ||||
|  | ||||
| void CHeroWindow::dismissCurrent() | ||||
| { | ||||
| 	CFunctionList<void()> 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<void()> ony = [=] { close(); }; | ||||
| 	ony += [=] { LOCPLINT->cb->dismissHero(curHero); }; | ||||
| 	LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[22], ony, 0, false); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -382,8 +382,8 @@ CSplitWindow::CSplitWindow(const CCreature * creature, std::function<void(int, i | ||||
| 	rightInput = new CTextInput(Rect(176, 218, 100, 36), FONT_BIG, std::bind(&CSplitWindow::setAmountText, this, _1, false)); | ||||
|  | ||||
| 	//add filters to allow only number input | ||||
| 	leftInput->filters.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<std::string>(leftAmount), false); | ||||
| 	rightInput->setText(boost::lexical_cast<std::string>(rightAmount), false); | ||||
|   | ||||
| @@ -202,10 +202,9 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<CC | ||||
| 	pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0)); | ||||
| 	pom.push_back(std::pair<std::string,CFunctionList<void()> >("ICANCEL.DEF",0)); | ||||
| 	CInfoWindow * temp = new CInfoWindow(text, player, components ? *components : std::vector<CComponent*>(), 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); | ||||
| } | ||||
|   | ||||
| @@ -15,71 +15,51 @@ | ||||
| template<typename Signature> | ||||
| class CFunctionList | ||||
| { | ||||
| public: | ||||
| 	std::vector<std::function<Signature> > funcs; | ||||
| public: | ||||
| 	CFunctionList( std::nullptr_t ) { } | ||||
| 	CFunctionList( int ) { } | ||||
| 	CFunctionList( ){ } | ||||
|  | ||||
| 	CFunctionList(int){}; | ||||
| 	CFunctionList(){}; | ||||
| 	template <typename Functor>  | ||||
| 	CFunctionList(const Functor &f) | ||||
| 	{ | ||||
| 		funcs.push_back(std::function<Signature>(f)); | ||||
| 	} | ||||
|  | ||||
| 	CFunctionList(const std::function<Signature> &first) | ||||
| 	{ | ||||
| 		if (first) | ||||
| 			funcs.push_back(first); | ||||
| 	} | ||||
| 	CFunctionList(std::nullptr_t) | ||||
| 	{} | ||||
| 	CFunctionList & operator+=(const std::function<Signature> &first) | ||||
|  | ||||
| 	CFunctionList & operator+=(const CFunctionList<Signature> &first) | ||||
| 	{ | ||||
| 		funcs.push_back(first); | ||||
| 		for( auto & fun : first.funcs) | ||||
| 		{ | ||||
| 			funcs.push_back(fun); | ||||
| 		} | ||||
| 		return *this; | ||||
| 	} | ||||
| 	void add(const CFunctionList<Signature> &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 <typename... Args> | ||||
| 	void operator()(Args ... args) const | ||||
| 	{ | ||||
| 		std::vector<std::function<Signature> > funcs2 = funcs; //backup | ||||
| 		for(size_t i=0;i<funcs2.size(); ++i)  | ||||
| 		std::vector<std::function<Signature> > funcs_copy = funcs; | ||||
| 		for( auto & fun : funcs_copy) | ||||
| 		{ | ||||
| 			if (funcs2[i]) | ||||
| 				funcs2[i](); | ||||
| 		} | ||||
| 	} | ||||
| 	template <typename Arg>  | ||||
| 	void operator()(const Arg & a) const | ||||
| 	{ | ||||
| 		std::vector<std::function<Signature> > funcs2 = funcs; //backup | ||||
| 		for(int i=0;i<funcs2.size(); i++)  | ||||
| 		{ | ||||
| 			if (funcs2[i]) | ||||
| 				funcs2[i](a); | ||||
| 		} | ||||
| 	} | ||||
| 	// Me wants variadic templates :( | ||||
| 	template <typename Arg1, typename Arg2> | ||||
| 	void operator()(Arg1 & a, Arg2 & b) const | ||||
| 	{ | ||||
| 		std::vector<std::function<Signature> > funcs2 = funcs; //backup | ||||
| 		for(int i=0;i<funcs2.size(); i++) | ||||
| 		{ | ||||
| 			if (funcs2[i]) | ||||
| 				funcs2[i](a, b); | ||||
| 			if (fun) | ||||
| 				fun(args...); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user