Newer
Older
Import / projects / Gameloft / bne_lib / code / Utils / ChildObject.h
#ifndef _CHILD_OBJECT_H_
#define _CHILD_OBJECT_H_

#include "Cast.h"
#include "ObjectUtils.h"

/// \brief Helper class to keep track of objects spawned onto parent objects. 
///        It is not added to a level directly - must be manually Clear()ed in DeInit() of parent.
template<typename T = CasualCore::Object>
class ChildObject
{
public:

  /// \brief Create the named object - will delete any existing object
  /// \param a_parent The parent to attach the object to
  /// \param a_objectName The name of the object to load
  /// \return Returns true on success
  bool Create(CasualCore::Object* a_parent, const char* a_objectName)
  {
    // Delete any existing object
    Clear();

    if (a_parent == nullptr) {
      return false;
    }
  
    // Create new object
#if defined(BNE_OBJECT_CROSSOVER)
    RKTransformObject* newObj = bne::object::CreateFromTemplate(a_objectName, a_parent);
#else // (!)defined(BNE_OBJECT_CROSSOVER)
    RKTransformObject* newObj = bne::CreateObjectFromFriendlyRKIName(a_objectName);
#endif // defined(BNE_OBJECT_CROSSOVER)

    // Cast to the correct type
    m_object = CCPTR_CAST(T, newObj);
    if (m_object == nullptr) {
#if defined(BNE_OBJECT_CROSSOVER)
      bne::object::Destroy(newObj);
#else // (!)defined(BNE_OBJECT_CROSSOVER)
      bne::DestroyObject(newObj);
#endif // defined(BNE_OBJECT_CROSSOVER)
      return false;
    }
 
#if !defined(BNE_OBJECT_CROSSOVER)
    m_object->SetParent(a_parent);                // Set parent
#endif // !defined(BNE_OBJECT_CROSSOVER)
    m_object->SetPosition(RKVector::Origin);      // Set position/rotation (seems to be necessary after attaching to parent)
    m_object->SetRotation(RKQuaternion::Identity); 
    return true;
  }

  /// \brief Clears out the item - should be called from the destructor of the parent object
  void Clear() 
  {
    if (m_object != nullptr)
    {
#if defined(BNE_OBJECT_CROSSOVER)
      bne::object::Destroy(m_object);
#else // (!)defined(BNE_OBJECT_CROSSOVER)
      bne::DestroyObject(m_object);
#endif // defined(BNE_OBJECT_CROSSOVER)
      m_object = nullptr;
    }
  }

  /// \brief Get access to the contained object
  inline T* Get()
  {
    return m_object;
  }  
  
  inline const T* Get() const
  {
    return m_object;
  }  
  
protected:

  T* m_object = nullptr; //!< The contained object
  
};

#endif // _CHILD_OBJECT_H_