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 "Util.h"
NodeList::NodeList() {
isPrefabList = true;
}
NodeList::NodeList(bool isPrefabList) {
this->isPrefabList = isPrefabList;
}
void NodeList::Append(Node *node) {
if (this->isPrefabList and not node->isPrefab) {
Util::Die("Attempt to add instanced node to prefab list!");
@ -34,10 +41,22 @@ void NodeList::Append(Node *node) {
push_back(node);
}
void NodeList::Remove(Node *node) {
remove(node);
}
bool NodeList::IsPrefabList() {
return isPrefabList;
}
void NodeList::FreeList() {
for(Node *node : *this) {
node->children.FreeList();
delete node;
}
clear();
}
Name Node::GetType() const {return "Node";}
bool Node::IsPrefab() {
@ -49,9 +68,26 @@ NodeList Node::GetChildren() {
}
void Node::AddChild(Node *child) {
child->parent = this;
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() {
return root;
}
@ -79,4 +115,5 @@ Node* Node::Instance() {
return instance;
}
NodeList *Node::freeList = new NodeList(false);
Node *Node::root = {Node().Instance()};

View File

@ -25,7 +25,7 @@
#ifndef NODE_H
#define NODE_H
#include <vector>
#include <list>
#include "types.h"
@ -34,22 +34,33 @@ class Node; // Forwards declare
A list of nodes, tagged as either a list of prefabs
or a list of instanced nodes.
*/
class NodeList : public std::vector<Node*> {
class NodeList : public std::list<Node*> {
public:
NodeList();
NodeList(bool isPrefabList);
/**
Add a node to this list, will check if it is a prefab
or an instance.
@param node The node to add
*/
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
@returns true if this is a prefab list,
false if it is an instanced list.
*/
bool IsPrefabList();
/**
Recursively frees all nodes in the list
*/
void FreeList();
private:
bool isPrefabList = true;
bool isPrefabList;
friend class Node;
};
@ -78,6 +89,21 @@ public:
@param child The node to add
*/
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
@ -108,7 +134,9 @@ public:
private:
NodeList children;
static NodeList *freeList;
static Node *root;
Node *parent;
bool isPrefab = true;
friend class NodeList;
};

View File

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

View File

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