diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-21 09:43:13 +0100 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-21 09:43:13 +0100 |
commit | 502fb8e8d1dcfe10f55fdef2cdfb71afec806204 (patch) | |
tree | 8b967076cf0212f00d811e57264e3e0878c059c4 /src/crepe/api/Script.h | |
parent | da379a58033c0ef3c9c854326a3fca25d6e54319 (diff) |
pull script/event changes from `loek/collision-system`
Diffstat (limited to 'src/crepe/api/Script.h')
-rw-r--r-- | src/crepe/api/Script.h | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index c9eb211..373b253 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -18,8 +18,10 @@ class ComponentManager; * This class is used as a base class for user-defined scripts that can be added to game * objects using the \c BehaviorScript component. * - * \note Additional *events* (like Unity's OnDisable and OnEnable) should be implemented as + * \info Additional *events* (like Unity's OnDisable and OnEnable) should be implemented as * member or lambda methods in derivative user script classes and registered in \c init(). + * + * \see feature_script */ class Script { protected: @@ -88,18 +90,40 @@ protected: void logf(Args &&... args); /** - * \brief Subscribe to an event - * + * \brief Subscribe to an event with an explicit channel + * \see EventManager::subscribe + */ + template <typename EventType> + void subscribe(const EventHandler<EventType> & callback, event_channel_t channel); + /** + * \brief Subscribe to an event on EventManager::CHANNEL_ALL * \see EventManager::subscribe */ template <typename EventType> - void subscribe(const EventHandler<EventType> & callback, event_channel_t channel = EventManager::CHANNEL_ALL); + void subscribe(const EventHandler<EventType> & callback); //! \} +private: + /** + * \brief Internal subscribe function + * + * This function exists so certain template specializations of Script::subscribe can be + * explicitly deleted, and does the following: + * - Wrap the user-provided callback in a check that tests if the parent BehaviorScript + * component is still active + * - Store the subscriber handle returned by the event manager so this listener is + * automatically unsubscribed at the end of this Script instance's life + * + * \tparam EventType concrete Event class + * \param callback User-provided callback function + * \param channel Event channel (may have been overridden by template specializations) + */ + template <typename EventType> + void subscribe_internal(const EventHandler<EventType> & callback, event_channel_t channel); + protected: - // NOTE: Script must have a constructor without arguments so the game programmer doesn't need - // to manually add `using Script::Script` to their concrete script class. + // NOTE: This must be the only constructor on Script, see "Late references" below Script() = default; //! Only \c BehaviorScript instantiates Script friend class BehaviorScript; @@ -107,6 +131,7 @@ public: // std::unique_ptr destroys script virtual ~Script(); +private: Script(const Script &) = delete; Script(Script &&) = delete; Script & operator=(const Script &) = delete; @@ -119,10 +144,19 @@ private: * These references are set by BehaviorScript immediately after calling the constructor of * Script. * + * \note Script must have a constructor without arguments so the game programmer doesn't need + * to manually add `using Script::Script` to their concrete script class if they want to + * implement a non-default constructor (e.g. for passing references to their own concrete + * Script classes). + * + * \todo These should be converted to OptionalRef<> once `loek/util` is merged + * * \{ */ //! Game object ID of game object parent BehaviorScript is attached to - game_object_id_t game_object_id = -1; + const game_object_id_t * game_object_id_ref = nullptr; + //! Reference to parent component + bool * active_ref = nullptr; //! Reference to component manager instance ComponentManager * component_manager_ref = nullptr; //! Reference to event manager instance @@ -136,6 +170,18 @@ private: std::vector<subscription_t> listeners; }; +/** + * \brief Subscribe to CollisionEvent for the current GameObject + * + * This is a template specialization for Script::subscribe which automatically sets the event + * channel so the callback handler is only called for CollisionEvent events that apply to the + * current GameObject the parent BehaviorScript is attached to. + */ +template <> +void Script::subscribe(const EventHandler<CollisionEvent> & callback); +template <> +void Script::subscribe(const EventHandler<CollisionEvent> & callback, event_channel_t) = delete; + } // namespace crepe #include "Script.hpp" |