diff options
Diffstat (limited to 'src/crepe/api')
-rw-r--r-- | src/crepe/api/BoxCollider.cpp | 7 | ||||
-rw-r--r-- | src/crepe/api/BoxCollider.h | 24 | ||||
-rw-r--r-- | src/crepe/api/CMakeLists.txt | 14 | ||||
-rw-r--r-- | src/crepe/api/CircleCollider.cpp | 6 | ||||
-rw-r--r-- | src/crepe/api/CircleCollider.h | 17 | ||||
-rw-r--r-- | src/crepe/api/Event.h | 59 | ||||
-rw-r--r-- | src/crepe/api/EventHandler.cpp | 2 | ||||
-rw-r--r-- | src/crepe/api/EventHandler.h | 112 | ||||
-rw-r--r-- | src/crepe/api/EventManager.cpp | 81 | ||||
-rw-r--r-- | src/crepe/api/EventManager.h | 122 | ||||
-rw-r--r-- | src/crepe/api/EventManager.hpp | 140 | ||||
-rw-r--r-- | src/crepe/api/IKeyListener.cpp | 51 | ||||
-rw-r--r-- | src/crepe/api/IKeyListener.h | 78 | ||||
-rw-r--r-- | src/crepe/api/IMouseListener.cpp | 64 | ||||
-rw-r--r-- | src/crepe/api/IMouseListener.h | 117 | ||||
-rw-r--r-- | src/crepe/api/KeyCodes.h | 146 | ||||
-rw-r--r-- | src/crepe/api/LoopManager.cpp | 13 | ||||
-rw-r--r-- | src/crepe/api/Rigidbody.h | 10 | ||||
-rw-r--r-- | src/crepe/api/Vector2.h | 3 |
19 files changed, 1057 insertions, 9 deletions
diff --git a/src/crepe/api/BoxCollider.cpp b/src/crepe/api/BoxCollider.cpp new file mode 100644 index 0000000..eafbdb2 --- /dev/null +++ b/src/crepe/api/BoxCollider.cpp @@ -0,0 +1,7 @@ +#include "BoxCollider.h" +#include "../Collider.h" + +using namespace crepe; + + +BoxCollider::BoxCollider(game_object_id_t game_object_id,Vector2 offset, double width, double height) : Collider(game_object_id,offset), width(width), height(height) {} diff --git a/src/crepe/api/BoxCollider.h b/src/crepe/api/BoxCollider.h new file mode 100644 index 0000000..7f51cba --- /dev/null +++ b/src/crepe/api/BoxCollider.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Vector2.h" +#include "../Collider.h" + +namespace crepe { + +/** + * \brief A class representing a box-shaped collider. + * + * This class is used for collision detection with other colliders (e.g., CircleCollider). + */ +class BoxCollider : public Collider { +public: + BoxCollider(game_object_id_t game_object_id,Vector2 offset, double width, double height); + + //! Width of box collider + double width; + + //! Height of box collider + double height; +}; + +} // namespace crepe diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index f9b370f..07b3a82 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -17,6 +17,12 @@ target_sources(crepe PUBLIC Vector2.cpp Camera.cpp Animator.cpp + BoxCollider.cpp + CircleCollider.cpp + EventManager.cpp + EventHandler.cpp + IKeyListener.cpp + IMouseListener.cpp LoopManager.cpp LoopTimer.cpp ) @@ -43,6 +49,14 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES SceneManager.hpp Camera.h Animator.h + BoxCollider.h + CircleCollider.h + EventManager.h + EventManager.hpp + EventHandler.h + Event.h + IKeyListener.h + IMouseListener.h LoopManager.h LoopTimer.h ) diff --git a/src/crepe/api/CircleCollider.cpp b/src/crepe/api/CircleCollider.cpp new file mode 100644 index 0000000..04a4995 --- /dev/null +++ b/src/crepe/api/CircleCollider.cpp @@ -0,0 +1,6 @@ +#include "CircleCollider.h" + +using namespace crepe; + + +CircleCollider::CircleCollider(game_object_id_t game_object_id,Vector2 offset, int radius) : Collider(game_object_id,offset), radius(radius) {} diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h index e77a592..4e04fa4 100644 --- a/src/crepe/api/CircleCollider.h +++ b/src/crepe/api/CircleCollider.h @@ -1,14 +1,23 @@ #pragma once + +#include "Vector2.h" + #include "../Collider.h" namespace crepe { +/** + * \brief A class representing a circle-shaped collider. + * + * This class is used for collision detection with other colliders (e.g., BoxCollider). + */ class CircleCollider : public Collider { public: - CircleCollider(game_object_id_t game_object_id, int radius) - : Collider(game_object_id), - radius(radius) {} - int radius; + + CircleCollider(game_object_id_t game_object_id,Vector2 offset, int radius); + + //! Radius of the circle collider. + double radius; }; } // namespace crepe diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h new file mode 100644 index 0000000..bd6a541 --- /dev/null +++ b/src/crepe/api/Event.h @@ -0,0 +1,59 @@ +#pragma once +#include "KeyCodes.h" +#include <iostream> +#include <string> +#include <typeindex> +#include "system/CollisionSystem.h" + +class Event { +public: +}; + +class KeyPressEvent : public Event { +public: + int repeat = 0; + Keycode key = Keycode::NONE; +}; + +class KeyReleaseEvent : public Event { +public: + Keycode key = Keycode::NONE; +}; + +class MousePressEvent : public Event { +public: + int mouse_x = 0; + int mouse_y = 0; + MouseButton button = MouseButton::NONE; +}; + +class MouseClickEvent : public Event { +public: + int mouse_x = 0; + int mouse_y = 0; + MouseButton button = MouseButton::NONE; +}; +class MouseReleaseEvent : public Event { +public: + int mouse_x = 0; + int mouse_y = 0; + MouseButton button = MouseButton::NONE; +}; +class MouseMoveEvent : public Event { +public: + int mouse_x = 0; + int mouse_y = 0; +}; +class CollisionEvent : public Event { +public: + crepe::CollisionSystem::CollisionInfo info; + CollisionEvent(const crepe::CollisionSystem::CollisionInfo& collisionInfo) + : info(collisionInfo) {} +}; +class TextSubmitEvent : public Event { +public: + std::string text = ""; +}; +class ShutDownEvent : public Event { +public: +}; diff --git a/src/crepe/api/EventHandler.cpp b/src/crepe/api/EventHandler.cpp new file mode 100644 index 0000000..93a116a --- /dev/null +++ b/src/crepe/api/EventHandler.cpp @@ -0,0 +1,2 @@ +#include "EventHandler.h" +bool IEventHandlerWrapper::exec(const Event & e) { return call(e); } diff --git a/src/crepe/api/EventHandler.h b/src/crepe/api/EventHandler.h new file mode 100644 index 0000000..0ab90de --- /dev/null +++ b/src/crepe/api/EventHandler.h @@ -0,0 +1,112 @@ +#pragma once +#include "Event.h" +#include <functional> +#include <iostream> +#include <typeindex> + +/** + * \brief A type alias for an event handler function. + * + * The EventHandler is a std::function that takes an EventType reference and returns a boolean value + * indicating whether the event is handled. + * + * \tparam EventType The type of event this handler will handle. + */ +// TODO: typedef +template <typename EventType> +using EventHandler = std::function<bool(const EventType & e)>; + +/** + * \class IEventHandlerWrapper + * \brief An abstract base class for event handler wrappers. + * + * This class provides the interface for handling events. Derived classes must implement the + * `call()` method to process events and the `get_type()` method to return the handler's type. + */ +class IEventHandlerWrapper { +public: + /** + * \brief Virtual destructor for IEventHandlerWrapper. + */ + virtual ~IEventHandlerWrapper() = default; + + /** + * \brief Executes the handler with the given event. + * + * This method calls the `call()` method of the derived class, passing the event to the handler. + * + * \param e The event to be processed. + * \return A boolean value indicating whether the event is handled. + */ + bool exec(const Event & e); + + /** + * \brief Get the type of the event handler. + * + * This method returns the type of the event handler as a string. + * + * \return A string representing the handler's type. + */ + virtual std::string get_type() const = 0; + +private: + /** + * \brief The method responsible for handling the event. + * + * This method is implemented by derived classes to process the event. + * + * \param e The event to be processed. + * \return A boolean value indicating whether the event is handled. + */ + virtual bool call(const Event & e) = 0; +}; + +/** + * \class EventHandlerWrapper + * \brief A wrapper for event handler functions. + * + * This class wraps an event handler function of a specific event type. It implements the + * `call()` and `get_type()` methods to allow the handler to be executed and its type to be + * queried. + * + * \tparam EventType The type of event this handler will handle. + */ +template <typename EventType> +class EventHandlerWrapper : public IEventHandlerWrapper { +public: + /** + * \brief Constructs an EventHandlerWrapper with a given handler. + * + * The constructor takes an event handler function and stores it in the wrapper. + * + * \param handler The event handler function. + */ + explicit EventHandlerWrapper(const EventHandler<EventType> & handler) + : m_handler(handler), m_handler_type(m_handler.target_type().name()) {} + +private: + /** + * \brief Calls the stored event handler with the event. + * + * This method casts the event to the appropriate type and calls the handler. + * + * \param e The event to be handled. + * \return A boolean value indicating whether the event is handled. + */ + bool call(const Event & e) override { + return m_handler(static_cast<const EventType &>(e)); + } + + /** + * \brief Returns the type of the handler. + * + * This method returns a string representing the type of the event handler. + * + * \return The handler type as a string. + */ + std::string get_type() const override { return m_handler_type; } + //! The event handler function. + EventHandler<EventType> m_handler; + //! The type name of the handler function. + const std::string m_handler_type; +}; diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/api/EventManager.cpp new file mode 100644 index 0000000..e881d49 --- /dev/null +++ b/src/crepe/api/EventManager.cpp @@ -0,0 +1,81 @@ +#include "EventManager.h" + +using namespace crepe; + +EventManager & EventManager::get_instance() { + static EventManager instance; + return instance; +} + +void EventManager::dispatch_events() { + for (std::vector<std::tuple<std::unique_ptr<Event>, int, + std::type_index>>::iterator event_it + = this->events_queue.begin(); + event_it != this->events_queue.end();) { + std::unique_ptr<Event> & event = std::get<0>(*event_it); + int channel = std::get<1>(*event_it); + std::type_index event_type = std::get<2>(*event_it); + + bool event_handled = false; + + if (channel) { + std::unordered_map< + std::type_index, + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>:: + iterator handlers_it + = subscribers_by_event_id.find(event_type); + if (handlers_it != subscribers_by_event_id.end()) { + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>> & + handlers_map + = handlers_it->second; + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>:: + iterator handlers + = handlers_map.find(channel); + if (handlers != handlers_map.end()) { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & + callbacks + = handlers->second; + for (std::vector<std::unique_ptr<IEventHandlerWrapper>>:: + iterator handler_it + = callbacks.begin(); + handler_it != callbacks.end(); ++handler_it) { + if ((*handler_it)->exec(*event)) { + event_it = events_queue.erase(event_it); + event_handled = true; + break; + } + } + } + } + } else { + // Handle event for all channels + std::unordered_map< + std::type_index, + std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator + handlers_it + = this->subscribers.find(event_type); + if (handlers_it != this->subscribers.end()) { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers + = handlers_it->second; + for (std::vector<std::unique_ptr<IEventHandlerWrapper>>:: + iterator handler_it + = handlers.begin(); + handler_it != handlers.end(); ++handler_it) { + // remove event from queue since and continue when callback returns true + if ((*handler_it)->exec(*event)) { + event_it = this->events_queue.erase(event_it); + event_handled = true; + break; + } + } + } + } + + if (!event_handled) { + ++event_it; + } + } +} diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h new file mode 100644 index 0000000..38d2e64 --- /dev/null +++ b/src/crepe/api/EventManager.h @@ -0,0 +1,122 @@ +#pragma once + +#include <functional> +#include <memory> +#include <type_traits> +#include <typeindex> +#include <unordered_map> +#include <vector> + +#include "Event.h" +#include "EventHandler.h" + + +namespace crepe { +/** + * \class EventManager + * \brief The EventManager class is responsible for managing the subscription, triggering, + * and queueing of events. It handles events and dispatches them to appropriate subscribers. + */ +class EventManager { +public: + /** + * \brief Deleted copy constructor to prevent copying of the EventManager instance. + */ + EventManager(const EventManager &) = delete; + + /** + * \brief Deleted copy assignment operator to prevent assignment of the EventManager instance. + */ + const EventManager & operator=(const EventManager &) = delete; + + /** + * \brief Get the singleton instance of the EventManager. + * + * This method returns the unique instance of the EventManager, creating it on the first call. + * + * \return Reference to the EventManager instance. + */ + static EventManager & get_instance(); + + /** + * \brief Subscribe to an event. + * + * This method allows the registration of a callback for a specific event type and channel. + * + * \tparam EventType The type of the event to subscribe to. + * \param callback The callback function to invoke when the event is triggered. + * \param channel The channel number to subscribe to (default is 0). + */ + template <typename EventType> + void subscribe(EventHandler<EventType> && callback, int channel = 0); + + /** + * \brief Unsubscribe from an event. + * + * This method removes a previously registered callback from an event. + * + * \tparam EventType The type of the event to unsubscribe from. + * \param callback The callback function to remove from the subscription list. + * \param channel The event ID to unsubscribe from. + */ + template <typename EventType> + void unsubscribe(const EventHandler<EventType> &, int channel); + + /** + * \brief Trigger an event. + * + * This method invokes the appropriate callback(s) for the specified event. + * + * \tparam EventType The type of the event to trigger. + * \param event The event data to pass to the callback. + * \param channel The channel from which to trigger the event (default is 0). + */ + template <typename EventType> + void trigger_event(const EventType & event, int channel); + + /** + * \brief Queue an event for later processing. + * + * This method adds an event to the event queue, which will be processed in the + * dispatch_events function. + * + * \tparam EventType The type of the event to queue. + * \param event The event to queue. + * \param channel The channel number for the event (default is 0). + */ + template <typename EventType> + void queue_event(EventType && event, int channel); + + /** + * \brief Dispatch all queued events. + * + * This method processes all events in the event queue and triggers the corresponding + * callbacks for each event. + */ + void dispatch_events(); + +private: + /** + * \brief Default constructor for the EventManager. + * + * This constructor is private to enforce the singleton pattern. + */ + EventManager() = default; + + //! The queue of events to be processed. + std::vector<std::tuple<std::unique_ptr<Event>, int, std::type_index>> + events_queue; + //! Registered event handlers. + std::unordered_map<std::type_index, + std::vector<std::unique_ptr<IEventHandlerWrapper>>> + subscribers; + //! Event handlers indexed by event ID. + std::unordered_map< + std::type_index, + std::unordered_map<int, + std::vector<std::unique_ptr<IEventHandlerWrapper>>>> + subscribers_by_event_id; +}; + +} // namespace crepe +#include "EventManager.hpp" diff --git a/src/crepe/api/EventManager.hpp b/src/crepe/api/EventManager.hpp new file mode 100644 index 0000000..b509097 --- /dev/null +++ b/src/crepe/api/EventManager.hpp @@ -0,0 +1,140 @@ +#include "EventManager.h" +namespace crepe { + +template <typename EventType> +void EventManager::subscribe(EventHandler<EventType> && callback, int channel) { + std::type_index event_type = typeid(EventType); + std::unique_ptr<EventHandlerWrapper<EventType>> handler + = std::make_unique<EventHandlerWrapper<EventType>>(callback); + + if (channel) { + std::unordered_map<int, + std::vector<std::unique_ptr<IEventHandlerWrapper>>> & + handlers_map + = this->subscribers_by_event_id[event_type]; + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator + handlers + = handlers_map.find(channel); + if (handlers != handlers_map.end()) { + handlers->second.emplace_back(std::move(handler)); + } else { + handlers_map[channel].emplace_back(std::move(handler)); + } + } else { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers + = this->subscribers[event_type]; + handlers.emplace_back(std::move(handler)); + } +} + +template <typename EventType> +void EventManager::queue_event(EventType && event, int channel) { + std::type_index event_type = std::type_index(typeid(EventType)); + + std::unique_ptr<EventType> event_ptr + = std::make_unique<EventType>(std::forward<EventType>(event)); + + std::tuple<std::unique_ptr<Event>, int, std::type_index> tuple( + std::move(event_ptr), channel, event_type); + this->events_queue.push_back(std::move(tuple)); +} + +template <typename EventType> +void EventManager::trigger_event(const EventType & event, int channel) { + std::type_index event_type = std::type_index(typeid(EventType)); + + if (channel > 0) { + std::unordered_map<int, + std::vector<std::unique_ptr<IEventHandlerWrapper>>> & + handlers_map + = this->subscribers_by_event_id[event_type]; + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator + handlers_it + = handlers_map.find(channel); + + if (handlers_it != handlers_map.end()) { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers + = handlers_it->second; + for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it + = handlers.begin(); + it != handlers.end();++it) { + // stops when callback returns true + if((*it)->exec(event)){ + break; + } + } + } + } else { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers + = this->subscribers[event_type]; + for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it + = handlers.begin(); + it != handlers.end();++it) { + // stops when callback returns true + if((*it)->exec(event)){ + break; + } + } + } +} + +template <typename EventType> +void EventManager::unsubscribe(const EventHandler<EventType> & callback, + int channel) { + std::type_index event_type(typeid(EventType)); + std::string handler_name = callback.target_type().name(); + + if (channel) { + std::unordered_map< + std::type_index, + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>:: + iterator subscriber_list + = this->subscribers_by_event_id.find(event_type); + if (subscriber_list != this->subscribers_by_event_id.end()) { + std::unordered_map< + int, std::vector<std::unique_ptr<IEventHandlerWrapper>>> & + handlers_map + = subscriber_list->second; + std::unordered_map< + int, + std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator + handlers + = handlers_map.find(channel); + if (handlers != handlers_map.end()) { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & callbacks + = handlers->second; + for (std::vector< + std::unique_ptr<IEventHandlerWrapper>>::iterator it + = callbacks.begin(); + it != callbacks.end(); ++it) { + if ((*it)->get_type() == handler_name) { + it = callbacks.erase(it); + return; + } + } + } + } + } else { + std::unordered_map<std::type_index, + std::vector<std::unique_ptr<IEventHandlerWrapper>>>:: + iterator handlers_it + = this->subscribers.find(event_type); + if (handlers_it != this->subscribers.end()) { + std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers + = handlers_it->second; + for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it + = handlers.begin(); + it != handlers.end(); ++it) { + if ((*it)->get_type() == handler_name) { + it = handlers.erase(it); + return; + } + } + } + } +} + +} diff --git a/src/crepe/api/IKeyListener.cpp b/src/crepe/api/IKeyListener.cpp new file mode 100644 index 0000000..4fd9855 --- /dev/null +++ b/src/crepe/api/IKeyListener.cpp @@ -0,0 +1,51 @@ +#include "IKeyListener.h" + +using namespace crepe; + +IKeyListener::IKeyListener() { + this->channel = channel; + this->subscribe_events(); +} +IKeyListener::IKeyListener(int channel) { + this->channel = channel; + this->subscribe_events(); +} +IKeyListener::~IKeyListener() { this->unsubscribe_events(); } + +void IKeyListener::subscribe_events() { + key_pressed_handler = [this](const KeyPressEvent & event) { + return this->on_key_pressed(event); + }; + key_released_handler = [this](const KeyReleaseEvent & event) { + return this->on_key_released(event); + }; + EventManager::get_instance().subscribe<KeyPressEvent>( + std::move(this->key_pressed_handler), this->channel); + EventManager::get_instance().subscribe<KeyReleaseEvent>( + std::move(this->key_released_handler), this->channel); +} + +void IKeyListener::unsubscribe_events() { + EventManager::get_instance().unsubscribe<KeyPressEvent>( + this->key_pressed_handler, channel); + EventManager::get_instance().unsubscribe<KeyReleaseEvent>( + this->key_released_handler, channel); + std::cout << std::endl; +} +void IKeyListener::activate_keys() { + if (this->active) { + return; + } + this->subscribe_events(); +} +void IKeyListener::deactivate_keys() { + if (!this->active) { + return; + } + this->unsubscribe_events(); +} +void IKeyListener::set_channel(int channel) { + this->unsubscribe_events(); + this->channel = channel; + this->subscribe_events(); +} diff --git a/src/crepe/api/IKeyListener.h b/src/crepe/api/IKeyListener.h new file mode 100644 index 0000000..839acbf --- /dev/null +++ b/src/crepe/api/IKeyListener.h @@ -0,0 +1,78 @@ +#pragma once +#include "Event.h" +#include "EventHandler.h" +#include "EventManager.h" + +/** + * \class IKeyListener + * \brief Interface for keyboard event handling in the application. + */ +class IKeyListener { +public: + /** + * \brief Constructs an IKeyListener with a specified channel. + * \param channel The channel ID for event handling. + */ + IKeyListener(int channel); + + /** + * \brief Default constructor for IKeyListener. + */ + IKeyListener(); + + /** + * \brief Destructor. + */ + virtual ~IKeyListener(); + + /** + * \brief Pure virtual function to handle key press events. + * \param event The key press event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_key_pressed(const KeyPressEvent & event) = 0; + + /** + * \brief Pure virtual function to handle key release events. + * \param event The key release event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_key_released(const KeyReleaseEvent & event) = 0; + + /** + * \brief Activates key listening. + */ + void activate_keys(); + + /** + * \brief Deactivates key listening. + */ + void deactivate_keys(); + + /** + * \brief Sets the channel ID for event handling. + * \param channel The channel ID to set. + */ + void set_channel(int channel); + +protected: + /** + * \brief Subscribes to key events. + */ + void subscribe_events(); + + /** + * \brief Unsubscribes from key events. + */ + void unsubscribe_events(); + +private: + //! Indicates whether key listening is active. + bool active = true; + //! Channel ID for event handling. + int channel = 0; + //! Key press event handler. + EventHandler<KeyPressEvent> key_pressed_handler; + //!< Key release event handler. + EventHandler<KeyReleaseEvent> key_released_handler; +}; diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp new file mode 100644 index 0000000..489e55b --- /dev/null +++ b/src/crepe/api/IMouseListener.cpp @@ -0,0 +1,64 @@ +#include "IMouseListener.h" + +using namespace crepe; + +IMouseListener::IMouseListener(int channel) { this->channel = channel; } + +IMouseListener::IMouseListener() { this->subscribe_events(); } + +IMouseListener::~IMouseListener() { this->unsubscribe_events(); } + +void IMouseListener::subscribe_events() { + // Define handler lambdas and subscribe them + mouse_click_handler = [this](const MouseClickEvent & event) { + return this->on_mouse_clicked(event); + }; + mouse_press_handler = [this](const MousePressEvent & event) { + return this->on_mouse_pressed(event); + }; + mouse_release_handler = [this](const MouseReleaseEvent & event) { + return this->on_mouse_released(event); + }; + mouse_move_handler = [this](const MouseMoveEvent & event) { + return this->on_mouse_moved(event); + }; + EventManager::get_instance().subscribe<MouseClickEvent>( + std::move(this->mouse_click_handler), this->channel); + EventManager::get_instance().subscribe<MousePressEvent>( + std::move(this->mouse_press_handler), this->channel); + EventManager::get_instance().subscribe<MouseReleaseEvent>( + std::move(this->mouse_release_handler), this->channel); + EventManager::get_instance().subscribe<MouseMoveEvent>( + std::move(this->mouse_move_handler), this->channel); +} +// TODO: reference voor singleton +void IMouseListener::unsubscribe_events() { + EventManager::get_instance().unsubscribe<MouseClickEvent>( + this->mouse_click_handler, this->channel); + EventManager::get_instance().unsubscribe<MousePressEvent>( + this->mouse_press_handler, this->channel); + EventManager::get_instance().unsubscribe<MouseReleaseEvent>( + this->mouse_release_handler, this->channel); + EventManager::get_instance().unsubscribe<MouseMoveEvent>( + this->mouse_move_handler, this->channel); +} + +void IMouseListener::activate_mouse() { + if (this->active) { + return; + } + this->subscribe_events(); +} + +void IMouseListener::deactivate_mouse() { + if (!this->active) { + return; + } + this->unsubscribe_events(); +} + +void IMouseListener::set_channel(int channel) { + this->unsubscribe_events(); + this->channel = channel; + this->subscribe_events(); +} diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h new file mode 100644 index 0000000..7e92956 --- /dev/null +++ b/src/crepe/api/IMouseListener.h @@ -0,0 +1,117 @@ +#pragma once + +#include "Event.h" +#include "EventHandler.h" +#include "EventManager.h" + +/** + * \class IMouseListener + * \brief Interface for mouse event handling in the application. + */ +class IMouseListener { +public: + /** + * \brief Default constructor. + */ + IMouseListener(); + + /** + * \brief Constructs an IMouseListener with a specified channel. + * \param channel The channel ID for event handling. + */ + IMouseListener(int channel); + + /** + * \brief Destructor. + */ + virtual ~IMouseListener(); + + /** + * \brief Copy constructor (deleted). + */ + IMouseListener(const IMouseListener &) = delete; + + /** + * \brief Copy assignment operator (deleted). + */ + IMouseListener & operator=(const IMouseListener &) = delete; + + /** + * \brief Move constructor (deleted). + */ + IMouseListener(IMouseListener &&) = delete; + + /** + * \brief Move assignment operator (deleted). + */ + IMouseListener & operator=(IMouseListener &&) = delete; + + /** + * \brief Handles a mouse click event. + * \param event The mouse click event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_mouse_clicked(const MouseClickEvent & event) = 0; + + /** + * \brief Handles a mouse press event. + * \param event The mouse press event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_mouse_pressed(const MousePressEvent & event) = 0; + + /** + * \brief Handles a mouse release event. + * \param event The mouse release event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_mouse_released(const MouseReleaseEvent & event) = 0; + + /** + * \brief Handles a mouse move event. + * \param event The mouse move event to handle. + * \return True if the event was handled, false otherwise. + */ + virtual bool on_mouse_moved(const MouseMoveEvent & event) = 0; + + /** + * \brief Activates mouse listening. + */ + void activate_mouse(); + + /** + * \brief Deactivates mouse listening. + */ + void deactivate_mouse(); + + /** + * \brief Sets the channel ID for event handling. + * \param channel The channel ID to set. + */ + void set_channel(int channel); + +protected: + /** + * \brief Subscribes to mouse events on the specified channel. + */ + void subscribe_events(); + + /** + * \brief Unsubscribes from mouse events on the specified channel. + */ + void unsubscribe_events(); + +private: + //! Indicates whether mouse listening is active. + bool active = true; + //! Channel ID for event handling. + int channel = 0; + //! Mouse click event handler. + EventHandler<MouseClickEvent> mouse_click_handler; + //! Mouse press event handler. + EventHandler<MousePressEvent> mouse_press_handler; + //! Mouse release event handler. + EventHandler<MouseReleaseEvent> mouse_release_handler; + //! Mouse move event handler. + EventHandler<MouseMoveEvent> mouse_move_handler; +}; diff --git a/src/crepe/api/KeyCodes.h b/src/crepe/api/KeyCodes.h new file mode 100644 index 0000000..e5a91fc --- /dev/null +++ b/src/crepe/api/KeyCodes.h @@ -0,0 +1,146 @@ +#pragma once + +enum class MouseButton { + NONE = 0, + LEFT_MOUSE = 1, + RIGHT_MOUSE = 2, + MIDDLE_MOUSE = 3, + X1_MOUSE = 4, + X2_MOUSE = 5, + SCROLL_UP = 6, + SCROLL_DOWN = 7, +}; + +enum class Keycode : int { + NONE = 0, + SPACE = 32, + APOSTROPHE = 39, /* ' */ + COMMA = 44, /* , */ + MINUS = 45, /* - */ + PERIOD = 46, /* . */ + SLASH = 47, /* / */ + + D0 = 48, /* 0 */ + D1 = 49, /* 1 */ + D2 = 50, /* 2 */ + D3 = 51, /* 3 */ + D4 = 52, /* 4 */ + D5 = 53, /* 5 */ + D6 = 54, /* 6 */ + D7 = 55, /* 7 */ + D8 = 56, /* 8 */ + D9 = 57, /* 9 */ + + SEMICOLON = 59, /* ; */ + EQUAL = 61, /* = */ + + A = 65, + B = 66, + C = 67, + D = 68, + E = 69, + F = 70, + G = 71, + H = 72, + I = 73, + J = 74, + K = 75, + L = 76, + M = 77, + N = 78, + O = 79, + P = 80, + Q = 81, + R = 82, + S = 83, + T = 84, + U = 85, + V = 86, + W = 87, + X = 88, + Y = 89, + Z = 90, + + LEFT_BRACKET = 91, /* [ */ + BACKSLASH = 92, /* \ */ + RIGHT_BRACKET = 93, /* ] */ + GRAVE_ACCENT = 96, /* ` */ + + WORLD1 = 161, /* non-US #1 */ + WORLD2 = 162, /* non-US #2 */ + + /* Function keys */ + ESCAPE = 256, + ENTER = 257, + TAB = 258, + BACKSPACE = 259, + INSERT = 260, + DELETE = 261, + RIGHT = 262, + LEFT = 263, + DOWN = 264, + UP = 265, + PAGE_UP = 266, + PAGE_DOWN = 267, + HOME = 268, + END = 269, + CAPS_LOCK = 280, + SCROLL_LOCK = 281, + NUM_LOCK = 282, + PRINT_SCREEN = 283, + PAUSE = 284, + F1 = 290, + F2 = 291, + F3 = 292, + F4 = 293, + F5 = 294, + F6 = 295, + F7 = 296, + F8 = 297, + F9 = 298, + F10 = 299, + F11 = 300, + F12 = 301, + F13 = 302, + F14 = 303, + F15 = 304, + F16 = 305, + F17 = 306, + F18 = 307, + F19 = 308, + F20 = 309, + F21 = 310, + F22 = 311, + F23 = 312, + F24 = 313, + F25 = 314, + + /* Keypad */ + KP0 = 320, + KP1 = 321, + KP2 = 322, + KP3 = 323, + KP4 = 324, + KP5 = 325, + KP6 = 326, + KP7 = 327, + KP8 = 328, + KP9 = 329, + KP_DECIMAL = 330, + KP_DIVIDE = 331, + KP_MULTIPLY = 332, + KP_SUBTRACT = 333, + KP_ADD = 334, + KP_ENTER = 335, + KP_EQUAL = 336, + + LEFT_SHIFT = 340, + LEFT_CONTROL = 341, + LEFT_ALT = 342, + LEFT_SUPER = 343, + RIGHT_SHIFT = 344, + RIGHT_CONTROL = 345, + RIGHT_ALT = 346, + RIGHT_SUPER = 347, + MENU = 348 +}; diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index a64366f..a4bc101 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -6,6 +6,8 @@ #include "../system/PhysicsSystem.h" #include "../system/RenderSystem.h" #include "../system/ScriptSystem.h" +#include "..//system/PhysicsSystem.h" +#include "..//system/CollisionSystem.h" #include "LoopManager.h" #include "LoopTimer.h" @@ -32,7 +34,12 @@ void LoopManager::start() { } void LoopManager::set_running(bool running) { this->game_running = running; } -void LoopManager::fixed_update() {} +void LoopManager::fixed_update() { + PhysicsSystem phys; + phys.update(); + CollisionSystem col; + col.update(); +} void LoopManager::loop() { LoopTimer & timer = LoopTimer::get_instance(); @@ -41,11 +48,11 @@ void LoopManager::loop() { while (game_running) { timer.update(); - while (timer.get_lag() >= timer.get_fixed_delta_time()) { + //while (timer.get_lag() >= timer.get_fixed_delta_time()) { this->process_input(); this->fixed_update(); timer.advance_fixed_update(); - } + //} this->update(); this->render(); diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 3e5c7a3..fddbf5c 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -1,5 +1,7 @@ #pragma once +#include <cmath> + #include "../Component.h" #include "Vector2.h" @@ -58,13 +60,13 @@ public: //! linear velocity of object Vector2 linear_velocity; //! maximum linear velocity of object - Vector2 max_linear_velocity; + Vector2 max_linear_velocity = {INFINITY ,INFINITY}; //! linear damping of object Vector2 linear_damping; //! angular velocity of object double angular_velocity = 0.0; //! max angular velocity of object - double max_angular_velocity = 0.0; + double max_angular_velocity = INFINITY; //! angular damping of object double angular_damping = 0.0; //! movements constraints of object @@ -73,6 +75,10 @@ public: bool use_gravity = true; //! if object bounces bool bounce = false; + //! bounce factor of material + double elastisity = 0.0; + //! offset of all colliders relative to transform position + Vector2 offset; }; public: diff --git a/src/crepe/api/Vector2.h b/src/crepe/api/Vector2.h index 2fb6136..438fde6 100644 --- a/src/crepe/api/Vector2.h +++ b/src/crepe/api/Vector2.h @@ -35,6 +35,9 @@ struct Vector2 { //! Checks if this vector is not equal to another vector. bool operator!=(const Vector2 & other) const; + + //! + double dot(const Vector2& other) const; }; } // namespace crepe |