Implement EntityBase class (DataModel)
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <GL/gl.h>
|
||||
#include <rewindow/types/window.h>
|
||||
#include <engine/world.h>
|
||||
enum class GAMESTATE: uint8_t {
|
||||
NORMAL = 0, //Gameplay.
|
||||
IN_MAIN_MENU = 1,
|
||||
@@ -21,11 +21,10 @@ public:
|
||||
//uint16_t minimumTickDelta = 15625;
|
||||
//float tickDelta = NULL;
|
||||
bool fullscreen;
|
||||
World* world;
|
||||
bool debug = true;
|
||||
uint64_t tickCount = 0;
|
||||
uint64_t frameCount = 0;
|
||||
float frameDelta = 0;
|
||||
float frameDelta = NULL;
|
||||
GLenum glError = GL_NO_ERROR;
|
||||
float nearPlane = 0.01f;
|
||||
float farPlane = 100.0f;
|
||||
|
@@ -2,15 +2,65 @@
|
||||
|
||||
#include <types/entityList.h>
|
||||
#include <types/vertex.h>
|
||||
class World {
|
||||
|
||||
|
||||
class EntityBase
|
||||
{
|
||||
protected:
|
||||
EntityBase* parent;
|
||||
std::vector<EntityBase*> children;
|
||||
public:
|
||||
EntityBase()
|
||||
{
|
||||
children = std::vector<EntityBase*> ();
|
||||
}
|
||||
std::vector<EntityBase*> GetChildren();
|
||||
void SetParent(EntityBase* parent);
|
||||
bool IsDescendantOf(EntityBase* ancestor);
|
||||
bool IsAncestorOf(EntityBase* descendant);
|
||||
std::vector<EntityBase*> GetDescendants();
|
||||
std::vector<EntityBase*> GetAncestors();
|
||||
EntityBase* GetParent() const { return parent;}
|
||||
EntityBase* FindFirstChild(std::string search_name);
|
||||
EntityBase* GetFamilyTreeRoot() const;
|
||||
EntityBase *Add(EntityBase *newChild);
|
||||
|
||||
// TODO: Constrain to DerivedEntityType
|
||||
template <typename T>
|
||||
T* FindFirstChildOfType() const
|
||||
{
|
||||
for (auto& child : children) {
|
||||
T* p = dynamic_cast<T>(child);
|
||||
|
||||
if (p != nullptr)
|
||||
return p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DescendantAdded(EntityBase* ent);
|
||||
void DescendantRemoved(EntityBase* ent);
|
||||
};
|
||||
|
||||
class PhysicalEntity: Entity {};
|
||||
class Container : Entity {};
|
||||
class Folder : public Container {};
|
||||
class Model : public Container {};
|
||||
|
||||
class DataModel {
|
||||
public:
|
||||
std::vector<EntityBase*> objects;
|
||||
std::vector<EntityBase*> getEntityList();
|
||||
bool addEntity(EntityBase* ptr);
|
||||
[[nodiscard]] int getEntityCount() const;
|
||||
[[nodiscard]] int getMobyCount() const;
|
||||
};
|
||||
|
||||
class World : public DataModel {
|
||||
private:
|
||||
EntityList eList;
|
||||
VertexArray playerBaseGeometry;
|
||||
public:
|
||||
EntityList* entityList();
|
||||
std::string name;
|
||||
[[nodiscard]] static int getEntityCount();
|
||||
[[nodiscard]] static int getMobyCount();
|
||||
|
||||
//TODO: Store these more elegantly of course.
|
||||
VertexArray getPlayerBaseGeometry();
|
||||
|
@@ -2,17 +2,17 @@
|
||||
#include <engine/world.h>
|
||||
#include <types/moby.h>
|
||||
|
||||
EntityList* World::entityList() {
|
||||
return &eList;
|
||||
std::vector<EntityBase*> DataModel::getEntityList() {
|
||||
return this->objects;
|
||||
}
|
||||
|
||||
int World::getEntityCount() {
|
||||
return engine->world->eList.list.size();
|
||||
int DataModel::getEntityCount() const {
|
||||
return this->objects.size();
|
||||
}
|
||||
|
||||
int World::getMobyCount() {
|
||||
int DataModel::getMobyCount() const {
|
||||
int count;
|
||||
for (auto& e : engine->world->entityList()->list)
|
||||
for (auto& e : this->objects)
|
||||
if (auto* m = dynamic_cast<Moby*>(e))
|
||||
count++;
|
||||
return count;
|
||||
@@ -24,3 +24,105 @@ VertexArray World::getPlayerBaseGeometry() {
|
||||
playerBaseGeometry.load("assets/models/cone.obj");
|
||||
return playerBaseGeometry;
|
||||
}
|
||||
|
||||
void EntityBase::SetParent(EntityBase *parent) {
|
||||
// hold a reference to this so it doesn't get collected as we're working with it
|
||||
EntityBase *oldParent = this->parent;
|
||||
if (parent == oldParent)
|
||||
return;
|
||||
// Don't allow for an instance to be parented to itself
|
||||
if (this == parent)
|
||||
throw std::runtime_error("Cannot parent a widget to itself");
|
||||
if (this->IsAncestorOf(parent))
|
||||
throw std::runtime_error("Cannot create circular object reference");
|
||||
|
||||
for (EntityBase *ancestor: this->GetAncestors()) {
|
||||
if (oldParent && !ancestor->IsAncestorOf(parent) && parent != ancestor) {
|
||||
ancestor->DescendantRemoved(this);
|
||||
for (EntityBase *descendant: this->GetDescendants()) {
|
||||
ancestor->DescendantRemoved(descendant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove ourselves from our parent (if we have one)
|
||||
if (this->parent) {
|
||||
parent->children.erase(std::remove(parent->children.begin(), parent->children.end(), this),
|
||||
parent->children.end());
|
||||
}
|
||||
// Update our old parent to the new one
|
||||
this->parent = parent;
|
||||
// If our parent is set to nullptr, we can't update it's vector of children
|
||||
if (!parent) { return; }
|
||||
parent->children.emplace_back(this);
|
||||
for (EntityBase* ancestor: this->GetAncestors()) {
|
||||
if (!oldParent || !(oldParent->IsDescendantOf(parent) && oldParent != ancestor)) {
|
||||
ancestor->DescendantAdded(this);
|
||||
for (auto* descendant : this->GetDescendants()) {
|
||||
ancestor->DescendantAdded(descendant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityBase::IsDescendantOf(EntityBase *ancestor) {
|
||||
if (ancestor == nullptr)
|
||||
return false;
|
||||
EntityBase *instance = this;
|
||||
while (instance->GetParent()) {
|
||||
instance = instance->GetParent();
|
||||
if (instance == ancestor)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EntityBase::IsAncestorOf(EntityBase *descendant) {
|
||||
if (descendant == nullptr)
|
||||
return false;
|
||||
EntityBase *instance = descendant;
|
||||
while (instance->GetParent()) {
|
||||
instance = instance->GetParent();
|
||||
if (instance == this)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<EntityBase *> EntityBase::GetChildren() {
|
||||
return this->children;
|
||||
}
|
||||
|
||||
std::vector<EntityBase *> EntityBase::GetAncestors() {
|
||||
std::vector<EntityBase *> ancestors;
|
||||
for (EntityBase *ancestor = this->parent; ancestor; ancestor = ancestor->parent) {
|
||||
ancestors.push_back(ancestor);
|
||||
}
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
std::vector<EntityBase *> EntityBase::GetDescendants() {
|
||||
std::vector<EntityBase *> descendants;
|
||||
for (auto& child: this->children) {
|
||||
descendants.push_back(child);
|
||||
std::vector<EntityBase *> recursiveDescendants = child->GetDescendants();
|
||||
descendants.insert(descendants.end(), recursiveDescendants.begin(), recursiveDescendants.end());
|
||||
}
|
||||
return descendants;
|
||||
}
|
||||
|
||||
EntityBase *EntityBase::Add(EntityBase *newChild) {
|
||||
newChild->SetParent(this);
|
||||
return newChild;
|
||||
}
|
||||
|
||||
EntityBase *EntityBase::GetFamilyTreeRoot() const {
|
||||
|
||||
//if (JUI::Scene* scene = dynamic_cast<JUI::Scene*>(parent); scene != nullptr)
|
||||
|
||||
// This is retarded, Fix ASAP!
|
||||
auto parent = this->GetParent();
|
||||
if (parent->GetParent() == nullptr)
|
||||
return parent;
|
||||
return parent->GetFamilyTreeRoot();
|
||||
}
|
||||
|
Reference in New Issue
Block a user