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 #include "base/observer.h" 8 9 namespace base { 10 namespace internal { 11 namespace { 12 13 bool CantUseObservables = false; 14 void (*HandleDelayedMethod)() = nullptr; 15 16 struct ObservableListWrap { ~ObservableListWrapbase::internal::__anon881c9c6d0111::ObservableListWrap17 ~ObservableListWrap() { 18 CantUseObservables = true; 19 } 20 OrderedSet<ObservableCallHandlers*> list; 21 }; 22 PendingObservables()23ObservableListWrap &PendingObservables() { 24 static ObservableListWrap result; 25 return result; 26 } 27 ActiveObservables()28ObservableListWrap &ActiveObservables() { 29 static ObservableListWrap result; 30 return result; 31 } 32 33 } // namespace 34 RegisterPendingObservable(ObservableCallHandlers * handlers)35void RegisterPendingObservable(ObservableCallHandlers *handlers) { 36 if (CantUseObservables) return; 37 PendingObservables().list.insert(handlers); 38 if (HandleDelayedMethod) { 39 HandleDelayedMethod(); 40 } 41 } 42 UnregisterActiveObservable(ObservableCallHandlers * handlers)43void UnregisterActiveObservable(ObservableCallHandlers *handlers) { 44 if (CantUseObservables) return; 45 ActiveObservables().list.remove(handlers); 46 } 47 UnregisterObservable(ObservableCallHandlers * handlers)48void UnregisterObservable(ObservableCallHandlers *handlers) { 49 if (CantUseObservables) return; 50 PendingObservables().list.remove(handlers); 51 ActiveObservables().list.remove(handlers); 52 } 53 54 } // namespace internal 55 InitObservables(void (* HandleDelayed)())56void InitObservables(void(*HandleDelayed)()) { 57 internal::HandleDelayedMethod = HandleDelayed; 58 } 59 HandleObservables()60void HandleObservables() { 61 if (internal::CantUseObservables) return; 62 auto &active = internal::ActiveObservables().list; 63 qSwap(active, internal::PendingObservables().list); 64 while (!active.empty()) { 65 auto first = *active.begin(); 66 (*first)(); 67 if (!active.empty() && *active.begin() == first) { 68 active.erase(active.begin()); 69 } 70 } 71 } 72 ObservableViewer(base::Observable<void> & observable)73rpl::producer<> ObservableViewer(base::Observable<void> &observable) { 74 return [&observable](const auto &consumer) { 75 auto lifetime = rpl::lifetime(); 76 lifetime.make_state<base::Subscription>( 77 observable.add_subscription([consumer]() { 78 consumer.put_next({}); 79 })); 80 return lifetime; 81 }; 82 } 83 84 } // namespace base 85