1 // This file is part of Desktop App Toolkit, 2 // a set of libraries for developing nice desktop applications. 3 // 4 // For license and copyright information please follow this link: 5 // https://github.com/desktop-app/legal/blob/master/LEGAL 6 // 7 #pragma once 8 9 #include "lottie/lottie_player.h" 10 #include "base/timer.h" 11 #include "base/algorithm.h" 12 #include "base/flat_set.h" 13 #include "base/flat_map.h" 14 15 #include <rpl/event_stream.h> 16 17 namespace Lottie { 18 19 class Animation; 20 class FrameRenderer; 21 22 struct MultiUpdate { 23 //std::variant< 24 // std::pair<Animation*, Information>, 25 // DisplayMultiFrameRequest, 26 // std::pair<Animation*, Error>> data; 27 }; 28 29 class MultiPlayer final : public Player { 30 public: 31 MultiPlayer( 32 Quality quality = Quality::Default, 33 std::shared_ptr<FrameRenderer> renderer = nullptr); 34 ~MultiPlayer(); 35 36 void start( 37 not_null<Animation*> animation, 38 std::unique_ptr<SharedState> state) override; 39 void failed(not_null<Animation*> animation, Error error) override; 40 void updateFrameRequest( 41 not_null<const Animation*> animation, 42 const FrameRequest &request) override; 43 bool markFrameShown() override; 44 void checkStep() override; 45 46 not_null<Animation*> append( 47 const QByteArray &content, 48 const FrameRequest &request); 49 not_null<Animation*> append( 50 FnMut<void(FnMut<void(QByteArray &&cached)>)> get, // Main thread. 51 FnMut<void(QByteArray &&cached)> put, // Unknown thread. 52 const QByteArray &content, 53 const FrameRequest &request); 54 55 rpl::producer<MultiUpdate> updates() const; 56 57 void remove(not_null<Animation*> animation); 58 59 void pause(not_null<Animation*> animation); 60 void unpause(not_null<Animation*> animation); 61 62 private: 63 struct PausedInfo { 64 not_null<SharedState*> state; 65 crl::time pauseTime = kTimeUnknown; 66 crl::time pauseDelay = kTimeUnknown; 67 }; 68 struct StartingInfo { 69 std::unique_ptr<SharedState> state; 70 bool paused = false; 71 }; 72 73 void addNewToActive( 74 not_null<Animation*> animation, 75 StartingInfo &&info); 76 [[nodiscard]] int countFrameIndex( 77 not_null<SharedState*> state, 78 crl::time time, 79 crl::time delay) const; 80 void startAtRightTime(std::unique_ptr<SharedState> state); 81 void processPending(); 82 void markFrameDisplayed(crl::time now); 83 void addTimelineDelay(crl::time delayed); 84 void checkNextFrameAvailability(); 85 void checkNextFrameRender(); 86 void unpauseFirst( 87 not_null<Animation*> animation, 88 not_null<SharedState*> state); 89 void pauseAndSaveState(not_null<Animation*> animation); 90 void unpauseAndKeepUp(not_null<Animation*> animation); 91 void removeNow(not_null<Animation*> animation); 92 93 Quality _quality = Quality::Default; 94 base::Timer _timer; 95 const std::shared_ptr<FrameRenderer> _renderer; 96 std::vector<std::unique_ptr<Animation>> _animations; 97 base::flat_map<not_null<Animation*>, not_null<SharedState*>> _active; 98 base::flat_map<not_null<Animation*>, PausedInfo> _paused; 99 base::flat_set<not_null<Animation*>> _pendingPause; 100 base::flat_set<not_null<Animation*>> _pendingUnpause; 101 base::flat_set<not_null<Animation*>> _pausedBeforeStart; 102 base::flat_set<not_null<Animation*>> _pendingRemove; 103 base::flat_map<not_null<Animation*>, StartingInfo> _pendingToStart; 104 crl::time _started = kTimeUnknown; 105 crl::time _lastSyncTime = kTimeUnknown; 106 crl::time _delay = 0; 107 crl::time _nextFrameTime = kTimeUnknown; 108 rpl::event_stream<MultiUpdate> _updates; 109 rpl::lifetime _lifetime; 110 111 }; 112 113 } // namespace Lottie 114