Implemented some fixes to collider. Made pickables use collider. Partial implementation of stackable objects.

This commit is contained in:
2016-12-21 21:49:10 +02:00
parent a7af100122
commit fc2597302b
12 changed files with 221 additions and 91 deletions

View File

@@ -9,6 +9,8 @@
#include <model/GameObject.h>
#include <model/Component.h>
#include <model/Transform.h>
#include <algorithm>
#include <iostream>
namespace farmlands {
@@ -18,10 +20,12 @@ GameObject::GameObject()
: name("unnamed"),
visible(true),
transform(this),
m_components(),
m_children(),
m_enabled(false),
m_parent(nullptr),
m_enabled(false)
m_children(),
m_childRemoveQueue(),
m_components(),
m_componentRemoveQueue()
{
}
@@ -105,42 +109,48 @@ void GameObject::addChild(GameObject* obj)
GameObject* GameObject::removeChild(GameObject::ChildrenIterator it)
{
m_children.erase(it);
ChildRemoveQueueItem item =
{
.data = *it,
.free = false
};
m_childRemoveQueue.push_back(item);
(*it)->m_parent = nullptr;
return *it;
}
GameObject* GameObject::removeChild(GameObject* obj)
{
for (auto it = m_children.begin(); it != m_children.end(); it++)
ChildRemoveQueueItem item =
{
if (*it == obj)
{
m_children.erase(it);
obj->m_parent = nullptr;
return *it;
}
}
.data = obj,
.free = false
};
m_childRemoveQueue.push_back(item);
obj->m_parent = nullptr;
return nullptr;
}
void GameObject::destroyChild(GameObject::ChildrenIterator it)
{
delete *it;
m_children.erase(it);
ChildRemoveQueueItem item =
{
.data = *it,
.free = true
};
m_childRemoveQueue.push_back(item);
}
void GameObject::destroyChild(GameObject* obj)
{
for (auto it = m_children.begin(); it != m_children.end(); it++)
ChildRemoveQueueItem item =
{
if (*it == obj)
{
delete *it;
m_children.erase(it);
return;
}
}
.data = obj,
.free = true
};
m_childRemoveQueue.push_back(item);
}
size_t GameObject::childrenSize() const
@@ -264,6 +274,18 @@ void GameObject::onPostRender()
for (auto child : m_children)
if (child->m_enabled && child->visible)
child->onPostRender();
// Process removals at end of frame
processRemovals();
}
void GameObject::onFrameEnded()
{
// Call children
for (auto child : m_children)
child->onFrameEnded();
processRemovals();
}
void GameObject::onEnable()
@@ -332,6 +354,38 @@ void GameObject::dumpTree(unsigned level)
child->dumpTree(level + 1);
}
void GameObject::processRemovals()
{
// Remove components/children at end of frame
for (auto item : m_childRemoveQueue)
{
auto it = std::find(m_children.begin(), m_children.end(), item.data);
if (it != m_children.end())
{
m_children.erase(it);
if (item.free)
{
item.data->onDestroy();
delete item.data;
}
}
}
m_childRemoveQueue.clear();
for (auto item : m_componentRemoveQueue)
{
m_components.erase(item.index);
if (item.free)
{
item.data->onDestroy();
delete item.data;
}
}
m_componentRemoveQueue.clear();
}
} /* namespace model */
} /* namespace farmlands */

View File

@@ -15,9 +15,10 @@
#include <SDL2/SDL.h>
#include <queue>
#include <typeindex>
#include <vector>
#include <unordered_map>
#include <vector>
namespace farmlands {
namespace model {
@@ -37,8 +38,11 @@ namespace model {
// Constructors
GameObject();
virtual ~GameObject();
// Cloneable
virtual GameObject* clone() override;
// Static methods
static GameObject* instantiate(GameObject* gameObject, std::string name, GameObject* parent);
// Components API
@@ -83,6 +87,7 @@ namespace model {
void onPreRender();
void onRender();
void onPostRender();
void onFrameEnded();
void onDestroy();
void onEnable();
@@ -98,18 +103,39 @@ namespace model {
// Other properties
std::string name;
bool visible;
bool persistent;
Transform transform;
private:
// Components
ComponentContainer m_components;
struct ComponentRemoveQueueItem
{
std::type_index index;
Component* data;
bool free;
};
// Tree
ChildrenContainer m_children;
GameObject* m_parent;
struct ChildRemoveQueueItem
{
GameObject* data;
bool free;
};
typedef std::vector<ComponentRemoveQueueItem> ComponentRemoveQueue;
typedef std::vector<ChildRemoveQueueItem> ChildRemoveQueue;
void processRemovals();
// Properties
bool m_enabled;
// Tree
GameObject* m_parent;
ChildrenContainer m_children;
ChildRemoveQueue m_childRemoveQueue;
// Components
ComponentContainer m_components;
ComponentRemoveQueue m_componentRemoveQueue;
};
template <typename T>
@@ -160,8 +186,14 @@ namespace model {
auto it = m_components.find(typeIndex);
if (it != m_components.end())
{
comp = dynamic_cast<T*>(it->second);
m_components.erase(it);
ComponentRemoveQueueItem item =
{
.index = typeIndex,
.data = it->second,
.free = false
};
m_componentRemoveQueue.push_back(item);
// it->second->gameObject = nullptr;
}
return comp;
@@ -176,10 +208,13 @@ namespace model {
auto it = m_components.find(typeIndex);
if (it != m_components.end())
{
T* comp = dynamic_cast<T*>(it->second);
m_components.erase(it);
delete comp;
ComponentRemoveQueueItem item =
{
.index = typeIndex,
.data = it->second,
.free = true
};
m_componentRemoveQueue.push_back(item);
}
}