#pragma once #include enum class PxTriggerAction { ENTER, LEAVE }; class GameObject { public: typedef std::function PhysicsCallback; GameObject(); virtual ~GameObject(); GameObject(const GameObject& other) = delete; GameObject(GameObject&& other) noexcept = delete; GameObject& operator=(const GameObject& other) = delete; GameObject& operator=(GameObject&& other) noexcept = delete; template std::enable_if_t, T*> AddChild(T* pObject) { AddChild_(pObject); return pObject; } void RemoveChild(GameObject* obj, bool deleteObject = false); template std::enable_if_t, T*> AddComponent(T* pComp) { AddComponent_(pComp); return pComp; } void RemoveComponent(BaseComponent* pComponent, bool deleteObject = false); void OnTrigger(GameObject* pTriggerObject, GameObject* pOtherObject, PxTriggerAction action) const; const std::wstring& GetTag() const { return m_Tag; } void SetTag(const std::wstring& tag) { m_Tag = tag; } TransformComponent* GetTransform() const { return m_pTransform; } GameScene* GetScene() const; GameObject* GetParent() const { return m_pParentObject; } void SetOnTriggerCallBack(PhysicsCallback callback); //added for post-post draw bool IsMarkedForPostPostDraw() const { return m_IsMarkedForPPDraw; } void SetMarkedForPostPostDraw(bool isMarked) { m_IsMarkedForPPDraw = isMarked; } #pragma region template bool HasComponent(bool searchChildren = false) { return GetComponent(searchChildren) != nullptr; } template T* GetComponent(bool searchChildren = false) { const type_info& ti = typeid(T); for (auto* component : m_pComponents) { if (component && typeid(*component) == ti) return static_cast(component); } if (searchChildren) { for (auto* child : m_pChildren) { if (child->GetComponent(searchChildren) != nullptr) return child->GetComponent(searchChildren); } } return nullptr; } template std::vector GetComponents(bool searchChildren = false) { const type_info& ti = typeid(T); std::vector components; for (auto* component : m_pComponents) { if (component && typeid(*component) == ti) components.push_back(static_cast(component)); } if (searchChildren) { for (auto* child : m_pChildren) { auto childComponents = child->GetComponents(searchChildren); for (auto* childComp : childComponents) components.push_back(static_cast(childComp)); } } return components; } template T* GetChild() { const type_info& ti = typeid(T); for (auto* child : m_pChildren) { if (child && typeid(*child) == ti) return static_cast(child); } return nullptr; } template std::vector GetChildren() { const type_info& ti = typeid(T); std::vector children; for (auto* child : m_pChildren) { if (child && typeid(*child) == ti) children.push_back(static_cast(child)); } return children; } #pragma endregion Template Methods protected: virtual void Initialize(const SceneContext&) {}; virtual void PostInitialize(const SceneContext& ) {} virtual void Draw(const SceneContext&) {} virtual void PostDraw(const SceneContext&) {} virtual void Update(const SceneContext&) {} virtual void OnParentAttach(GameObject* /*pParent*/) {} virtual void OnParentDetach(GameObject* /*pPreviousParent*/) {} virtual void OnSceneAttach(GameScene* /*pScene*/){} virtual void OnSceneDetach(GameScene* /*pScene*/){} private: friend class GameScene; //Handles private interface void RootInitialize(const SceneContext& sceneContext); void RootPostInitialize(const SceneContext& sceneContext); void RootUpdate(const SceneContext& sceneContext); void RootDraw(const SceneContext& sceneContext); void RootPostDraw(const SceneContext& sceneContext); //TODO: collapse in single Draw with context void RootShadowMapDraw(const SceneContext& sceneContext) const; //TODO: collapse in single Draw with context void RootOnSceneAttach(GameScene* pScene); void RootOnSceneDetach(GameScene* pScene); void AddChild_(GameObject* pObject); void AddComponent_(BaseComponent* pComponent); std::vector m_pChildren{}; std::vector m_pComponents{}; bool m_IsInitialized{}, m_IsActive{}; GameScene* m_pParentScene{}; GameObject* m_pParentObject{}; TransformComponent* m_pTransform{}; PhysicsCallback m_OnTriggerCallback{}; std::wstring m_Tag{}; bool m_IsMarkedForPPDraw{ false }; };