Skip to content

Instantly share code, notes, and snippets.

@HungryProton
Last active May 5, 2020 11:58
Show Gist options
  • Save HungryProton/fcca29c10b912ba1139d901b80eb63ec to your computer and use it in GitHub Desktop.
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.
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