spacebox/src/Delegate.cpp

116 lines
3.5 KiB
C++

/* ✨ +------------------------------------------------------+
____/ \____ ✨/| Open source game framework licensed to freely use, |
✨\ / / | copy, and modify. Created for 🌠dank.game🌠 |
+--\ . . /--+ | |
| ~/ ︶ \👍| | 🌐 https://open.shampoo.ooo/shampoo/spacebox |
| ~~~🌊~~~~🌊~ | +------------------------------------------------------+
| SPACE 🪐🅱 OX | /
| 🌊 ~ ~~~~ ~~ |/
+-------------*/
#include "Delegate.hpp"
using namespace sb;
Delegate::Delegate(Node* parent) : Node(parent) {}
void Delegate::add_subscriber(Subscriber subscriber, std::uint32_t type)
{
if (subscribers.count(type) == 0)
{
subscribers[type] = {};
}
subscribers[type].push_back(subscriber);
}
void Delegate::dispatch()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
/* Don't even notify subscribers of the event if input is suppressed and the input is a key or mouse click. */
if (get_input().is_suppressed() && (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP ||
event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP))
{
continue;
}
for (auto iter = subscribers.begin(); iter != subscribers.end(); iter++)
{
if (event.type == iter->first)
{
cancelling_propagation = false;
for (Subscriber subscriber : iter->second)
{
if (subscriber.obj->is_active())
{
subscriber.func(event);
if (cancelling_propagation)
{
break;
}
}
}
}
}
if (event.type == command_event_type)
{
delete static_cast<std::string*>(event.user.data1);
delete static_cast<bool*>(event.user.data2);
}
}
}
bool Delegate::compare(SDL_Event& event, const std::vector<std::string>& commands, bool neutral, bool cancel)
{
for (const std::string& command : commands)
{
if (compare(event, command, neutral, cancel))
{
return true;
}
}
return false;
}
bool Delegate::compare(SDL_Event& event, const std::string& command, bool neutral, bool cancel)
{
return event.type == command_event_type && (command == "" || command == event_command(event)) &&
(neutral || (cancel == event_cancel_state(event)));
}
bool Delegate::compare_cancel(SDL_Event& event, const std::string& command)
{
return compare(event, command, false, true);
}
bool Delegate::compare_neutral(SDL_Event& event, const std::string& command)
{
return compare(event, command, true);
}
void Delegate::cancel_propagation()
{
cancelling_propagation = true;
}
const std::string& Delegate::event_command(SDL_Event& event)
{
return *static_cast<std::string*>(event.user.data1);
}
bool Delegate::event_cancel_state(SDL_Event& event)
{
return *static_cast<bool*>(event.user.data2);
}
void Delegate::post(const std::string& command, bool cancel)
{
SDL_Event relay;
bool* cancel_pointer = new bool(cancel);
std::string* command_pointer = new std::string(command);
relay.type = command_event_type;
relay.user.data1 = command_pointer;
relay.user.data2 = cancel_pointer;
SDL_PushEvent(&relay);
}