💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
3.5 KiB

  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_EVENT_DISPATCHER_HPP
  20. #define ANTKEEPER_EVENT_DISPATCHER_HPP
  21. #include "event.hpp"
  22. #include "event-handler.hpp"
  23. #include <cstddef>
  24. #include <list>
  25. #include <map>
  26. /**
  27. * Queues events and dispatches them to event handlers.
  28. */
  29. class event_dispatcher
  30. {
  31. public:
  32. /// Creates an event dispatcher
  33. event_dispatcher();
  34. /// Destroys an event dispatcher
  35. ~event_dispatcher();
  36. /**
  37. * Processes all pending subscriptions and unsubscriptions, dispatches queued events, then dispatches due scheduled events.
  38. *
  39. * @param time The current time.
  40. */
  41. void update(double time);
  42. /**
  43. * Subscribes an event handler to event dispatches.
  44. *
  45. * @param handler Handler to subscribe.
  46. */
  47. template <typename T>
  48. void subscribe(event_handler<T>* handler);
  49. /**
  50. * Unsubscribes an event handler from event dispatches.
  51. *
  52. * @param handler Handler to unsubscribe.
  53. */
  54. template <typename T>
  55. void unsubscribe(event_handler<T>* handler);
  56. /**
  57. * Adds an event to the queue.
  58. *
  59. * @param event Event to queue.
  60. */
  61. void queue(const event_base& event);
  62. /**
  63. * Schedules an event to be dispatched at a specific time.
  64. *
  65. * @param event Event to schedule.
  66. * @param time Time that the event should be dispatched.
  67. */
  68. void schedule(const event_base& event, double time);
  69. /**
  70. * Dispatches a single event.
  71. *
  72. * @param event Event to dispatch.
  73. */
  74. void dispatch(const event_base& event);
  75. /**
  76. * Dispatches all events in the queue.
  77. */
  78. void flush();
  79. /// Removes all queued and scheduled events from the queue without notifying handlers.
  80. void clear();
  81. private:
  82. std::list<std::tuple<std::size_t, event_handler_base*>> to_subscribe;
  83. std::list<std::tuple<std::size_t, event_handler_base*>> to_unsubscribe;
  84. std::map<std::size_t, std::list<event_handler_base*>> handler_map;
  85. std::list<event_base*> queued_events;
  86. std::multimap<double, event_base*> scheduled_events;
  87. bool updating;
  88. };
  89. template <typename T>
  90. void event_dispatcher::subscribe(event_handler<T>* handler)
  91. {
  92. if (updating)
  93. {
  94. to_subscribe.push_back(std::make_tuple(handler->get_handled_event_type_id(), handler));
  95. }
  96. else
  97. {
  98. handler_map[handler->get_handled_event_type_id()].push_back(handler);
  99. }
  100. }
  101. template <typename T>
  102. void event_dispatcher::unsubscribe(event_handler<T>* handler)
  103. {
  104. if (updating)
  105. {
  106. to_unsubscribe.push_back(std::make_tuple(handler->get_handled_event_type_id(), handler));
  107. }
  108. else
  109. {
  110. handler_map[handler->get_handled_event_type_id()].remove(handler);
  111. }
  112. }
  113. inline void event_dispatcher::queue(const event_base& event)
  114. {
  115. queued_events.push_back(event.clone());
  116. }
  117. inline void event_dispatcher::schedule(const event_base& event, double time)
  118. {
  119. scheduled_events.insert(std::pair<double, event_base*>(time, event.clone()));
  120. }
  121. #endif // ANTKEEPER_EVENT_DISPATCHER_HPP