HatchitGame
ht_gameobject.h
1 
26 #pragma once
27 
28 #include <vector>
29 #include <unordered_map>
30 #include <tuple>
31 #include <utility>
32 
33 #include <ht_platform.h>
34 #include <ht_transform.h>
35 #include <ht_guid.h>
36 
37 #ifdef HT_SYS_LINUX
38  #include <cstdlib>
39 #endif
40 
41 #include <ht_component.h>
42 
43 namespace Hatchit {
44 
45  namespace Game {
46  class Scene;
47 
48  class HT_API GameObject
49  {
50  friend class Scene;
51  public:
52  GameObject(const GameObject& rhs) = default;
53  GameObject(GameObject&& rhs) = default;
54  GameObject& operator=(const GameObject& rhs) = default;
55  GameObject& operator=(GameObject&& rhs) = default;
56 
60  const Core::Guid& GetGuid(void) const;
61 
65  const std::string& GetName(void) const;
66 
70  Transform& GetTransform(void);
71 
76  bool GetEnabled(void) const;
77 
82  void SetEnabled(bool value);
83 
87  inline void Enable(void)
88  {
89  SetEnabled(true);
90  }
91 
95  inline void Disable(void)
96  {
97  SetEnabled(false);
98  }
99 
104  GameObject* GetParent(void);
105 
110  void SetParent(GameObject *parent);
111 
117  GameObject* GetChildAtIndex(std::size_t index);
118 
123  void AddChild(GameObject *child);
124 
129  void RemoveChildAtIndex(std::size_t index);
130 
135  void RemoveChild(GameObject *child);
136 
140  void OnInit(void);
141 
147  void Update(void);
148 
149 
154  void MarkForDestroy(void);
155 
156 
166  template <typename T>
167  bool AddComponent(T *component);
168 
180  template <typename T, typename... Args>
181  bool AddComponent(Args&&... args);
182 
190  template <typename T>
191  bool RemoveComponent(void);
192 
198  template <typename T>
199  bool HasComponent(void) const;
200 
208  template <typename T1, typename T2, typename... Args>
209  bool HasComponent(void) const;
210 
217  template <typename T>
218  T* GetComponent(void);
219 
226  template <typename... Args>
227  std::tuple<Args*...> GetComponents(void);
228 
235  template <typename T>
236  bool EnableComponent(void);
237 
244  template <typename... Args>
245  auto EnableComponents(void) -> decltype(std::make_tuple(EnableComponent<Args>()...))
246  {
247  return std::make_tuple(EnableComponent<Args>()...);
248  }
249 
256  template <typename T>
257  bool DisableComponent(void);
258 
264  template <typename... Args>
265  auto DisableComponents(void) -> decltype(std::make_tuple(DisableComponent<Args>()...))
266  {
267  return std::make_tuple(DisableComponent<Args>()...);
268  }
269 
270  private:
271 
272 
278  GameObject(void);
279 
292  GameObject(const Core::Guid guid, const std::string name, Transform t, bool enabled);
293 
294 
299  ~GameObject(void);
300 
301 
305  void OnEnabled(void);
306 
307 
311  void OnDisabled(void);
312 
313 
321  template<typename T>
322  bool AddUninitializedComponent(T *component);
323 
335  template <typename T, typename... Args>
336  bool AddUninitializedComponent(Args&&... args);
337 
338  bool m_enabled;
339  bool m_destroyed;//* < bool indicating that this object is to be destroyed on the next update call*/
340  std::string m_name;
341  Core::Guid m_guid;
342  Transform m_transform;
343  GameObject *m_parent;
344  std::vector<GameObject*> m_children;
345  std::vector<Game::Component*> m_components;
346  std::unordered_map<Core::Guid, std::vector<Component*>::size_type> m_componentMap;
347  };
348 
349 
350  template <typename T>
351  bool GameObject::AddComponent(T *component)
352  {
353  static_assert(std::is_base_of<Component, T>::value, "Must be a sub-class of Hatchit::Game::Component!");
354 
355  Core::Guid component_id = Game::Component::template GetComponentId<T>();
356  std::unordered_map<Core::Guid, std::vector<Component*>::size_type>::const_iterator iter = m_componentMap.find(component_id);
357  if (iter != m_componentMap.cend())
358  return false;
359 
360  m_componentMap.insert(std::make_pair(component_id, m_components.size()));
361  m_components.push_back(component);
362 
363  component->SetOwner(this);
364 
365  component->VOnInit();
366 
367  if(m_enabled)
368  component->VOnEnable();
369 
370  return true;
371  }
372 
373  template <>
374  inline bool GameObject::AddComponent<Component>(Component *component)
375  {
376  Core::Guid component_id = component->VGetComponentId();
377  std::unordered_map<Core::Guid, std::vector<Component*>::size_type>::const_iterator iter = m_componentMap.find(component_id);
378  if (iter != m_componentMap.cend())
379  return false;
380 
381  m_componentMap.insert(std::make_pair(component_id, m_components.size()));
382  m_components.push_back(component);
383 
384  component->SetOwner(this);
385 
386  component->VOnInit();
387 
388  if (m_enabled)
389  component->SetEnabled(true);
390 
391  return true;
392  }
393 
394  template <typename T, typename... Args>
395  bool GameObject::AddComponent(Args&&... args)
396  {
397  static_assert(std::is_base_of<Component, T>::value && !std::is_same<Component, T>::value, "Must be a sub-class of Hatchit::Game::Component!");
398 
399  Core::Guid component_id = Game::Component:: template GetComponentId<T>();
400  std::unordered_map<Core::Guid, std::vector<Component*>::size_type>::const_iterator iter = m_componentMap.find(component_id);
401  if (iter != m_componentMap.cend())
402  return false;
403 
404  T *component = new T(std::forward<Args>(args)...);
405  m_componentMap.insert(std::make_pair(component_id, m_components.size()));
406  m_components.push_back(component);
407 
408  component->SetOwner(this);
409 
410  component->VOnInit();
411 
412  if (m_enabled)
413  component->VOnEnable();
414 
415  return true;
416  }
417 
418  template <typename T>
420  {
421  static_assert(std::is_base_of<Component, T>::value && !std::is_same<Component, T>::value, "Must be a sub-class of Hatchit::Game::Component!");
422 
423  Core::Guid component_id = Game::Component:: template GetComponentId<T>();
424  std::unordered_map<Core::Guid, std::vector<Component*>::size_type>::const_iterator iter = m_componentMap.find(component_id);
425  if (iter == m_componentMap.cend())
426  return false;
427 
428  std::vector<Component*>::size_type index = m_componentMap[component_id];
429  Component *component = m_components[index];
430  if(component->GetEnabled())
431  component->SetEnabled(false);
432  component->VOnDestroy();
433 
434  m_components[index] = nullptr;
435  m_componentMap.erase(component_id);
436  delete component;
437 
438  return true;
439  }
440 
441  template <typename T>
442  bool GameObject::HasComponent(void) const
443  {
444  static_assert(std::is_base_of<Component, T>::value && !std::is_same<Component, T>::value, "Must be a sub-class of Hatchit::Game::Component!");
445  Core::Guid component_id = Component:: template GetComponentId<T>();
446  return (m_componentMap.find(component_id) != m_componentMap.cend());
447  }
448 
449  template <typename T1, typename T2, typename... Args>
450  bool GameObject::HasComponent(void) const
451  {
452  static_assert(std::is_base_of<Component, T1>::value && !std::is_same<Component, T1>::value, "Must be a sub-class of Hatchit::Game::Component!");
453  return HasComponent<T1>() && HasComponent<T2, Args...>();
454  }
455 
456  template <typename T>
458  {
459  static_assert(std::is_base_of<Component, T>::value && !std::is_same<Component, T>::value, "Must be a sub-class of Hatchit::Game::Component!");
460 
461  Core::Guid component_id = Component::GetComponentId<T>();
462  std::unordered_map<Core::Guid, std::vector<Component*>::size_type>::const_iterator iter = m_componentMap.find(component_id);
463  if (iter == m_componentMap.cend())
464  return nullptr;
465 
466  std::vector<Component*>::size_type index = m_componentMap[component_id];
467  return dynamic_cast<T*>(m_components[index]);
468  }
469 
470  template <typename... Args>
471  std::tuple<Args*...> GameObject::GetComponents(void)
472  {
473  return std::make_tuple(GetComponent<Args>()...);
474  }
475 
476  template <typename T>
478  {
479  static_assert(std::is_base_of<Component, T>::value && !std::is_same<Component, T>::value, "Must be a sub-class of Hatchit::Game::Component!");
480 
481  if (!HasComponent<T>())
482  return false;
483 
484  Core::Guid component_id = Component::GetComponentId<T>();
485  std::vector<Component*>::size_type index = m_componentMap[component_id];
486  Component *component = m_components[index];
487  if (component->GetEnabled())
488  return false;
489 
490  component->SetEnabled(true);
491 
492  return true;
493  }
494 
495  template <typename T>
497  {
498  static_assert(std::is_base_of<Component, T>::value && !std::is_same<Component, T>::value, "Must be a sub-class of Hatchit::Game::Component!");
499 
500  if (!HasComponent<T>())
501  return false;
502 
503  Core::Guid component_id = Component::GetComponentId<T>();
504  std::vector<Component*>::size_type index = m_componentMap[component_id];
505  Component *component = m_components[index];
506  if (!component->GetEnabled())
507  return false;
508 
509  component->SetEnabled(false);
510 
511  return true;
512  }
513 
514  template<typename T>
515  inline bool GameObject::AddUninitializedComponent(T* component)
516  {
517  static_assert(std::is_base_of<Component, T>::value, "Must be a sub-class of Hatchit::Game::Component!");
518 
519  Core::Guid component_id = Component::GetComponentId<T>();
520  std::unordered_map<Core::Guid, std::vector<Component*>::size_type>::const_iterator iter = m_componentMap.find(component_id);
521  if (iter != m_componentMap.cend())
522  return false;
523 
524  m_componentMap.insert(std::make_pair(component_id, m_components.size()));
525  m_components.push_back(component);
526 
527  component->SetOwner(this);
528 
529  return true;
530  }
531 
532  template<>
533  inline bool GameObject::AddUninitializedComponent<Component>(Component* component)
534  {
535  Core::Guid component_id = component->VGetComponentId();
536  std::unordered_map<Core::Guid, std::vector<Component*>::size_type>::const_iterator iter = m_componentMap.find(component_id);
537  if (iter != m_componentMap.cend())
538  return false;
539 
540  m_componentMap.insert(std::make_pair(component_id, m_components.size()));
541  m_components.push_back(component);
542 
543  component->SetOwner(this);
544 
545  return true;
546  }
547 
548  template<typename T, typename ...Args>
549  inline bool GameObject::AddUninitializedComponent(Args && ...args)
550  {
551  static_assert(std::is_base_of<Component, T>::value && !std::is_same<Component, T>::value, "Must be a sub-class of Hatchit::Game::Component!");
552 
553  Core::Guid component_id = Game::Component:: template GetComponentId<T>();
554  std::unordered_map<Core::Guid, std::vector<Component*>::size_type>::const_iterator iter = m_componentMap.find(component_id);
555  if (iter != m_componentMap.cend())
556  return false;
557 
558  T *component = new T(std::forward<Args>(args)...);
559  m_componentMap.insert(std::make_pair(component_id, m_components.size()));
560  m_components.push_back(component);
561 
562  component->SetOwner(this);
563 
564  return true;
565  }
566  }
567 }
auto DisableComponents(void) -> decltype(std::make_tuple(DisableComponent< Args >()...))
Disable Components of type Args...
Definition: ht_gameobject.h:265
void Disable(void)
An inline for SetEnabled(false);.
Definition: ht_gameobject.h:95
virtual void VOnDestroy(void)=0
Called when the GameObject is destroyed/deleted.
void Enable(void)
An inline for SetEnabled(true);.
Definition: ht_gameobject.h:87
void SetEnabled(bool value)
Setter that sets the value of m_enabled.
Definition: ht_component.cpp:36
Definition: ht_transform.h:25
Definition: ht_component.h:42
T * GetComponent(void)
Return a Component of type T attached to this GameObject.
Definition: ht_gameobject.h:457
Hatchit Engine Copyright(c) 2015-2016 Third-Degree.
Definition: ht_glfwkeyboard.h:21
Definition: ht_gameobject.h:48
bool AddComponent(T *component)
Attempts to attach a Component of type T.
Definition: ht_gameobject.h:351
std::tuple< Args *... > GetComponents(void)
Returns Components of type Args...
Definition: ht_gameobject.h:471
bool DisableComponent(void)
Disable a Component of type T attached to this GameObject.
Definition: ht_gameobject.h:496
bool EnableComponent(void)
Enable a Component of type T attached to this GameObject.
Definition: ht_gameobject.h:477
bool HasComponent(void) const
Test if a Component of type T is attached to this GameObject.
Definition: ht_gameobject.h:442
auto EnableComponents(void) -> decltype(std::make_tuple(EnableComponent< Args >()...))
Enable Components of type Args...
Definition: ht_gameobject.h:245
bool RemoveComponent(void)
Attempts to remove a Component of type T.
Definition: ht_gameobject.h:419
bool GetEnabled(void)
Getter that returns that value of m_enabled.
Definition: ht_component.cpp:31
Defines a scene.
Definition: ht_scene.h:44