-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Give entities a way to communicate with each other via the MessageDispatchService. The `MessageInbox` component is used to receive messages. Currently the MessageDispatchService is for entity-to-entity communication. Global events will be handled by another service, although will probably use the same `Message` object with `EventArg` parameters.
- Loading branch information
1 parent
62af3fa
commit 9c05d98
Showing
18 changed files
with
893 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef GL_ADAGIO_EVENTVARIANTTYPE_H | ||
#define GL_ADAGIO_EVENTVARIANTTYPE_H | ||
|
||
#include "../literals/HashString.h" | ||
#include <cstdint> | ||
|
||
namespace Adagio { | ||
enum Type { | ||
TYPE_NULL, TYPE_UINT, TYPE_INT, TYPE_FLOAT, TYPE_BOOL, TYPE_HASH | ||
}; | ||
|
||
struct EventArg { | ||
std::uint32_t eventName{0}; | ||
|
||
Type type{TYPE_NULL}; | ||
|
||
union { | ||
std::uint32_t m_Uint{0}; | ||
std::int32_t m_Int; | ||
float m_Float; | ||
bool m_Bool; | ||
}; | ||
}; | ||
} // namespace Adagio | ||
#endif // GL_ADAGIO_EVENTVARIANTTYPE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#include "Message.h" | ||
#include <stdexcept> | ||
#include <algorithm> | ||
|
||
const Adagio::EventArg *Adagio::Message::getArg(unsigned char index) const { return &argument[index]; } | ||
|
||
Adagio::Message &Adagio::Message::addBoolArg(std::uint32_t eventName, bool value) { | ||
EventArg &arg = getFirstFreeArgument(); | ||
arg.eventName = eventName; | ||
arg.type = Adagio::TYPE_BOOL; | ||
arg.m_Bool = value; | ||
return *this; | ||
} | ||
|
||
Adagio::Message &Adagio::Message::addUintArg(std::uint32_t eventName, std::uint32_t value) { | ||
EventArg &arg = getFirstFreeArgument(); | ||
arg.eventName = eventName; | ||
arg.type = Adagio::TYPE_UINT; | ||
arg.m_Uint = value; | ||
return *this; | ||
} | ||
|
||
Adagio::Message &Adagio::Message::addIntArg(std::uint32_t eventName, std::int32_t value) { | ||
EventArg &arg = getFirstFreeArgument(); | ||
arg.eventName = eventName; | ||
arg.type = Adagio::TYPE_INT; | ||
arg.m_Int = value; | ||
return *this; | ||
} | ||
|
||
Adagio::Message &Adagio::Message::addFloatArg(std::uint32_t eventName, float value) { | ||
EventArg &arg = getFirstFreeArgument(); | ||
arg.eventName = eventName; | ||
arg.type = Adagio::TYPE_FLOAT; | ||
arg.m_Float = value; | ||
return *this; | ||
} | ||
|
||
unsigned char Adagio::Message::getArgumentCount() const { | ||
for (unsigned char i = 0; i < MAX_EVENT_ARGS; i++) { | ||
if (argument[i].type == Adagio::TYPE_NULL) { | ||
return i; | ||
} | ||
} | ||
return MAX_EVENT_ARGS; | ||
} | ||
|
||
void Adagio::Message::nullifyArguments() { | ||
for (auto &a: argument) { | ||
a.eventName = 0; | ||
a.type = Adagio::TYPE_NULL; | ||
a.m_Uint = 0; | ||
} | ||
} | ||
|
||
Adagio::EventArg &Adagio::Message::getFirstFreeArgument() { | ||
unsigned char count = getArgumentCount(); | ||
if (count >= MAX_EVENT_ARGS) { | ||
throw std::range_error("Too many arguments on event"); | ||
} | ||
return argument[count]; | ||
} | ||
|
||
const Adagio::EventArg *Adagio::Message::getArgByName(std::uint32_t argName) const { | ||
auto i = std::find_if(argument, argument + MAX_EVENT_ARGS, [argName](const Adagio::EventArg &arg) { | ||
return arg.eventName == argName; | ||
}); | ||
if (i != argument + MAX_EVENT_ARGS) { | ||
return i; | ||
} | ||
return nullptr; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#ifndef GL_ADAGIO_MESSAGE_H | ||
#define GL_ADAGIO_MESSAGE_H | ||
|
||
#include "EventArg.h" | ||
|
||
#define MAX_EVENT_ARGS 4 | ||
|
||
namespace Adagio { | ||
struct Message { | ||
struct MessageLinks { | ||
Message *next{nullptr}; | ||
Message *prev{nullptr}; | ||
}; | ||
std::uint32_t name{0}; | ||
std::uint32_t from{0}; | ||
std::uint32_t to{0}; | ||
bool active{false}; | ||
MessageLinks links; | ||
|
||
EventArg argument[MAX_EVENT_ARGS]; | ||
|
||
[[nodiscard]] const EventArg *getArg(unsigned char index) const; | ||
|
||
[[nodiscard]] const EventArg *getArgByName(std::uint32_t name) const; | ||
|
||
Message &addBoolArg(std::uint32_t eventName, bool value); | ||
|
||
Message &addUintArg(std::uint32_t eventName, std::uint32_t value); | ||
|
||
Message &addIntArg(std::uint32_t eventName, std::int32_t value); | ||
|
||
Message &addFloatArg(std::uint32_t eventName, float value); | ||
|
||
[[nodiscard]] unsigned char getArgumentCount() const; | ||
|
||
void nullifyArguments(); | ||
|
||
private: | ||
EventArg &getFirstFreeArgument(); | ||
}; | ||
} // namespace Adagio | ||
|
||
#endif // GL_ADAGIO_MESSAGE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#include "MessageCollection.h" | ||
|
||
namespace Adagio { | ||
size_t MessageCollection::size() const { | ||
return length; | ||
} | ||
|
||
void MessageCollection::append(Message *e) { | ||
e->links.next = nullptr; | ||
if (first == nullptr) { | ||
e->links.prev = nullptr; | ||
first = e; | ||
} else { | ||
e->links.prev = last; | ||
last->links.next = e; | ||
} | ||
last = e; | ||
length++; | ||
} | ||
|
||
Message *MessageCollection::operator[](size_t i) const { | ||
return at(i); | ||
} | ||
|
||
void MessageCollection::remove(size_t index) { | ||
Message *event = at(index); | ||
Message *prev = event->links.prev; | ||
Message *next = event->links.next; | ||
if (index == 0) { | ||
first = next; | ||
} | ||
if (index == length - 1) { | ||
last = prev; | ||
} | ||
if (prev && next) { | ||
prev->links.next = next; | ||
next->links.prev = prev; | ||
} | ||
event->nullifyArguments(); | ||
event->active = false; | ||
event->name = 0; | ||
event->from = 0; | ||
event->to = 0; | ||
length--; | ||
} | ||
|
||
Message *MessageCollection::at(size_t i) const { | ||
Message *event = first; | ||
for (size_t j = 0; j < i; j++) { | ||
event = event->links.next; | ||
} | ||
return event; | ||
} | ||
|
||
Message *MessageCollection::shift() { | ||
Message *e = first; | ||
if (first) { | ||
remove(0); | ||
} | ||
return e; | ||
} | ||
|
||
bool MessageCollection::empty() const { | ||
return size() == 0; | ||
} | ||
} // Adagio |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#ifndef GL_ADAGIO_MESSAGECOLLECTION_H | ||
#define GL_ADAGIO_MESSAGECOLLECTION_H | ||
|
||
#include "Message.h" | ||
|
||
namespace Adagio { | ||
class MessageCollection { | ||
public: | ||
Message *first{nullptr}; | ||
Message *last{nullptr}; | ||
|
||
void append(Message *e); | ||
|
||
void remove(size_t index); | ||
|
||
Message *shift(); | ||
|
||
[[nodiscard]] bool empty() const; | ||
|
||
[[nodiscard]] size_t size() const; | ||
|
||
[[nodiscard]] Message *at(size_t i) const; | ||
|
||
Message *operator[](size_t i) const; | ||
|
||
private: | ||
size_t length{0}; | ||
}; | ||
|
||
} // Adagio | ||
|
||
#endif //GL_ADAGIO_MESSAGECOLLECTION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#include "MessageDispatchService.h" | ||
#include <algorithm> | ||
|
||
namespace Adagio { | ||
Message &MessageDispatchService::dispatch(InboxId to, InboxId from, std::uint32_t eventName) { | ||
auto inbox = inboxMap.find(to); | ||
auto it = std::find_if(eventPool, eventPool + MSGPOOL_MAX, [](Message &e) { | ||
return !e.active; | ||
}); | ||
if (it == eventPool + MSGPOOL_MAX || inbox == inboxMap.end()) { | ||
invalidMessage.name = 0xdeadbeef; | ||
invalidMessage.active = false; | ||
return invalidMessage; | ||
} | ||
it->active = true; | ||
it->from = from; | ||
it->to = to; | ||
it->name = eventName; | ||
inbox->second->append(it); | ||
return *it; | ||
} | ||
|
||
void MessageDispatchService::registerInbox(InboxId id, MessageCollection *inboxDestination) { | ||
inboxMap[id] = inboxDestination; | ||
} | ||
|
||
void MessageDispatchService::unregisterInbox(InboxId id) { | ||
inboxMap.erase(id); | ||
} | ||
} // namespace Adagio |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#ifndef GL_ADAGIO_MESSAGEDISPATCHSERVICE_H | ||
#define GL_ADAGIO_MESSAGEDISPATCHSERVICE_H | ||
|
||
#include <cstdint> | ||
#include <unordered_map> | ||
#include "Message.h" | ||
#include "MessageCollection.h" | ||
|
||
#define MSGPOOL_MAX 32 | ||
|
||
namespace Adagio { | ||
|
||
typedef std::uint32_t InboxId; | ||
|
||
class MessageDispatchService { | ||
public: | ||
void registerInbox(InboxId id, MessageCollection *inboxDestination); | ||
|
||
template<typename T, typename U> | ||
void registerInbox(T id, U &inboxObject) { | ||
registerInbox(static_cast<InboxId>(id), &inboxObject.messages); | ||
} | ||
|
||
template<typename T> | ||
void registerInbox(T id, MessageCollection *inboxDestination) { | ||
registerInbox(static_cast<InboxId>(id), inboxDestination); | ||
} | ||
|
||
void unregisterInbox(InboxId id); | ||
|
||
template<typename T> | ||
void unregisterInbox(T id) { | ||
unregisterInbox(static_cast<InboxId>(id)); | ||
} | ||
|
||
Message &dispatch(InboxId to, InboxId from, std::uint32_t eventName); | ||
|
||
template<typename T, typename U> | ||
Message &dispatch(T to, U from, std::uint32_t eventName) { | ||
return dispatch(static_cast<InboxId>(to), static_cast<InboxId>(from), eventName); | ||
} | ||
|
||
private: | ||
Message eventPool[MSGPOOL_MAX]; | ||
Message invalidMessage; | ||
std::unordered_map<InboxId, MessageCollection *> inboxMap; | ||
}; | ||
|
||
} // namespace Adagio | ||
|
||
#endif // GL_ADAGIO_MESSAGEDISPATCHSERVICE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef GL_ADAGIO_MESSAGEINBOX_H | ||
#define GL_ADAGIO_MESSAGEINBOX_H | ||
|
||
#include "../../../event/MessageCollection.h" | ||
|
||
struct MessageInbox { | ||
Adagio::MessageCollection messages; | ||
}; | ||
|
||
#endif //GL_ADAGIO_MESSAGEINBOX_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#include "../../../../event/MessageDispatchService.h" | ||
#include "../MessageInbox.h" | ||
#include "MessageInboxHooks.h" | ||
|
||
void RegisterInboxWithMessageService(entt::registry ®istry, entt::entity id) { | ||
Adagio::MessageDispatchService *eventService = registry.ctx().get<Adagio::MessageDispatchService *>(); | ||
if (eventService) { | ||
MessageInbox &component = registry.get<MessageInbox>(id); | ||
eventService->registerInbox(id, component); | ||
} | ||
} | ||
|
||
void UnregisterInboxWithMessageService(entt::registry ®istry, entt::entity id) { | ||
Adagio::MessageDispatchService *eventService = registry.ctx().get<Adagio::MessageDispatchService *>(); | ||
if (eventService) { | ||
eventService->unregisterInbox(id); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef GL_ADAGIO_MESSAGEINBOXHOOKS_H | ||
#define GL_ADAGIO_MESSAGEINBOXHOOKS_H | ||
|
||
#include <entt/entt.hpp> | ||
|
||
void RegisterInboxWithMessageService(entt::registry ®istry, entt::entity id); | ||
|
||
void UnregisterInboxWithMessageService(entt::registry ®istry, entt::entity id); | ||
|
||
#endif //GL_ADAGIO_MESSAGEINBOXHOOKS_H |
Oops, something went wrong.