Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
	Author : Tobias Stein
	Date   : 9th July, 2016
	File   : EventHandler.h

	EventHandler class.

	All Rights Reserved. (c) Copyright 2016.
*/

#ifndef __EVENT_HANDLER_H__
#define __EVENT_HANDLER_H__


#include "API.h"

#include "Memory/Allocator/LinearAllocator.h"

#include "IEvent.h"
#include "EventDispatcher.h"

namespace ECS { namespace Event {

	class ECS_API EventHandler : Memory::GlobalMemoryUser
	{
		// allow IEventListener access private methods for Add/Remove callbacks
		friend class ECSEngine;
	

		using EventDispatcherMap = std::unordered_map<EventTypeId, Internal::IEventDispatcher*>;
	
		using EventStorage = std::vector<IEvent*>;
	
		using EventMemoryAllocator = Memory::Allocator::LinearAllocator;
	
		DECLARE_LOGGER

	private:
		
		EventHandler(const EventHandler&);
		EventHandler& operator=(EventHandler&);
	
		EventDispatcherMap			m_EventDispatcherMap;
		
	
		EventMemoryAllocator*		m_EventMemoryAllocator;

		// Holds a list of all sent events since last EventHandler::DispatchEvents() call
		EventStorage				m_EventStorage;
	
	
		// Add event callback
		template<class E>
		inline void AddEventCallback(Internal::IEventDelegate* const eventDelegate)
		{
			EventTypeId ETID = E::STATIC_EVENT_TYPE_ID;

			EventDispatcherMap::const_iterator iter = this->m_EventDispatcherMap.find(ETID);
			if (iter == this->m_EventDispatcherMap.end())
			{
				std::pair<EventTypeId, Internal::IEventDispatcher*> kvp(ETID, new Internal::EventDispatcher<E>());
	
				kvp.second->AddEventCallback(eventDelegate);
	
				this->m_EventDispatcherMap.insert(kvp);
			}
			else
			{
				this->m_EventDispatcherMap[ETID]->AddEventCallback(eventDelegate);
			}
	
		}
	
		// Remove event callback
		inline void RemoveEventCallback(Internal::IEventDelegate* eventDelegate)
		{
			auto typeId = eventDelegate->GetStaticEventTypeId();
			EventDispatcherMap::const_iterator iter = this->m_EventDispatcherMap.find(typeId);
			if (iter != this->m_EventDispatcherMap.end())
			{
				this->m_EventDispatcherMap[typeId]->RemoveEventCallback(eventDelegate);
			}
		}
	
	
	
	public:
	
		EventHandler();
		~EventHandler();
	
		// clear buffer, that is, simply reset index buffer
		inline void ClearEventBuffer()
		{
			this->m_EventMemoryAllocator->clear();
			this->m_EventStorage.clear();
		}
	
		inline void ClearEventDispatcher()
		{
			this->m_EventDispatcherMap.clear();
		}
	
		template<class E, class... ARGS>
		void Send(ARGS&&... eventArgs)
		{
			// check if type of object is trivially copyable
			static_assert(std::is_trivially_copyable<E>::value, "Event is not trivially copyable.");
	
	
			// allocate memory to store event data
			void* pMem = this->m_EventMemoryAllocator->allocate(sizeof(E), alignof(E));

			// add new event to buffer and event storage
			if (pMem != nullptr)
			{
				this->m_EventStorage.push_back(new (pMem)E(std::forward<ARGS>(eventArgs)...));

				LogInfo("\'%s\' event buffered.", typeid(E).name());
			}
			else
			{
				LogWarning("Event buffer is full! Cut off new incoming events !!!");
			}
		}
	
		// dispatches all stores events and clears buffer
		void DispatchEvents()
		{
			size_t lastIndex = this->m_EventStorage.size();
			size_t thisIndex = 0;

			while (thisIndex < lastIndex)
			{
				auto event = this->m_EventStorage[thisIndex++];
				if (event == nullptr)
				{
					LogError("Skip corrupted event.", event->GetEventTypeID());
					continue;
				}

				auto it = this->m_EventDispatcherMap.find(event->GetEventTypeID());
				if (it == this->m_EventDispatcherMap.end())
					continue;
	
				it->second->Dispatch(event);

				// update last index, after dispatch operation there could be new events
				lastIndex = this->m_EventStorage.size();
			}
			
			// reset
			ClearEventBuffer();
		}
	};

}} // namespace ECS::Event

#endif // __EVENT_HANDLER_H__ 

Commits for Divide-Framework/trunk/Source Code/Libs/EntityComponentSystem/include/ECS/Event/EventHandler.h

Diff revisions: vs.
Revision Author Commited Message
1021 Diff Diff IonutCava picture IonutCava Sun 21 Jan, 2018 22:19:16 +0000

[Ionut]
- Performance optimizations

991 IonutCava picture IonutCava Tue 05 Dec, 2017 23:51:14 +0000