mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Converted timer event into tick event that is called every frame
This commit is contained in:
		| @@ -17,7 +17,7 @@ class CIntObject; | ||||
|  | ||||
| class ClientCommandManager //take mantis #2292 issue about account if thinking about handling cheats from command-line | ||||
| { | ||||
| 	bool currentCallFromIngameConsole; | ||||
| 	bool currentCallFromIngameConsole = false; | ||||
|  | ||||
| 	void giveTurn(const PlayerColor &color); | ||||
| 	void printInfoAboutInterfaceObject(const CIntObject *obj, int level); | ||||
|   | ||||
| @@ -24,54 +24,66 @@ | ||||
| #include "../../lib/TextOperations.h" | ||||
| #include "../../lib/mapObjects/CArmedInstance.h" | ||||
|  | ||||
| #include <SDL_timer.h> | ||||
|  | ||||
| CInGameConsole::CInGameConsole() | ||||
| 	: CIntObject(KEYBOARD | TEXTINPUT), | ||||
| 	prevEntDisp(-1), | ||||
| 	defaultTimeout(10000), | ||||
| 	maxDisplayedTexts(10) | ||||
| 	: CIntObject(KEYBOARD | TIME | TEXTINPUT) | ||||
| 	, prevEntDisp(-1) | ||||
| { | ||||
| 	type |= REDRAW_PARENT; | ||||
| } | ||||
|  | ||||
| void CInGameConsole::showAll(SDL_Surface * to) | ||||
| { | ||||
| 	show(to); | ||||
| } | ||||
|  | ||||
| void CInGameConsole::show(SDL_Surface * to) | ||||
| { | ||||
| 	int number = 0; | ||||
|  | ||||
| 	std::vector<std::list< std::pair< std::string, uint32_t > >::iterator> toDel; | ||||
|  | ||||
| 	boost::unique_lock<boost::mutex> lock(texts_mx); | ||||
| 	for(auto it = texts.begin(); it != texts.end(); ++it, ++number) | ||||
| 	for(auto & text : texts) | ||||
| 	{ | ||||
| 		Point leftBottomCorner(0, pos.h); | ||||
| 		Point textPosition(leftBottomCorner.x + 50, leftBottomCorner.y - texts.size() * 20 - 80 + number * 20); | ||||
|  | ||||
| 		graphics->fonts[FONT_MEDIUM]->renderTextLeft(to, it->first, Colors::GREEN, | ||||
| 			Point(leftBottomCorner.x + 50, leftBottomCorner.y - (int)texts.size() * 20 - 80 + number*20)); | ||||
| 		graphics->fonts[FONT_MEDIUM]->renderTextLeft(to, text.text, Colors::GREEN, textPosition ); | ||||
|  | ||||
| 		if((int)(SDL_GetTicks() - it->second) > defaultTimeout) | ||||
| 		number++; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CInGameConsole::tick(uint32_t msPassed) | ||||
| { | ||||
| 			toDel.push_back(it); | ||||
| 	size_t sizeBefore = texts.size(); | ||||
| 	{ | ||||
| 		boost::unique_lock<boost::mutex> lock(texts_mx); | ||||
|  | ||||
| 		for(auto & text : texts) | ||||
| 			text.timeOnScreen += msPassed; | ||||
|  | ||||
| 		vstd::erase_if( | ||||
| 			texts, | ||||
| 			[&](const auto & value) | ||||
| 			{ | ||||
| 				return value.timeOnScreen > defaultTimeout; | ||||
| 			} | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| 	for(auto & elem : toDel) | ||||
| 	{ | ||||
| 		texts.erase(elem); | ||||
| 	} | ||||
| 	if(sizeBefore != texts.size()) | ||||
| 		GH.totalRedraw(); // FIXME: ingame console has no parent widget set | ||||
| } | ||||
|  | ||||
| void CInGameConsole::print(const std::string & txt) | ||||
| { | ||||
| 	// boost::unique_lock scope | ||||
| 	{ | ||||
| 		boost::unique_lock<boost::mutex> lock(texts_mx); | ||||
| 		int lineLen = conf.go()->ac.outputLineLength; | ||||
|  | ||||
| 		if(txt.size() < lineLen) | ||||
| 		{ | ||||
| 		texts.push_back(std::make_pair(txt, SDL_GetTicks())); | ||||
| 		if(texts.size() > maxDisplayedTexts) | ||||
| 		{ | ||||
| 			texts.pop_front(); | ||||
| 		} | ||||
| 			texts.push_back({txt, 0}); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| @@ -79,16 +91,18 @@ void CInGameConsole::print(const std::string &txt) | ||||
| 			for(int g = 0; g < txt.size() / lineLen + 1; ++g) | ||||
| 			{ | ||||
| 				std::string part = txt.substr(g * lineLen, lineLen); | ||||
| 			if(part.size() == 0) | ||||
| 				if(part.empty()) | ||||
| 					break; | ||||
|  | ||||
| 			texts.push_back(std::make_pair(part, SDL_GetTicks())); | ||||
| 			if(texts.size() > maxDisplayedTexts) | ||||
| 			{ | ||||
| 				texts.pop_front(); | ||||
| 				texts.push_back({part, 0}); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		while(texts.size() > maxDisplayedTexts) | ||||
| 			texts.erase(texts.begin()); | ||||
| 	} | ||||
|  | ||||
| 	GH.totalRedraw(); // FIXME: ingame console has no parent widget set | ||||
| } | ||||
|  | ||||
| void CInGameConsole::keyPressed (const SDL_Keycode & key) | ||||
| @@ -136,7 +150,7 @@ void CInGameConsole::keyPressed (const SDL_Keycode & key) | ||||
| 		} | ||||
| 	case SDLK_UP: //up arrow | ||||
| 		{ | ||||
| 			if(previouslyEntered.size() == 0) | ||||
| 			if(previouslyEntered.empty()) | ||||
| 				break; | ||||
|  | ||||
| 			if(prevEntDisp == -1) | ||||
| @@ -178,7 +192,7 @@ void CInGameConsole::keyPressed (const SDL_Keycode & key) | ||||
|  | ||||
| void CInGameConsole::textInputed(const std::string & inputtedText) | ||||
| { | ||||
| 	if(!captureAllKeys || enteredText.size() == 0) | ||||
| 	if(!captureAllKeys || enteredText.empty()) | ||||
| 		return; | ||||
| 	enteredText.resize(enteredText.size()-1); | ||||
|  | ||||
|   | ||||
| @@ -14,12 +14,29 @@ | ||||
| class CInGameConsole : public CIntObject | ||||
| { | ||||
| private: | ||||
| 	std::list< std::pair< std::string, uint32_t > > texts; //list<text to show, time of add> | ||||
| 	boost::mutex texts_mx;		// protects texts | ||||
| 	std::vector< std::string > previouslyEntered; //previously entered texts, for up/down arrows to work | ||||
| 	int prevEntDisp; //displayed entry from previouslyEntered - if none it's -1 | ||||
| 	int defaultTimeout; //timeout for new texts (in ms) | ||||
| 	int maxDisplayedTexts; //hiw many texts can be displayed simultaneously | ||||
| 	struct TextState | ||||
| 	{ | ||||
| 		std::string text; | ||||
| 		uint32_t timeOnScreen; | ||||
| 	}; | ||||
|  | ||||
| 	/// Currently visible texts in the overlay | ||||
| 	std::vector<TextState> texts; | ||||
|  | ||||
| 	/// protects texts | ||||
| 	boost::mutex texts_mx; | ||||
|  | ||||
| 	/// previously entered texts, for up/down arrows to work | ||||
| 	std::vector<std::string> previouslyEntered; | ||||
|  | ||||
| 	/// displayed entry from previouslyEntered - if none it's -1 | ||||
| 	int prevEntDisp; | ||||
|  | ||||
| 	/// timeout for new texts (in ms) | ||||
| 	static constexpr int defaultTimeout = 10000; | ||||
|  | ||||
| 	/// how many texts can be displayed simultaneously | ||||
| 	static constexpr int maxDisplayedTexts = 10; | ||||
|  | ||||
| 	std::weak_ptr<IStatusBar> currentStatusBar; | ||||
| 	std::string enteredText; | ||||
| @@ -27,7 +44,9 @@ private: | ||||
| public: | ||||
| 	void print(const std::string & txt); | ||||
|  | ||||
| 	void tick(uint32_t msPassed) override; | ||||
| 	void show(SDL_Surface * to) override; | ||||
| 	void showAll(SDL_Surface * to) override; | ||||
| 	void keyPressed(const SDL_Keycode & key) override; | ||||
| 	void textInputed(const std::string & enteredText) override; | ||||
| 	void textEdited(const std::string & enteredText) override; | ||||
|   | ||||
| @@ -254,12 +254,22 @@ void CInfoBar::showSelection() | ||||
| 	showGameStatus();//FIXME: may be incorrect but shouldn't happen in general | ||||
| } | ||||
|  | ||||
| void CInfoBar::tick() | ||||
| void CInfoBar::tick(uint32_t msPassed) | ||||
| { | ||||
| 	assert(timerCounter > 0); | ||||
|  | ||||
| 	if (msPassed >= timerCounter) | ||||
| 	{ | ||||
| 		timerCounter = 0; | ||||
| 		removeUsedEvents(TIME); | ||||
| 		if(GH.topInt() == adventureInt) | ||||
| 			popComponents(true); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		timerCounter -= msPassed; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CInfoBar::clickLeft(tribool down, bool previousState) | ||||
| { | ||||
| @@ -290,6 +300,7 @@ void CInfoBar::hover(bool on) | ||||
|  | ||||
| CInfoBar::CInfoBar(const Rect & position) | ||||
| 	: CIntObject(LCLICK | RCLICK | HOVER, position.topLeft()), | ||||
| 	timerCounter(0), | ||||
| 	state(EMPTY) | ||||
| { | ||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); | ||||
| @@ -302,6 +313,14 @@ CInfoBar::CInfoBar(const Point & position): CInfoBar(Rect(position.x, position.y | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| void CInfoBar::setTimer(uint32_t msToTrigger) | ||||
| { | ||||
| 	if (!(active & TIME)) | ||||
| 		addUsedEvents(TIME); | ||||
| 	timerCounter = msToTrigger; | ||||
| } | ||||
|  | ||||
| void CInfoBar::showDate() | ||||
| { | ||||
| 	OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE); | ||||
| @@ -312,7 +331,6 @@ void CInfoBar::showDate() | ||||
| 	redraw(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void CInfoBar::pushComponents(const std::vector<Component> & components, std::string message, int timer) | ||||
| { | ||||
| 	auto actualPush = [&](const std::vector<Component> & components, std::string message, int timer, size_t max){ | ||||
|   | ||||
| @@ -138,6 +138,7 @@ private: | ||||
|  | ||||
| 	std::shared_ptr<CVisibleInfo> visibleInfo; | ||||
| 	EState state; | ||||
| 	uint32_t timerCounter; | ||||
| 	bool shouldPopAll = false; | ||||
|  | ||||
| 	std::queue<std::pair<VisibleComponentInfo::Cache, int>> componentsQueue; | ||||
| @@ -151,13 +152,14 @@ private: | ||||
| 	//removes all information about current state, deactivates timer (if any) | ||||
| 	void reset(); | ||||
|  | ||||
| 	void tick() override; | ||||
| 	void tick(uint32_t msPassed) override; | ||||
|  | ||||
| 	void clickLeft(tribool down, bool previousState) override; | ||||
| 	void clickRight(tribool down, bool previousState) override; | ||||
| 	void hover(bool on) override; | ||||
|  | ||||
| 	void playNewDaySound(); | ||||
| 	void setTimer(uint32_t msToTrigger); | ||||
| public: | ||||
| 	CInfoBar(const Rect & pos); | ||||
| 	CInfoBar(const Point & pos); | ||||
|   | ||||
| @@ -192,7 +192,7 @@ void CGuiHandler::updateTime() | ||||
| 	for (auto & elem : hlp) | ||||
| 	{ | ||||
| 		if(!vstd::contains(timeinterested,elem)) continue; | ||||
| 		(elem)->onTimer(ms); | ||||
| 		(elem)->tick(ms); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -29,7 +29,6 @@ CIntObject::CIntObject(int used_, Point pos_): | ||||
| 	active(active_m) | ||||
| { | ||||
| 	hovered = captureAllKeys = strongInterest = false; | ||||
| 	toNextTick = timerDelay = 0; | ||||
| 	used = used_; | ||||
|  | ||||
| 	recActions = defActions = GH.defActionsDef; | ||||
| @@ -60,24 +59,6 @@ CIntObject::~CIntObject() | ||||
| 		parent_m->removeChild(this); | ||||
| } | ||||
|  | ||||
| void CIntObject::setTimer(int msToTrigger) | ||||
| { | ||||
| 	if (!(active & TIME)) | ||||
| 		activate(TIME); | ||||
| 	toNextTick = timerDelay = msToTrigger; | ||||
| 	used |= TIME; | ||||
| } | ||||
|  | ||||
| void CIntObject::onTimer(int timePassed) | ||||
| { | ||||
| 	toNextTick -= timePassed; | ||||
| 	if (toNextTick < 0) | ||||
| 	{ | ||||
| 		toNextTick += timerDelay; | ||||
| 		tick(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CIntObject::show(SDL_Surface * to) | ||||
| { | ||||
| 	if(defActions & UPDATE) | ||||
|   | ||||
| @@ -65,14 +65,8 @@ class CIntObject : public IShowActivatable //interface object | ||||
| { | ||||
| 	ui16 used;//change via addUsed() or delUsed | ||||
|  | ||||
| 	//time handling | ||||
| 	int toNextTick; | ||||
| 	int timerDelay; | ||||
|  | ||||
| 	std::map<MouseButton, bool> currentMouseState; | ||||
|  | ||||
| 	void onTimer(int timePassed); | ||||
|  | ||||
| 	//non-const versions of fields to allow changing them in CIntObject | ||||
| 	CIntObject *parent_m; //parent object | ||||
| 	ui16 active_m; | ||||
| @@ -129,8 +123,7 @@ public: | ||||
| 	virtual void mouseMoved (const Point & cursorPosition){} | ||||
|  | ||||
| 	//time handling | ||||
| 	void setTimer(int msToTrigger);//set timer delay and activate timer if needed. | ||||
| 	virtual void tick(){} | ||||
| 	virtual void tick(uint32_t msPassed){} | ||||
|  | ||||
| 	//mouse wheel | ||||
| 	virtual void wheelScrolled(bool down, bool in){} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user