Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
EventHandler.h
Go to the documentation of this file.
1/*
2 Author : Tobias Stein
3 Date : 9th July, 2016
4 File : EventHandler.h
5
6 EventHandler class.
7
8 All Rights Reserved. (c) Copyright 2016.
9*/
10
11#pragma once
12#ifndef ECS__EVENT_HANDLER_H__
13#define ECS__EVENT_HANDLER_H__
14
15
16#include "API.h"
17
19
20#include "IEvent.h"
21#include "EventDispatcher.h"
22
23namespace ECS { namespace Event {
24
26 {
27 // allow IEventListener access private methods for Add/Remove callbacks
28 friend class ECS::ECSEngine;
29
31
33
35
37
38
39 EventHandler(const EventHandler&) = delete;
41
43
44
46
47 // Holds a list of all sent events since last EventHandler::DispatchEvents() call
49
50
51 // Add event callback
52 template<class E>
53 inline void AddEventCallback(Internal::IEventDelegate* const eventDelegate)
54 {
55 EventTypeId ETID = E::STATIC_EVENT_TYPE_ID;
56
57 EventDispatcherMap::const_iterator iter = this->m_EventDispatcherMap.find(ETID);
58 if (iter == this->m_EventDispatcherMap.end())
59 {
60 eastl::pair<EventTypeId, Internal::IEventDispatcher*> kvp(ETID, new Internal::EventDispatcher<E>());
61
62 kvp.second->AddEventCallback(eventDelegate);
63
64 this->m_EventDispatcherMap.insert(kvp);
65 }
66 else
67 {
68 this->m_EventDispatcherMap[ETID]->AddEventCallback(eventDelegate);
69 }
70
71 }
72
73 // Remove event callback
75 {
76 const auto typeId = eventDelegate->GetStaticEventTypeId();
77 const EventDispatcherMap::const_iterator iter = this->m_EventDispatcherMap.find(typeId);
78 if (iter != this->m_EventDispatcherMap.end())
79 {
80 this->m_EventDispatcherMap[typeId]->RemoveEventCallback(eventDelegate);
81 }
82 }
83
84
85
86 public:
87
90
91 // clear buffer, that is, simply reset index buffer
92 inline void ClearEventBuffer()
93 {
94 this->m_EventMemoryAllocator->clear();
95 this->m_EventStorage.clear();
96 }
97
99 {
100 this->m_EventDispatcherMap.clear();
101 }
102
103 template<class E, class... ARGS>
104 void Send(ECSEngine* engine, ARGS&&... eventArgs)
105 {
106 // check if type of object is trivially copyable
107 static_assert(std::is_trivially_copyable<E>::value, "Event is not trivially copyable.");
108
109
110 // allocate memory to store event data
111 void* pMem = this->m_EventMemoryAllocator->allocate(sizeof(E), alignof(E));
112
113 // add new event to buffer and event storage
114 if (pMem != nullptr)
115 {
116 this->m_EventStorage.push_back(new (pMem)E(engine, FWD(eventArgs)...));
117
118 LOG_INFO("\'{}\' event buffered.", typeid(E).name());
119 }
120 else
121 {
122 LOG_WARNING("Event buffer is full! Cut off new incoming events !!!");
123 }
124 }
125
126 template<class E, class... ARGS>
127 void SendAndDispatchEvent(ECSEngine* engine, ARGS&&... eventArgs)
128 {
129 void* pMem = this->m_EventMemoryAllocator->allocate(sizeof(E), alignof(E));
130 auto event = new (pMem)E(engine, FWD(eventArgs)...);
131 auto it = this->m_EventDispatcherMap.find(event->GetEventTypeID());
132 if (it != eastl::cend(this->m_EventDispatcherMap)) {
133 it->second->Dispatch(event);
134 }
135 }
136
137 // dispatches all stores events and clears buffer
139 {
141
142 size_t lastIndex = this->m_EventStorage.size();
143 size_t thisIndex = 0;
144
145 while (thisIndex < lastIndex)
146 {
147 IEvent* event = this->m_EventStorage[thisIndex++];
148 if (event != nullptr) {
149 const auto it = this->m_EventDispatcherMap.find(event->GetEventTypeID());
150 if (it != eastl::cend(this->m_EventDispatcherMap)) {
151 it->second->Dispatch(event);
152 // update last index, after dispatch operation there could be new events
153 lastIndex = this->m_EventStorage.size();
154 }
155 } else {
156 LOG_ERROR("Skip corrupted event [ {} ]", event->GetEventTypeID());
157 continue;
158 }
159 }
160
161 // reset
162 ClearEventBuffer();
163 }
164 };
165
166}} // namespace ECS::Event
167
168#endif // ECS__EVENT_HANDLER_H__
#define LOG_WARNING(format,...)
Definition: LoggerMacro.h:26
#define DECLARE_LOGGER
Definition: LoggerMacro.h:15
#define LOG_INFO(format,...)
Definition: LoggerMacro.h:25
#define LOG_ERROR(format,...)
Definition: LoggerMacro.h:27
#define ECS_API
Definition: Platform.h:16
#define FWD(...)
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
EventHandler & operator=(EventHandler &)=delete
void RemoveEventCallback(Internal::IEventDelegate *eventDelegate)
Definition: EventHandler.h:74
EventStorage m_EventStorage
Definition: EventHandler.h:48
void SendAndDispatchEvent(ECSEngine *engine, ARGS &&... eventArgs)
Definition: EventHandler.h:127
EventMemoryAllocator * m_EventMemoryAllocator
Definition: EventHandler.h:45
Divide::hashMap< EventTypeId, Internal::IEventDispatcher * > EventDispatcherMap
Definition: EventHandler.h:30
Divide::vector< IEvent * > EventStorage
Definition: EventHandler.h:32
void AddEventCallback(Internal::IEventDelegate *const eventDelegate)
Definition: EventHandler.h:53
EventDispatcherMap m_EventDispatcherMap
Definition: EventHandler.h:42
DECLARE_LOGGER EventHandler(const EventHandler &)=delete
void Send(ECSEngine *engine, ARGS &&... eventArgs)
Definition: EventHandler.h:104
virtual u64 GetStaticEventTypeId() const =0
virtual void * allocate(size_t size, u8 alignment) override
constexpr Optick::Category::Type GameLogic
Definition: Profiler.h:63
eastl::vector< Type > vector
Definition: Vector.h:42
hashAlg::unordered_map< K, V, HashFun, Predicate > hashMap
Definition: HashMap.h:55
TypeID EventTypeId
Definition: IEvent.h:22