Files
axyz/src/Engine/Core/EntityWrapper.cpp
T

249 lines
6.8 KiB
C++

#include "Core/EntityWrapper.h"
#include "Core/World.h"
const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Invalid);
const std::string EntityWrapper::Name() const
{
return World->GetName(ID);
}
bool EntityWrapper::HasComponent(const std::string& componentName)
{
if (!Valid()) {
return false;
}
return World->HasComponent(ID, componentName);
}
void EntityWrapper::AttachComponent(const char* componentName)
{
if (!Valid()) {
LOG_WARNING("Could not attach \"%s\" component to #%i, entity is not valid.", componentName, ID);
return;
}
World->AttachComponent(ID, componentName);
}
EntityWrapper EntityWrapper::Parent()
{
if (this->World == nullptr || this->ID == EntityID_Invalid) {
return EntityWrapper::Invalid;
} else {
return EntityWrapper(this->World, this->World->GetParent(this->ID));
}
}
EntityWrapper EntityWrapper::FirstParentByName(const std::string& parentEntityName)
{
EntityWrapper entity = *this;
while (entity.Parent().Valid()) {
entity = entity.Parent();
if (entity.Name() == parentEntityName) {
return entity;
}
}
return EntityWrapper::Invalid;
}
EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
{
return firstChildByNameRecursive(name, this->ID);
}
EntityWrapper EntityWrapper::FirstLevelChildByName(const std::string& name)
{
EntityID parent = this->ID;
if (!this->World->ValidEntity(parent)) {
return EntityWrapper::Invalid;
}
auto itPair = this->World->GetDirectChildren(parent);
if (itPair.first == itPair.second) {
return EntityWrapper::Invalid;
}
for (auto it = itPair.first; it != itPair.second; ++it) {
std::string itName = this->World->GetName(it->second);
if (itName == name) {
return EntityWrapper(this->World, it->second);
} else if (it->second != EntityID_Invalid) {
continue;
}
}
return EntityWrapper::Invalid;
}
EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& componentType)
{
EntityWrapper entity = *this;
while (entity.Parent().Valid()) {
entity = entity.Parent();
if (entity.HasComponent(componentType)) {
return entity;
}
}
return EntityWrapper::Invalid;
}
EntityWrapper EntityWrapper::Clone(EntityWrapper parent /*= Invalid*/)
{
if (!Valid()) {
return EntityWrapper::Invalid;
}
EntityWrapper clone = cloneRecursive(*this, EntityWrapper::Invalid);
this->World->SetParent(clone.ID, parent.ID);
return clone;
}
std::vector<EntityWrapper> EntityWrapper::ChildrenWithComponent(const std::string& componentType)
{
std::vector<EntityWrapper> childrenWithComponent;
childrenWithComponentRecursive(componentType, *this, childrenWithComponent);
return childrenWithComponent;
}
void EntityWrapper::DeleteChildren()
{
auto itPair = this->World->GetDirectChildren(this->ID);
if (itPair.first == itPair.second) {
return;
}
std::vector<EntityID> entitiesToDelete;
for (auto it = itPair.first; it != itPair.second; it++) {
entitiesToDelete.push_back(it->second);
}
for (auto& e : entitiesToDelete) {
this->World->DeleteEntity(e);
}
}
bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
{
EntityWrapper entity = *this;
while (entity.Parent().Valid()) {
entity = entity.Parent();
if (entity == potentialParent) {
return true;
}
}
return false;
}
bool EntityWrapper::Valid() const
{
if (this->World == nullptr) {
return false;
}
if (this->ID == EntityID_Invalid) {
return false;
}
if (!this->World->ValidEntity(this->ID)) {
return false;
}
return true;
}
ComponentWrapper EntityWrapper::operator[](const char* componentName)
{
if (World->HasComponent(ID, componentName)) {
return World->GetComponent(ID, componentName);
} else {
LOG_WARNING("EntityWrapper implicitly attached \"%s\" component to #%i as a result of a fetch request!", componentName, ID);
return World->AttachComponent(ID, componentName);
}
}
ComponentWrapper EntityWrapper::operator[](const std::string& componentName)
{
return this->operator[](componentName.c_str());
}
bool EntityWrapper::operator==(const EntityWrapper& e) const
{
return (this->ID == e.ID) && (this->World == e.World);
}
bool EntityWrapper::operator!=(const EntityWrapper& e) const
{
return !this->operator==(e);
}
EntityWrapper::operator EntityID() const
{
return this->ID;
}
EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name, EntityID parent)
{
if (!this->World->ValidEntity(parent)) {
return EntityWrapper::Invalid;
}
auto itPair = this->World->GetDirectChildren(parent);
if (itPair.first == itPair.second) {
return EntityWrapper::Invalid;
}
for (auto it = itPair.first; it != itPair.second; ++it) {
std::string itName = this->World->GetName(it->second);
if (itName == name) {
return EntityWrapper(this->World, it->second);
} else if (it->second != EntityID_Invalid) {
EntityWrapper result = firstChildByNameRecursive(name, it->second);
if (result != EntityWrapper::Invalid) {
return result;
}
}
}
return EntityWrapper::Invalid;
}
EntityWrapper EntityWrapper::cloneRecursive(EntityWrapper entity, EntityWrapper parent)
{
EntityWrapper clone = EntityWrapper(entity.World, entity.World->CreateEntity(parent.ID));
entity.World->SetName(clone.ID, entity.Name());
// Clone components
for (auto& kv : entity.World->GetComponentPools()) {
if (kv.second->KnowsEntity(entity.ID)) {
ComponentWrapper c1 = kv.second->GetByEntity(entity.ID);
ComponentWrapper c2 = entity.World->AttachComponent(clone.ID, kv.first);
c1.Copy(c2);
}
}
// Clone children
auto children = entity.World->GetDirectChildren(entity.ID);
for (auto it = children.first; it != children.second; ++it) {
EntityWrapper child(entity.World, it->second);
cloneRecursive(child, clone);
}
return clone;
}
void EntityWrapper::childrenWithComponentRecursive(const std::string& componentType, EntityWrapper& entity, std::vector<EntityWrapper>& childrenWithComponent)
{
auto itPair = this->World->GetDirectChildren(entity.ID);
if (itPair.first == itPair.second) {
return;
}
for (auto it = itPair.first; it != itPair.second; ++it) {
EntityWrapper child = EntityWrapper(entity.World, it->second);
if (child.HasComponent(componentType)) {
childrenWithComponent.push_back(child);
}
childrenWithComponentRecursive(componentType, child, childrenWithComponent);
}
}