Can free instanced game elements from within the game

This commit is contained in:
Dane Johnson 2021-01-27 17:34:03 -06:00
parent a51c3d04b2
commit 21c540ef69
4 changed files with 85 additions and 5 deletions

View File

@ -24,6 +24,13 @@
#include "Node.h" #include "Node.h"
#include "Util.h" #include "Util.h"
NodeList::NodeList() {
isPrefabList = true;
}
NodeList::NodeList(bool isPrefabList) {
this->isPrefabList = isPrefabList;
}
void NodeList::Append(Node *node) { void NodeList::Append(Node *node) {
if (this->isPrefabList and not node->isPrefab) { if (this->isPrefabList and not node->isPrefab) {
Util::Die("Attempt to add instanced node to prefab list!"); Util::Die("Attempt to add instanced node to prefab list!");
@ -34,10 +41,22 @@ void NodeList::Append(Node *node) {
push_back(node); push_back(node);
} }
void NodeList::Remove(Node *node) {
remove(node);
}
bool NodeList::IsPrefabList() { bool NodeList::IsPrefabList() {
return isPrefabList; return isPrefabList;
} }
void NodeList::FreeList() {
for(Node *node : *this) {
node->children.FreeList();
delete node;
}
clear();
}
Name Node::GetType() const {return "Node";} Name Node::GetType() const {return "Node";}
bool Node::IsPrefab() { bool Node::IsPrefab() {
@ -49,9 +68,26 @@ NodeList Node::GetChildren() {
} }
void Node::AddChild(Node *child) { void Node::AddChild(Node *child) {
child->parent = this;
children.Append(child); children.Append(child);
} }
Node *Node::GetParent() {
return parent;
}
void Node::QueueFree() {
parent->children.Remove(this);
freeList->Append(this);
}
void Node::DoFree() {
if (this != root) {
Util::Die("Tried to call DoFree from non-root node");
}
freeList->FreeList();
}
Node *Node::GetRoot() { Node *Node::GetRoot() {
return root; return root;
} }
@ -79,4 +115,5 @@ Node* Node::Instance() {
return instance; return instance;
} }
NodeList *Node::freeList = new NodeList(false);
Node *Node::root = {Node().Instance()}; Node *Node::root = {Node().Instance()};

View File

@ -25,7 +25,7 @@
#ifndef NODE_H #ifndef NODE_H
#define NODE_H #define NODE_H
#include <vector> #include <list>
#include "types.h" #include "types.h"
@ -34,22 +34,33 @@ class Node; // Forwards declare
A list of nodes, tagged as either a list of prefabs A list of nodes, tagged as either a list of prefabs
or a list of instanced nodes. or a list of instanced nodes.
*/ */
class NodeList : public std::vector<Node*> { class NodeList : public std::list<Node*> {
public: public:
NodeList();
NodeList(bool isPrefabList);
/** /**
Add a node to this list, will check if it is a prefab Add a node to this list, will check if it is a prefab
or an instance. or an instance.
@param node The node to add @param node The node to add
*/ */
void Append(Node *node); void Append(Node *node);
/**
Remove a node from this list
@param node The node to remove
*/
void Remove(Node *node);
/** /**
Whether or not this is a list of prefabs Whether or not this is a list of prefabs
@returns true if this is a prefab list, @returns true if this is a prefab list,
false if it is an instanced list. false if it is an instanced list.
*/ */
bool IsPrefabList(); bool IsPrefabList();
/**
Recursively frees all nodes in the list
*/
void FreeList();
private: private:
bool isPrefabList = true; bool isPrefabList;
friend class Node; friend class Node;
}; };
@ -78,6 +89,21 @@ public:
@param child The node to add @param child The node to add
*/ */
void AddChild(Node *child); void AddChild(Node *child);
/**
@return This node's parent;
*/
Node *GetParent();
/**
Remove this node and it's children from the tree
and queue their memory for freeing
*/
void QueueFree();
/**
Actually frees the memory
Should only be called from root
*/
void DoFree();
/** /**
Gets the root of the game scene tree Gets the root of the game scene tree
@ -108,7 +134,9 @@ public:
private: private:
NodeList children; NodeList children;
static NodeList *freeList;
static Node *root; static Node *root;
Node *parent;
bool isPrefab = true; bool isPrefab = true;
friend class NodeList; friend class NodeList;
}; };

View File

@ -121,7 +121,10 @@ int main() {
// Start rendering to texture; // Start rendering to texture;
screen.Enable(); screen.Enable();
// Call update function
lua->Update(delta); lua->Update(delta);
// Delete freed nodes
root->DoFree();
shader->Use(); shader->Use();
shader->UpdateProjection(projection); shader->UpdateProjection(projection);
@ -176,7 +179,7 @@ int main() {
delete screenShader; delete screenShader;
delete skyboxShader; delete skyboxShader;
delete flatShader() delete shader;
lua->Close(); lua->Close();
delete lua; delete lua;

View File

@ -5,6 +5,9 @@ local physics_ball
local character local character
local ball local ball
local camera local camera
local die_cube
local total = 0.0
local vx = 0.0 local vx = 0.0
local vy = 0.0 local vy = 0.0
@ -90,6 +93,9 @@ function init()
cube_prefab:AddChild(orbiter) cube_prefab:AddChild(orbiter)
cube = cube_prefab:Instance() cube = cube_prefab:Instance()
couch.Node.GetRoot():AddChild(cube) couch.Node.GetRoot():AddChild(cube)
die_cube = cube_prefab:Instance()
couch.Node.GetRoot():AddChild(die_cube)
die_cube:Translate(couch.Vector3(0.0, 0.0, 3.0))
local ball_prefab = couch.Mesh.FromFile("ball.obj") local ball_prefab = couch.Mesh.FromFile("ball.obj")
material = ball_prefab:GetMaterial(0) material = ball_prefab:GetMaterial(0)
@ -131,6 +137,7 @@ function init()
end end
function update(delta) function update(delta)
total = total + delta
local move_vec = couch.Vector3() local move_vec = couch.Vector3()
local camera_transform = camera:GetTransform() local camera_transform = camera:GetTransform()
move_vec = camera_transform.position + camera_transform:Forward() * delta * vz * SPEED move_vec = camera_transform.position + camera_transform:Forward() * delta * vz * SPEED
@ -152,12 +159,17 @@ function update(delta)
elseif loc.y < 2.0 then elseif loc.y < 2.0 then
ballvy = 1.0 ballvy = 1.0
end end
ball:Translate(couch.Vector3(ballvy * delta, 0.0, 0.0)) ball:Translate(couch.Vector3(0.0, ballvy * delta, 0.0))
cube:RotateY(2.0 * delta) cube:RotateY(2.0 * delta)
cube:RotateZ(1.0 * delta) cube:RotateZ(1.0 * delta)
character:ApplyForce(character_move_vec * 10.0) character:ApplyForce(character_move_vec * 10.0)
if total > 1.0 and die_cube then
die_cube:QueueFree()
die_cube = nil
end
end end
function action_dir(key, action, pos, neg, curr) function action_dir(key, action, pos, neg, curr)