338 lines
6.1 KiB
C++
338 lines
6.1 KiB
C++
/*
|
|
* GameObject.cpp
|
|
*
|
|
* Created on: Nov 30, 2016
|
|
* Author: tibi
|
|
*/
|
|
|
|
#include <GameState.h>
|
|
#include <model/GameObject.h>
|
|
#include <model/Component.h>
|
|
#include <model/Transform.h>
|
|
#include <iostream>
|
|
|
|
namespace farmlands {
|
|
namespace model {
|
|
|
|
GameObject::GameObject()
|
|
: name("unnamed"),
|
|
visible(true),
|
|
transform(this),
|
|
m_components(),
|
|
m_children(),
|
|
m_parent(nullptr),
|
|
m_enabled(false)
|
|
{
|
|
}
|
|
|
|
GameObject* GameObject::clone()
|
|
{
|
|
GameObject* clone = new GameObject();
|
|
clone->visible = visible;
|
|
|
|
// Clone components
|
|
for (auto pair : m_components)
|
|
{
|
|
Component* compClone = pair.second->clone();
|
|
compClone->gameObject = clone;
|
|
|
|
clone->m_components.emplace(pair.first, compClone);
|
|
}
|
|
|
|
// Clone components
|
|
for (auto child : m_children)
|
|
clone->addChild(child->clone());
|
|
|
|
return clone;
|
|
}
|
|
|
|
GameObject::~GameObject()
|
|
{
|
|
// Delete children
|
|
for (auto child : m_children)
|
|
{
|
|
child->onDestroy();
|
|
delete child;
|
|
}
|
|
|
|
// Delete components
|
|
for (auto pair : m_components)
|
|
{
|
|
pair.second->onDestroy();
|
|
delete pair.second;
|
|
}
|
|
}
|
|
|
|
|
|
GameObject* GameObject::instantiate(GameObject* gameObject, std::string name, GameObject* parent)
|
|
{
|
|
Assert(gameObject != nullptr, "Can't instantiate a null object!");
|
|
Assert(parent != nullptr, "Parent cannot be null!");
|
|
|
|
// Clone object
|
|
GameObject* instance = gameObject->clone();
|
|
instance->name = name;
|
|
parent->addChild(instance);
|
|
|
|
// Call methods
|
|
instance->onCreate();
|
|
if (GameState::current().gameInitialized)
|
|
instance->onInitialize();
|
|
|
|
return instance;
|
|
}
|
|
|
|
size_t GameObject::componentsSize() const
|
|
{
|
|
return m_components.size();
|
|
}
|
|
|
|
GameObject::ComponentIterator GameObject::componentsBegin()
|
|
{
|
|
return m_components.begin();
|
|
}
|
|
|
|
GameObject::ComponentIterator GameObject::componentsEnd()
|
|
{
|
|
return m_components.end();
|
|
}
|
|
|
|
void GameObject::addChild(GameObject* obj)
|
|
{
|
|
m_children.push_back(obj);
|
|
obj->m_parent = this;
|
|
}
|
|
|
|
GameObject* GameObject::removeChild(GameObject::ChildrenIterator it)
|
|
{
|
|
m_children.erase(it);
|
|
return *it;
|
|
}
|
|
|
|
GameObject* GameObject::removeChild(GameObject* obj)
|
|
{
|
|
for (auto it = m_children.begin(); it != m_children.end(); it++)
|
|
{
|
|
if (*it == obj)
|
|
{
|
|
m_children.erase(it);
|
|
obj->m_parent = nullptr;
|
|
return *it;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void GameObject::destroyChild(GameObject::ChildrenIterator it)
|
|
{
|
|
delete *it;
|
|
m_children.erase(it);
|
|
}
|
|
|
|
void GameObject::destroyChild(GameObject* obj)
|
|
{
|
|
for (auto it = m_children.begin(); it != m_children.end(); it++)
|
|
{
|
|
if (*it == obj)
|
|
{
|
|
delete *it;
|
|
m_children.erase(it);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
size_t GameObject::childrenSize() const
|
|
{
|
|
return m_children.size();
|
|
}
|
|
|
|
GameObject::ChildrenIterator GameObject::childrenBegin()
|
|
{
|
|
return m_children.begin();
|
|
}
|
|
|
|
GameObject::ChildrenIterator GameObject::childrenEnd()
|
|
{
|
|
return m_children.end();
|
|
}
|
|
|
|
GameObject* GameObject::parent()
|
|
{
|
|
return m_parent;
|
|
}
|
|
|
|
GameObject::ChildrenIterator GameObject::findByName(std::string name)
|
|
{
|
|
return findByName(name, childrenBegin());
|
|
}
|
|
|
|
GameObject::ChildrenIterator GameObject::findByName(std::string name, ChildrenIterator begin)
|
|
{
|
|
for (auto it = begin; it != childrenEnd(); it++)
|
|
if ((*it)->name == name)
|
|
return it;
|
|
|
|
return childrenEnd();
|
|
}
|
|
|
|
void GameObject::onCreate()
|
|
{
|
|
// Enable self
|
|
setEnabled(true);
|
|
|
|
// Call components
|
|
for (auto pair : m_components)
|
|
pair.second->onCreate();
|
|
|
|
// Call children
|
|
for (auto child : m_children)
|
|
child->onCreate();
|
|
}
|
|
|
|
void GameObject::onInitialize()
|
|
{
|
|
// Call components
|
|
for (auto pair : m_components)
|
|
pair.second->onInitialize();
|
|
|
|
// Call children
|
|
for (auto child : m_children)
|
|
child->onInitialize();
|
|
}
|
|
|
|
bool GameObject::onEvent(SDL_Event& event)
|
|
{
|
|
bool handled = false;
|
|
|
|
// Call components
|
|
for (auto it = m_components.begin(); it != m_components.end() && !handled; it++)
|
|
handled = it->second->onEvent(event);
|
|
|
|
// Call children
|
|
for (auto it = m_children.begin(); it != m_children.end() && !handled; it++)
|
|
if ((*it)->m_enabled)
|
|
handled = (*it)->onEvent(event);
|
|
|
|
return handled;
|
|
}
|
|
|
|
void GameObject::onUpdateLogic()
|
|
{
|
|
// Call components
|
|
for (auto pair : m_components)
|
|
pair.second->onUpdateLogic();
|
|
|
|
// Call children
|
|
for (auto child : m_children)
|
|
if (child->m_enabled)
|
|
child->onUpdateLogic();
|
|
}
|
|
|
|
void GameObject::onPreRender()
|
|
{
|
|
// Call components
|
|
for (auto pair : m_components)
|
|
pair.second->onPreRender();
|
|
|
|
// Call children
|
|
for (auto child : m_children)
|
|
if (child->m_enabled && child->visible)
|
|
child->onPreRender();
|
|
}
|
|
|
|
void GameObject::onRender()
|
|
{
|
|
// Call components
|
|
for (auto pair : m_components)
|
|
pair.second->onRender();
|
|
|
|
// Call children
|
|
for (auto child : m_children)
|
|
if (child->m_enabled && child->visible)
|
|
child->onRender();
|
|
}
|
|
|
|
void GameObject::onPostRender()
|
|
{
|
|
// Call components
|
|
for (auto pair : m_components)
|
|
pair.second->onPostRender();
|
|
|
|
// Call children
|
|
for (auto child : m_children)
|
|
if (child->m_enabled && child->visible)
|
|
child->onPostRender();
|
|
}
|
|
|
|
void GameObject::onEnable()
|
|
{
|
|
// Call components
|
|
for (auto pair : m_components)
|
|
pair.second->onEnable();
|
|
|
|
// Call children
|
|
for (auto child : m_children)
|
|
if (child->enabled())
|
|
child->onEnable();
|
|
}
|
|
|
|
void GameObject::onDisable()
|
|
{
|
|
// Call components
|
|
for (auto pair : m_components)
|
|
pair.second->onDisable();
|
|
|
|
// Call children
|
|
for (auto child : m_children)
|
|
if (child->enabled())
|
|
child->onDisable();
|
|
}
|
|
|
|
void GameObject::onDestroy()
|
|
{
|
|
// Don't call onDestroy on children/components
|
|
// because it will be called in the destructor
|
|
}
|
|
|
|
void GameObject::setEnabled(bool enabled)
|
|
{
|
|
// Don't set again
|
|
if (m_enabled == enabled)
|
|
return;
|
|
|
|
m_enabled = enabled;
|
|
|
|
// If parent is disabled, we are disabled
|
|
if (m_parent == nullptr || m_parent->enabled())
|
|
{
|
|
// Call onEnable/onDisable
|
|
if (enabled) onEnable();
|
|
else onDisable();
|
|
}
|
|
}
|
|
|
|
void GameObject::dumpTree(unsigned level)
|
|
{
|
|
// Print spaces
|
|
for (unsigned i = 0; i < level; i++)
|
|
std::cout<<" ";
|
|
|
|
// Game object info
|
|
std::cout << "* GameObject: " << name << "[";
|
|
std::cout << ((m_enabled) ? "e" : " ") << "][";
|
|
std::cout << ((visible) ? "v" : " ") << "]\n";
|
|
|
|
// Components
|
|
for (auto component : m_components)
|
|
component.second->dump(level);
|
|
|
|
for (auto child : m_children)
|
|
child->dumpTree(level + 1);
|
|
}
|
|
|
|
} /* namespace model */
|
|
} /* namespace farmlands */
|
|
|