Implemented some fixes to collider. Made pickables use collider. Partial implementation of stackable objects.
This commit is contained in:
@@ -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 */
|
||||
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user