Implement EntityBase class (DataModel)

This commit is contained in:
2024-01-16 17:42:48 -05:00
parent a29455f482
commit 2578663907
3 changed files with 165 additions and 14 deletions

View File

@@ -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;

View File

@@ -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();

View File

@@ -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();
}