diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj index e54c82ec..8da6f80c 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj +++ b/SHADE_Engine/SHADE_Engine.vcxproj @@ -102,6 +102,7 @@ + @@ -116,6 +117,9 @@ + + + @@ -200,6 +204,8 @@ + + @@ -286,4 +292,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters index 7486fad4..f0d769f0 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj.filters +++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters @@ -1,6 +1,9 @@ + + {8EEA3EAC-7A8C-6982-6347-7DD64F88F0D2} + {1AB26817-067F-C322-2F98-B1CA1BC4F8B0} @@ -19,6 +22,9 @@ {DBC7D3B0-C769-FE86-B024-12DB9C6585D7} + + {3A8963B1-262B-8E87-0FE6-A1DBFB2615D8} + {8A8E2B37-7646-6D84-DF4D-46E0CB240875} @@ -117,6 +123,9 @@ + + Common + ECS_Base\Components @@ -159,6 +168,15 @@ Engine + + Events + + + Events + + + Events + Filesystem @@ -405,6 +423,12 @@ Engine + + Events + + + Events + Filesystem diff --git a/SHADE_Engine/src/Common/SHCommonTypes.h b/SHADE_Engine/src/Common/SHCommonTypes.h new file mode 100644 index 00000000..97ef7928 --- /dev/null +++ b/SHADE_Engine/src/Common/SHCommonTypes.h @@ -0,0 +1,28 @@ +/************************************************************************************//*! +\file SHCommonTypes.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 8, 2022 +\brief Contains the definitions of type alias for commonly used units for + clarity and convenience. + + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Type used to mark a value that is supposed to represent a size in bytes. + */ + /***********************************************************************************/ + using Byte = size_t; +} diff --git a/SHADE_Engine/src/Events/SHEvent.cpp b/SHADE_Engine/src/Events/SHEvent.cpp new file mode 100644 index 00000000..4ac7c612 --- /dev/null +++ b/SHADE_Engine/src/Events/SHEvent.cpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * \file SHEvent.cpp + * \author Loh Xiao Qi + * \brief Implementation of SHEvent.h Initialise data member of smart pointer + * to package data. Return the package pointer and package type + * accordingly. + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior + * written consent of Digipen Institute of Technology is prohibited + ******************************************************************************/ +#include "SHpch.h" +#include "SHEvent.h" +#include + +namespace SHADE +{ + /**************************************************************************** + * \param PackagePtr - smart pointer to package data. + + * \brief Constructor for Event. User needs to dynamically allocate memory + * for package data and pass in the smart pointer so the data member + * can be initialised properly. + ****************************************************************************/ + SHEvent::SHEvent(PackagePtr pkg) + : package{ std::move(pkg) } + { + + } + + /**************************************************************************** + * \brief Get pointer to data package. + * + * \return Smart pointer to Package Base, needs to be cast to correct + * derived class. + ****************************************************************************/ + ConstPackagePtr& SHEvent::GetData() const + { + return package; + } + + /**************************************************************************** + * \brief Gets the type of package. + ****************************************************************************/ + SHPackageType SHEvent::GetType() const + { + return package->GetPackageType(); + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Events/SHEvent.h b/SHADE_Engine/src/Events/SHEvent.h new file mode 100644 index 00000000..fc128a17 --- /dev/null +++ b/SHADE_Engine/src/Events/SHEvent.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * \file SHEventBase.h + * \author Loh Xiao Qi + * \brief Event base abstract class declaration + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior written consent + * of Digipen Institute of Technology is prohibited. +******************************************************************************/ +#ifndef SH_EVENT_BASE_H +#define SH_EVENT_BASE_H + +namespace SHADE +{ + class SHEvent + { + public: + /**************************************************************************** + * \param PackagePtr - smart pointer to package data. + + * \brief Constructor for Event. User needs to dynamically allocate memory + * for package data and pass in the smart pointer so the data member + * can be initialised properly. + ****************************************************************************/ + SHEvent(PackagePtr); + + /**************************************************************************** + * \brief Get pointer to data package. + * + * \return Smart pointer to Package Base, needs to be cast to correct + * derived class. + ****************************************************************************/ + PackagePtr const& GetData() const; + + /**************************************************************************** + * \brief Gets the type of package. + ****************************************************************************/ + SHPackageType GetType() const; + private: + PackagePtr package; + }; +} + + +#endif // !SH_EVENT_BASE_H diff --git a/SHADE_Engine/src/Events/SHEventManager.cpp b/SHADE_Engine/src/Events/SHEventManager.cpp new file mode 100644 index 00000000..b1038da8 --- /dev/null +++ b/SHADE_Engine/src/Events/SHEventManager.cpp @@ -0,0 +1,144 @@ +/****************************************************************************** + * \file SHEventManager.cpp + * \author Loh Xiao Qi + * \brief Function Implmentations for SHEventManager + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior + * written consent of Digipen Institute of Technology is prohibited + ******************************************************************************/ +#include "SHpch.h" +#include "SHEventManager.h" + +namespace SHADE +{ + SHEventManager* SHEventManager::instance; + + /**************************************************************************** + * \brief Ctor and Dtor. Dtor will delete instance of self stored at + * data member instance. + ****************************************************************************/ + SHEventManager::SHEventManager() + { + + } + + /**************************************************************************** + * \brief Exit function to terminate the manager properly and deallocate + * memory. + ****************************************************************************/ + void SHEventManager::Exit() + { + delete instance; + } + + /**************************************************************************** + * \brief Returns singleton instance of event manager in heap memory. If + * instance does not exist, one is created immediately. + ****************************************************************************/ + SHEventManager& SHEventManager::GetEventManagerInstance() + { + // Create instance of event manager and return + if (!instance) + { + instance = new SHEventManager(); + } + + return *instance; + } + + /**************************************************************************** + * \brief Returns function pointer to entry point for events. + ****************************************************************************/ + EventManagerListener SHEventManager::GetListenerFunction() + { + return &(instance->CatchEvent); + } + + /**************************************************************************** + * \param ListenerConstPtr - Const pointer to listener that sent event. + * \param EventType - Templated type for every type of event + + * \brief Receives event from the listeners. + ****************************************************************************/ + void SHEventManager::CatchEvent(SHEvent event) + { + + // Do something with the event + + instance->Broadcast(event); + } + + /**************************************************************************** + * \param ResponseFunction - function pointer from receiver to be passed + * into event manager to be called when events are broadcasted. + * \param SHPackageType - package type that corresponding subscriber is + * subscribing to. + + * \brief Links a function pointer from a subscriber to a particular + * package type + ****************************************************************************/ + void SHEventManager::SubscribeTo(SHPackageType pkgType, ReceiverPtr receiver) + { + SHEventManager::GetEventManagerInstance().RegisterReceiverToType(pkgType, receiver); + } + + void SHEventManager::StaticSubscribeTo(SHPackageType pkgType, ResponseFunction func) + { + SHEventManager::GetEventManagerInstance().RegisterStaticReceiverToType(pkgType, func); + } + + /**************************************************************************** + * \param ReceiverPtr - Pointer to receiver + * \param ListenerConstPtr - Const pointer to listener that receiver is + * subscribing to. + + * \brief Registers receiver as a subscriber to listener in the registry. + ****************************************************************************/ + void SHEventManager::RegisterReceiverToType( + SHPackageType pkgType, ReceiverPtr receiver) + { + if (packageReceiverRegistry.contains(pkgType)) + { + packageReceiverRegistry[pkgType].emplace_back(receiver); + } + else + { + packageReceiverRegistry.emplace(pkgType, std::vector{ receiver }); + } + } + + void SHEventManager::RegisterStaticReceiverToType(SHPackageType pkgType, ResponseFunction func) + { + if (staticPackageReceiverRegistry.contains(pkgType)) + { + staticPackageReceiverRegistry[pkgType].emplace_back(func); + } + else + { + staticPackageReceiverRegistry.emplace(pkgType, std::vector{ func }); + } + } + + /**************************************************************************** + * \param ListenerConstPtr - Const pointer to listener that sent event. + * \param EventType - Event data + + * \brief Broadcast event to all receivers that are subscribed to this + * listener. + ****************************************************************************/ + void SHEventManager::Broadcast(SHEvent const& event) + { + ResponseVec& receivers{ packageReceiverRegistry[event.GetType()] }; + for (auto& receiver : receivers) + { + receiver->Receive(event.GetData()); + } + + auto& funcs{ staticPackageReceiverRegistry[event.GetType()] }; + for (auto func : funcs) + { + func(event.GetData()); + } + } +} diff --git a/SHADE_Engine/src/Events/SHEventManager.h b/SHADE_Engine/src/Events/SHEventManager.h new file mode 100644 index 00000000..e8d499dc --- /dev/null +++ b/SHADE_Engine/src/Events/SHEventManager.h @@ -0,0 +1,112 @@ +/****************************************************************************** + * \file SHEventManager.h + * \author Loh Xiao Qi + * \brief Class declaration for event manager. + * + * \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction + * or disclosure of this file or its contents without the prior written consent + * of Digipen Institute of Technology is prohibited. +******************************************************************************/ +#ifndef SH_EVENT_MANAGER_H +#define SH_EVENT_MANAGER_H + +#include "SHEvent.h" +#include "SHEventReceiver.h" +#include +#include +#include + +namespace SHADE +{ + using ResponseFunction = std::function; + using ReceiverPtr = std::shared_ptr; + using ResponseVec = std::vector; + using StaticResponseVec = std::vector; + + using EventManagerListener = std::function; + + class SHEventManager + { + public: + /**************************************************************************** + * \brief Ctor and Dtor. Dtor will delete instance of self stored at + * data member instance. + ****************************************************************************/ + SHEventManager(); + + /**************************************************************************** + * \brief Returns singleton instance of event manager in heap memory. If + * instance does not exist, one is created immediately. + ****************************************************************************/ + static SHEventManager& GetEventManagerInstance(); + + /**************************************************************************** + * \brief Returns function pointer to entry point for events. + ****************************************************************************/ + static EventManagerListener GetListenerFunction(); + + /**************************************************************************** + * \brief Exit function to terminate the manager properly and deallocate + * memory. + ****************************************************************************/ + static void Exit(); + + /**************************************************************************** + * \param ListenerConstPtr - Const pointer to listener that sent event. + * \param EventType - Templated type for every type of event + + * \brief Receives event from the listeners. + ****************************************************************************/ + static void CatchEvent(SHEvent); + + /**************************************************************************** + * \param ResponseFunction - function pointer from receiver to be passed + * into event manager to be called when events are broadcasted. + * \param SHPackageType - package type that corresponding subscriber is + * subscribing to. + + * \brief Links a function pointer from a subscriber to a particular + * package type + ****************************************************************************/ + void SubscribeTo(SHPackageType, ReceiverPtr); + + void StaticSubscribeTo(SHPackageType, ResponseFunction); + private: + // Singleton instance + static SHEventManager* instance; + + // Registry for broadcasters and subscribers + std::unordered_map< + SHPackageType, + ResponseVec> packageReceiverRegistry; + + // Registry for static broadcasters and subscribers + std::unordered_map< + SHPackageType, + StaticResponseVec> staticPackageReceiverRegistry; + + /**************************************************************************** + * \param ListenerConstPtr - Const pointer to listener that sent event. + * \param EventType - Event data + + * \brief Broadcast event to all receivers that are subscribed to this + * listener. + ****************************************************************************/ + void Broadcast(SHEvent const&); + + /**************************************************************************** + * \param ReceiverPtr - Pointer to receiver + * \param ListenerConstPtr - Const pointer to listener that receiver is + * subscribing to. + + * \brief Registers receiver as a subscriber to listener in the registry. + ****************************************************************************/ + void RegisterReceiverToType(SHPackageType, ReceiverPtr); + + void RegisterStaticReceiverToType(SHPackageType, ResponseFunction); + + }; + +} + +#endif // !SH_EVENTS_MANAGER_H diff --git a/SHADE_Engine/src/Events/SHEventReceiver.h b/SHADE_Engine/src/Events/SHEventReceiver.h new file mode 100644 index 00000000..387b8a97 --- /dev/null +++ b/SHADE_Engine/src/Events/SHEventReceiver.h @@ -0,0 +1,35 @@ +#ifndef SH_EVENT_RECEIVER_H +#define SH_EVENT_RECEIVER_H + +#include "SHEvent.h" + +namespace SHADE +{ + class SHEventReceiver + { + private: + public: + virtual void Receive(PackagePtr) = 0; + }; + + template + class SHEventReceiverSpec : public SHEventReceiver + { + private: + T* object; + void(T::*callback)(PackagePtr); + + public: + SHEventReceiverSpec(T* obj, void(T::*cb)(PackagePtr)) + :SHEventReceiver(), object{obj}, callback{ cb } + { + + } + + void Receive(PackagePtr evt) + { + (object->*callback)(evt); + } + }; +} +#endif // !SH_EVENT_RECEIVER_H diff --git a/SHADE_Engine/src/SHpch.h b/SHADE_Engine/src/SHpch.h index 0342eedb..43a832f3 100644 --- a/SHADE_Engine/src/SHpch.h +++ b/SHADE_Engine/src/SHpch.h @@ -30,3 +30,6 @@ #include #include #include +#include + +#include "Common/SHCommonTypes.h"