mirror of https://github.com/procxx/kepka.git
				
				
				
			Fix new animations engine restarts.
This commit is contained in:
		
							parent
							
								
									b0ff443eac
								
							
						
					
					
						commit
						aa00f9bd34
					
				|  | @ -20,19 +20,37 @@ constexpr auto kIgnoreUpdatesTimeout = crl::time(4); | ||||||
| } // namespace
 | } // namespace
 | ||||||
| 
 | 
 | ||||||
| void Basic::start() { | void Basic::start() { | ||||||
| 	if (!animating()) { | 	if (animating()) { | ||||||
|  | 		restart(); | ||||||
|  | 	} else { | ||||||
| 		Core::App().animationManager().start(this); | 		Core::App().animationManager().start(this); | ||||||
| 	} | 	} | ||||||
| 	_started = crl::now(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Basic::stop() { | void Basic::stop() { | ||||||
| 	if (animating()) { | 	if (animating()) { | ||||||
| 		Core::App().animationManager().stop(this); | 		Core::App().animationManager().stop(this); | ||||||
| 		_started = -1; |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Basic::restart() { | ||||||
|  | 	Expects(_started >= 0); | ||||||
|  | 
 | ||||||
|  | 	_started = crl::now(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Basic::markStarted() { | ||||||
|  | 	Expects(_started < 0); | ||||||
|  | 
 | ||||||
|  | 	_started = crl::now(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Basic::markStopped() { | ||||||
|  | 	Expects(_started >= 0); | ||||||
|  | 
 | ||||||
|  | 	_started = -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Manager::Manager() { | Manager::Manager() { | ||||||
| 	Core::Sandbox::Instance().widgetUpdateRequests( | 	Core::Sandbox::Instance().widgetUpdateRequests( | ||||||
| 	) | rpl::start_with_next([=] { | 	) | rpl::start_with_next([=] { | ||||||
|  | @ -42,28 +60,30 @@ Manager::Manager() { | ||||||
| 
 | 
 | ||||||
| void Manager::start(not_null<Basic*> animation) { | void Manager::start(not_null<Basic*> animation) { | ||||||
| 	if (_updating) { | 	if (_updating) { | ||||||
| 		_starting.push_back(animation); | 		_starting.emplace_back(animation.get()); | ||||||
| 	} else { | 	} else { | ||||||
| 		if (empty(_active)) { | 		if (empty(_active)) { | ||||||
| 			updateQueued(); | 			updateQueued(); | ||||||
| 		} | 		} | ||||||
| 		_active.push_back(animation); | 		_active.emplace_back(animation.get()); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Manager::stop(not_null<Basic*> animation) { | void Manager::stop(not_null<Basic*> animation) { | ||||||
| 	if (empty(_active)) { | 	if (empty(_active) && empty(_starting)) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  | 	const auto value = animation.get(); | ||||||
|  | 	const auto proj = &ActiveBasicPointer::get; | ||||||
|  | 	auto &list = _updating ? _starting : _active; | ||||||
|  | 	list.erase(ranges::remove(list, value, proj), end(list)); | ||||||
|  | 
 | ||||||
| 	if (_updating) { | 	if (_updating) { | ||||||
| 		const auto i = ranges::find(_active, animation.get()); | 		const auto i = ranges::find(_active, value, proj); | ||||||
| 		if (i != end(_active)) { | 		if (i != end(_active)) { | ||||||
| 			*i = nullptr; | 			*i = nullptr; | ||||||
| 		} | 		} | ||||||
| 		return; | 	} else if (empty(_active)) { | ||||||
| 	} |  | ||||||
| 	_active.erase(ranges::remove(_active, animation.get()), end(_active)); |  | ||||||
| 	if (empty(_active)) { |  | ||||||
| 		stopTimer(); | 		stopTimer(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -82,13 +102,17 @@ void Manager::update() { | ||||||
| 	const auto guard = gsl::finally([&] { _updating = false; }); | 	const auto guard = gsl::finally([&] { _updating = false; }); | ||||||
| 
 | 
 | ||||||
| 	_lastUpdateTime = now; | 	_lastUpdateTime = now; | ||||||
| 	_active.erase(ranges::remove_if(_active, [&](Basic *element) { | 	const auto isFinished = [&](const ActiveBasicPointer &element) { | ||||||
| 		return !element || !element->call(now); | 		return !element.call(now); | ||||||
| 	}), end(_active)); | 	}; | ||||||
|  | 	_active.erase(ranges::remove_if(_active, isFinished), end(_active)); | ||||||
| 
 | 
 | ||||||
| 	if (!empty(_starting)) { | 	if (!empty(_starting)) { | ||||||
| 		auto starting = std::move(_starting); | 		_active.insert( | ||||||
| 		_active.insert(end(_active), begin(starting), end(starting)); | 			end(_active), | ||||||
|  | 			std::make_move_iterator(begin(_starting)), | ||||||
|  | 			std::make_move_iterator(end(_starting))); | ||||||
|  | 		_starting.clear(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,6 +37,10 @@ private: | ||||||
| 	[[nodiscard]] static Fn<bool(crl::time)> Prepare(Callback &&callback); | 	[[nodiscard]] static Fn<bool(crl::time)> Prepare(Callback &&callback); | ||||||
| 
 | 
 | ||||||
| 	[[nodiscard]] bool call(crl::time now) const; | 	[[nodiscard]] bool call(crl::time now) const; | ||||||
|  | 	void restart(); | ||||||
|  | 
 | ||||||
|  | 	void markStarted(); | ||||||
|  | 	void markStopped(); | ||||||
| 
 | 
 | ||||||
| 	crl::time _started = -1; | 	crl::time _started = -1; | ||||||
| 	Fn<bool(crl::time)> _callback; | 	Fn<bool(crl::time)> _callback; | ||||||
|  | @ -98,6 +102,50 @@ public: | ||||||
| 	void update(); | 	void update(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | 	class ActiveBasicPointer { | ||||||
|  | 	public: | ||||||
|  | 		ActiveBasicPointer(Basic *value = nullptr) : _value(value) { | ||||||
|  | 			if (_value) { | ||||||
|  | 				_value->markStarted(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		ActiveBasicPointer(ActiveBasicPointer &&other) | ||||||
|  | 		: _value(base::take(other._value)) { | ||||||
|  | 		} | ||||||
|  | 		ActiveBasicPointer &operator=(ActiveBasicPointer &&other) { | ||||||
|  | 			if (_value != other._value) { | ||||||
|  | 				if (_value) { | ||||||
|  | 					_value->markStopped(); | ||||||
|  | 				} | ||||||
|  | 				_value = base::take(other._value); | ||||||
|  | 			} | ||||||
|  | 			return *this; | ||||||
|  | 		} | ||||||
|  | 		~ActiveBasicPointer() { | ||||||
|  | 			if (_value) { | ||||||
|  | 				_value->markStopped(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		[[nodiscard]] bool call(crl::time now) const { | ||||||
|  | 			return _value && _value->call(now); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		friend inline bool operator==( | ||||||
|  | 				const ActiveBasicPointer &a, | ||||||
|  | 				const ActiveBasicPointer &b) { | ||||||
|  | 			return a._value == b._value; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		Basic *get() const { | ||||||
|  | 			return _value; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		Basic *_value = nullptr; | ||||||
|  | 
 | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
| 	friend class Basic; | 	friend class Basic; | ||||||
| 
 | 
 | ||||||
| 	void timerEvent(QTimerEvent *e) override; | 	void timerEvent(QTimerEvent *e) override; | ||||||
|  | @ -113,8 +161,8 @@ private: | ||||||
| 	int _timerId = 0; | 	int _timerId = 0; | ||||||
| 	bool _updating = false; | 	bool _updating = false; | ||||||
| 	bool _scheduled = false; | 	bool _scheduled = false; | ||||||
| 	std::vector<Basic*> _active; | 	std::vector<ActiveBasicPointer> _active; | ||||||
| 	std::vector<not_null<Basic*>> _starting; | 	std::vector<ActiveBasicPointer> _starting; | ||||||
| 	rpl::lifetime _lifetime; | 	rpl::lifetime _lifetime; | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue