/* ✨ +------------------------------------------------------+ ____/ \____ ✨/| Open source game framework licensed to freely use, | ✨\ / / | copy, and modify. Created for 🌠dank.game🌠 | +--\ . . /--+ | | | ~/ οΈΆ \πŸ‘| | 🌐 https://open.shampoo.ooo/shampoo/spacebox | | ~~~🌊~~~~🌊~ | +------------------------------------------------------+ | SPACE πŸͺπŸ…± OX | / | 🌊 ~ ~~~~ ~~ |/ +-------------*/ #pragma once #include #include #include #include #include #include #include "SDL.h" #include "Node.hpp" namespace sb { struct Subscriber { std::function func; Node* obj; }; class Delegate : public Node { private: std::map> subscribers; bool cancelling_propagation = false; public: inline static std::uint32_t command_event_type = SDL_RegisterEvents(1); Delegate(Node*); void add_subscriber(Subscriber, std::uint32_t); void dispatch(); static bool compare(SDL_Event&, const std::vector&, bool = false, bool = false); static bool compare(SDL_Event&, const std::string& = "", bool = false, bool = false); static bool compare_cancel(SDL_Event&, const std::string& = ""); static bool compare_neutral(SDL_Event&, const std::string& = ""); void cancel_propagation(); static const std::string& event_command(SDL_Event&); static bool event_cancel_state(SDL_Event&); /*! * Post a custom command to the queue. There is not currently support for passing custom data along with the command. The string * and bool arguments will be copied onto the heap and deleted when the event is retrieved from the queue. * * @param command name of the custom command * @param cancel whether or not the event is a cancellation */ static void post(const std::string& command, bool cancel = false); /*! * Subscribe a sb::Node or extention of sb::Node object's member function to receive a reference to an SDL_Event whenever * an event of the specified type is triggered. The type can be an SDL event type from https://wiki.libsdl.org/SDL2/SDL_EventType, * or if no type is specified, the type will be the custom user event used by this framework, sb::Delegate::command_event_type. * * The function submitted must accept a single argument of type SDL_Event&. * * sb::Delegate::command_event_type is an SDL_EventType used by this framework to automatically send framework and user created * events that are mapped to keys in an sb::Configuration object's "keys" field. For example, by default `ALT+enter` is configured * to send an event named `fullscreen`. Using a JSON file, `z` could be mapped to an event named `jump`. * * The subscribing object must be unsubscribed with Delegate::unsubscribe(const Type*) before it is destroyed, otherwise it will * be null referenced. * * @param func a sb::Node or child of sb::Node object's member class function pointer * @param obj a pointer to the object * @param type the SDL_EventType to receive events for */ template void subscribe(void(Type::*func)(SDL_Event&), Type* obj, std::uint32_t type = command_event_type) { add_subscriber({std::bind(func, obj, std::placeholders::_1), static_cast(obj)}, type); } /*! * Unsubscribe all subscribers in list associated with the submitted object. * * @param obj pointer to object to search for in subscriber list for removal */ template void unsubscribe(const Type* obj) { for (auto type = subscribers.begin(); type != subscribers.end(); type++) { for (auto subscriber = type->second.begin(); subscriber != type->second.end();) { if (obj == subscriber->obj) { subscriber = type->second.erase(subscriber); } else { subscriber++; } } } } }; } #include "Input.hpp" #include "Game.hpp"