Last active
May 5, 2020 11:58
-
-
Save HungryProton/fcca29c10b912ba1139d901b80eb63ec to your computer and use it in GitHub Desktop.
A simple node pool that works with an arbitrary amount of different node types.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tool | |
extends Node | |
class_name NodePool | |
var _pools := {} | |
func _exit_tree() -> void: | |
clear() | |
""" | |
Search in the node pools for a node that's not already used. If no nodes are found, create one | |
with the proper type and store in in the pool. | |
The 'type' variable is a GDScripNativeClass object, which means you can call this method like this | |
get_or_create(Position3D) | |
And it will take care of calling new() only if necessary. | |
""" | |
func get_or_create(type: GDScriptNativeClass) -> Node: | |
var node | |
if _pools.has(type): | |
var available_nodes: Array = _pools[type]["free"] | |
if available_nodes.size() == 0: | |
node = type.new() | |
_pools[type]["used"].append(node) | |
else: | |
node = available_nodes.pop_front() | |
_pools[type]["used"].append(node) | |
else: | |
node = type.new() | |
_pools[type] = { | |
"free": [], | |
"used": [node] | |
} | |
return node | |
""" | |
Once you don't need the node anymore, call this method to release it. Next time get_or_create will | |
be called with the matching type, it will reuse that node instead of creating a new one. | |
I can't find a way to convert a Node to a GDScriptNativeClass object so for now, manually specify | |
the node type when calling this method. | |
var node = pool.get_or_create(Position3D) # Or any other type | |
pool.release_node(Position3D, node) | |
""" | |
func release_node(type: GDScriptNativeClass, node: Node) -> void: | |
# TODO find a way to convert Node to GDScriptNativeClass | |
if not _pools.has(type): | |
return | |
var used = _pools[type]["used"] | |
var index = used.find(node) | |
if index == -1: | |
return | |
node = used[index] | |
used.remove(index) | |
# TODO : Reset all node properties first | |
_pools[type]["free"].append(node) | |
""" | |
Loop through the dictionary and free every object that doesn't have a parent. If an object is in | |
the scene tree, it will no longer be managed by the pool node. | |
""" | |
func clear() -> void: | |
for key in _pools.keys(): | |
for key2 in _pools[key].keys(): | |
var p = _pools[key][key2] | |
while p.size() > 0: | |
var node = p.pop_front() | |
if not node.get_parent(): | |
node.queue_free() | |
_pools = {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment