invoke_queued.h 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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. #include <QtCore/QEvent>
  9. #include <QtCore/QCoreApplication>
  10. #include "base/basic_types.h"
  11. namespace base {
  12. class InvokeQueuedEvent : public QEvent {
  13. public:
  14. static auto Type() {
  15. static const auto Result = QEvent::Type(QEvent::registerEventType());
  16. return Result;
  17. }
  18. explicit InvokeQueuedEvent(FnMut<void()> &&method)
  19. : QEvent(Type())
  20. , _method(std::move(method)) {
  21. }
  22. void invoke() {
  23. _method();
  24. }
  25. private:
  26. FnMut<void()> _method;
  27. };
  28. } // namespace base
  29. template <typename Lambda>
  30. inline void InvokeQueued(const QObject *context, Lambda &&lambda) {
  31. QCoreApplication::postEvent(
  32. const_cast<QObject*>(context),
  33. new base::InvokeQueuedEvent(std::forward<Lambda>(lambda)));
  34. }
  35. class SingleQueuedInvokation : public QObject {
  36. public:
  37. SingleQueuedInvokation(Fn<void()> callback) : _callback(callback) {
  38. }
  39. void call() {
  40. if (_pending.testAndSetAcquire(0, 1)) {
  41. InvokeQueued(this, [this] {
  42. if (_pending.testAndSetRelease(1, 0)) {
  43. _callback();
  44. }
  45. });
  46. }
  47. }
  48. private:
  49. Fn<void()> _callback;
  50. QAtomicInt _pending = { 0 };
  51. };