35#define __DeclareMsg(NAME, FOURCC, ...) \
36class NAME : public Game::Message<NAME, __VA_ARGS__> \
42 constexpr static const char* GetName() \
47 constexpr static const uint GetFourCC() \
53#define __RegisterMsg(MSGTYPE, FUNCTION) \
54 MSGTYPE::Register(MSGTYPE::Delegate::FromFunction<FUNCTION>())
56#define __this_RegisterMsg(MSGTYPE, METHOD) \
57 MSGTYPE::Register(MSGTYPE::Delegate::FromMethod<std::remove_pointer<decltype(this)>::type, &std::remove_pointer<decltype(this)>::type::METHOD>(this))
61using UnqualifiedType =
typename std::remove_const<typename std::remove_reference<T>::type>::type;
80template <
class MSG,
class ... TYPES>
105 static void Send(TYPES ... values);
172 template<std::size_t...Is>
175 this->
callbacks.Get<1>(cid)(std::get<Is>(data.Get<0>(index))...);
180 this->
send_expander(data, cid, index, std::make_index_sequence<
sizeof...(TYPES)>());
187template <
typename MSG,
class ... TYPES>
191 this->name = MSG::GetName();
192 this->fourcc = MSG::GetFourCC();
198template <
typename MSG,
class ... TYPES>
208template <
typename MSG,
class ... TYPES>
213 Instance()->listenerPool.Allocate(l.id);
214 IndexT index = Instance()->callbacks.Alloc();
215 Instance()->callbacks.Set(index, l, callback);
216 Instance()->listenerMap.Add(l, index);
224template <
typename MSG,
class ... TYPES>
228 auto instance = Instance();
233 instance->listenerMap.Erase(listener.
listenerId);
234 instance->callbacks.EraseIndexSwap(index);
235 if (instance->callbacks.Size() != 0)
237 instance->listenerMap[instance->callbacks.Get<0>(index)] = index;
245template <
typename MSG,
class ... TYPES>
249 auto instance = Instance();
250 SizeT size = instance->callbacks.Size();
251 for (
SizeT i = 0; i < size; ++i)
254 instance->callbacks.Get<1>(i)(values...);
261template<
typename MSG,
class ...TYPES>
262inline typename Message<MSG, TYPES...>::MessageQueueId
265 auto instance = Instance();
267 instance->messageQueueIdPool.Allocate(
id.
id);
269 if (
Ids::Index(
id.
id) >= instance->messageQueues.Size())
273 instance->messageQueues.Append({});
279template<
typename MSG,
class ...TYPES>
283 auto instance = Instance();
286 auto i = instance->messageQueues[index].Alloc();
287 instance->messageQueues[index].Set(i, std::make_tuple(values...));
293template<
typename MSG,
class ... TYPES>
297 auto instance = Instance();
300 n_assert(instance->messageQueueIdPool.IsValid(
id.id));
302 auto& data = instance->messageQueues[
Ids::Index(
id.
id)];
304 SizeT size = data.Size();
305 SizeT cidSize = instance->callbacks.Size();
307 for (
SizeT cid = 0; cid < cidSize; ++cid)
309 for (
SizeT i = 0; i < size; i++)
311 instance->send_expander(data, cid, i);
322template<
typename MSG,
class ...TYPES>
inline void
325 auto instance = Instance();
328 n_assert(instance->messageQueueIdPool.IsValid(
id.id));
330 instance->messageQueues[
Ids::Index(
id.
id)].Clear();
331 instance->messageQueueIdPool.Deallocate(
id.
id);
334template<
typename MSG,
class ...TYPES>
inline bool
344template <
typename MSG,
class ... TYPES>
348 n_error(
"Network distributed messages not yet supported!");
354template <
typename MSG,
class ... TYPES>
358 auto instance = Instance();
359 SizeT size = instance->callbacks.Size();
360 for (
SizeT i = 0; i < size; i++)
362 instance->listenerPool.Deallocate((instance->callbacks.template Get<0>(i)).id);
364 instance->callbacks.Clear();
365 instance->distributedMessages.Clear();
366 instance->listenerMap.Clear();
372template <
typename MSG,
class ... TYPES>
382template <
typename MSG,
class ... TYPES>
383inline typename Message<MSG, TYPES...>::MessageQueue&
typename std::remove_const< typename std::remove_reference< T >::type >::type UnqualifiedType
Removes const reference from T.
Definition message.h:61
void send_expander(MessageQueue &data, const IndexT cid, const SizeT index, std::index_sequence< Is... >)
Definition message.h:173
typename Util::ArrayAllocator< Util::Tuple< UnqualifiedType< TYPES > ... > > MessageQueue
Type definition for this message's queues.
Definition message.h:96
static void Send(TYPES ... values)
Send a message.
Definition message.h:247
static Message< MSG, TYPES... > * Instance()
Definition message.h:138
static void DeAllocateMessageQueue(MessageQueueId id)
Deallocate a message queue. All messages in the queue will be destroyed.
Definition message.h:323
~Message()
Definition message.h:200
Ids::IdGenerationPool listenerPool
Definition message.h:168
Ids::IdGenerationPool messageQueueIdPool
id generation pool for the deferred messages queues.
Definition message.h:156
Util::ArrayAllocator< MessageListenerId, Delegate > callbacks
contains the callback and the listener it's attached to.
Definition message.h:153
static bool IsValid(MessageListenerId listener)
Returns whether a MessageListenerId is still registered or not.
Definition message.h:374
static MessageQueueId AllocateMessageQueue()
Creates a new message queue for deferred dispatching.
Definition message.h:263
MessageQueue distributedMessages
Contains the arguments of a recieved distributed message.
Definition message.h:163
Util::FourCC fourcc
Definition message.h:167
static MessageListener Register(Delegate &&callback)
Register a listener to this message. Returns an ID for the listener so that we can associate it.
Definition message.h:210
Util::StringAtom name
Definition message.h:166
static bool IsMessageQueueValid(MessageQueueId id)
Check whether a message queue is still valid.
Definition message.h:335
static void Distribute(TYPES ...)
Send a network distributed message.
Definition message.h:346
void send_expander(MessageQueue &data, const IndexT cid, const SizeT index)
Definition message.h:178
Message()
Definition message.h:189
static void DispatchMessageQueue(MessageQueueId id)
Dispatch all messages in a message queue.
Definition message.h:295
static void Defer(MessageQueueId qid, TYPES ... values)
Add a message to a message queue.
Definition message.h:281
friend MSG
Definition message.h:136
static void Deregister(MessageListener listener)
Deregister a listener.
Definition message.h:226
static void DeregisterAll()
Deregisters all listeners at once.
Definition message.h:356
Util::Array< MessageQueue > messageQueues
Deferred messages.
Definition message.h:159
Util::HashTable< MessageListenerId, IndexT > listenerMap
Internal singleton instance.
Definition message.h:147
void operator=(const Message< MSG, TYPES... > &)=delete
static MessageQueue & GetMessageQueue(MessageQueueId id)
Returns a message queue by id Can be used to manually dispatch queues.
Definition message.h:384
Provides a system for creating array friendly id numbers with reuse and generations.
Definition idgenerationpool.h:43
bool IsValid(Id32 id) const
check if valid
Definition idgenerationpool.cc:66
The ArrayAllocator provides a variadic list of types which is to be contained in the allocator and fe...
Definition arrayallocator.h:34
Nebula's dynamic array class.
Definition array.h:60
Nebula delegate class, allows to store a function, method or lambda call into a C++ object for later ...
Definition delegate.h:39
A four-character-code is a quasi-human-readable 32-bit-id.
Definition fourcc.h:19
Organizes key/value pairs by a hash code.
Definition hashtable.h:42
A StringAtom.
Definition stringatom.h:22
void __cdecl n_error(const char *msg,...)
This function is called when a serious situation is encountered which requires abortion of the applic...
Definition debug.cc:138
#define n_assert(exp)
Definition debug.h:50
#define ID_32_TYPE(x)
Definition id.h:16
Game::EditorState.
Definition orientation.h:7
static constexpr Id24 Index(const Id32 id)
Definition idgenerationpool.h:70
Util::FourCC messageId
Definition message.h:73
MessageListenerId listenerId
Definition message.h:74
static const int InvalidIndex
Definition types.h:54
int SizeT
Definition types.h:49
int IndexT
Definition types.h:48