💿🐜 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.

138 lines
3.6 KiB

  1. /*
  2. * Copyright (C) 2020 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 <cstdlib>
  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. };
  88. template <typename T>
  89. void event_dispatcher::subscribe(event_handler<T>* handler)
  90. {
  91. to_subscribe.push_back(std::make_tuple(handler->get_handled_event_type_id(), handler));
  92. }
  93. template <typename T>
  94. void event_dispatcher::unsubscribe(event_handler<T>* handler)
  95. {
  96. to_unsubscribe.push_back(std::make_tuple(handler->get_handled_event_type_id(), handler));
  97. }
  98. inline void event_dispatcher::queue(const event_base& event)
  99. {
  100. queued_events.push_back(event.clone());
  101. }
  102. inline void event_dispatcher::schedule(const event_base& event, double time)
  103. {
  104. scheduled_events.insert(std::pair<double, event_base*>(time, event.clone()));
  105. }
  106. inline void event_dispatcher::dispatch(const event_base& event)
  107. {
  108. // Get list of handlers for this type of event
  109. const std::list<event_handler_base*>& handlers = handler_map[event.get_event_type_id()];
  110. // For each handler
  111. for (auto handler = handlers.begin(); handler != handlers.end(); ++handler)
  112. {
  113. // Pass event to the handler
  114. (*handler)->route_event(event);
  115. }
  116. }
  117. #endif // ANTKEEPER_EVENT_DISPATCHER_HPP