diff --git a/components/behaviour/object_pool/object_pool.gd b/components/behaviour/object_pool/object_pool.gd new file mode 100644 index 0000000..68732a6 --- /dev/null +++ b/components/behaviour/object_pool/object_pool.gd @@ -0,0 +1,92 @@ +@icon("res://components/behaviour/object_pool/object_pool.svg") +class_name ObjectPool extends Node + +signal killed(spawned_object: Variant) + +@export var scene: PackedScene +@export var create_objects_on_ready: bool = true +@export var max_objects_in_pool: int = 100: + set(value): + if value != max_objects_in_pool: + max_objects_in_pool = maxi(1, absi(value)) +@export var process_mode_on_spawn: ProcessMode = Node.PROCESS_MODE_INHERIT + +var pool: Array[Variant] = [] +var spawned: Array[Variant] = [] + + +func _init( + _scene: PackedScene, + amount: int, + create_on_ready: bool = true, + _process_mode_on_spawn: ProcessMode = Node.PROCESS_MODE_INHERIT +) -> void: + scene = _scene + max_objects_in_pool = amount + create_objects_on_ready = create_on_ready + process_mode_on_spawn = _process_mode_on_spawn + + +func _ready() -> void: + if create_objects_on_ready: + create_pool(max_objects_in_pool) + + killed.connect(on_killed) + + +func create_pool(amount: int) -> void: + if scene == null: + push_error("ObjectPool: The scene to spawn is not defined for this object pool") + return + + amount = mini(amount, max_objects_in_pool - pool.size()) + + for i in amount: + add_to_pool(scene.instantiate()) + + +func add_to_pool(new_object: Variant) -> void: + if pool.has(new_object): + return + + new_object.process_mode = Node.PROCESS_MODE_DISABLED + new_object.hide() + pool.append(new_object) + + +func kill(spawned_object) -> void: + if spawned.has(spawned_object): + spawned.erase(spawned_object) + add_to_pool(spawned_object) + + +func spawn() -> Variant: + if pool.size() > 0: + var pool_object: Variant = pool.pop_back() + pool_object.process_mode = process_mode_on_spawn + pool_object.show() + spawned.append(pool_object) + + return pool_object + + return null + + +func spawn_multiple(amount: int) -> Array[Variant]: + amount = mini(amount, pool.size()) + + var spawned_objects: Array[Variant] = [] + + for i in amount: + var spawned_object: Variant = spawn() + + if spawned_object == null: + break + + spawned_objects.append(spawned_object) + + return spawned_objects + + +func on_killed(spawned_object: Variant) -> void: + kill(spawned_object) diff --git a/components/behaviour/object_pool/object_pool.svg b/components/behaviour/object_pool/object_pool.svg new file mode 100644 index 0000000..758dd0b --- /dev/null +++ b/components/behaviour/object_pool/object_pool.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/components/behaviour/object_pool/object_pool.svg.import b/components/behaviour/object_pool/object_pool.svg.import new file mode 100644 index 0000000..e6d2e3b --- /dev/null +++ b/components/behaviour/object_pool/object_pool.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b4ukqec1un17f" +path="res://.godot/imported/object_pool.svg-9cb4c9becd7d7a8ff4067b1122248dd8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://components/behaviour/object_pool/object_pool.svg" +dest_files=["res://.godot/imported/object_pool.svg-9cb4c9becd7d7a8ff4067b1122248dd8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/utilities/viewport/texture_helper.gd b/utilities/viewport/texture_helper.gd index e21cf62..faaf2cb 100644 --- a/utilities/viewport/texture_helper.gd +++ b/utilities/viewport/texture_helper.gd @@ -1,11 +1,11 @@ class_name TextureHelper -func get_texture_dimensions(texture: Texture2D) -> Rect2i: +static func get_texture_dimensions(texture: Texture2D) -> Rect2i: return texture.get_image().get_used_rect() -func get_texture_rect_dimensions(texture_rect: TextureRect) -> Vector2: +static func get_texture_rect_dimensions(texture_rect: TextureRect) -> Vector2: var texture: Texture2D = texture_rect.texture var used_rect: Rect2i = get_texture_dimensions(texture) var texture_dimensions: Vector2 = Vector2(used_rect.size) * texture_rect.scale @@ -13,7 +13,7 @@ func get_texture_rect_dimensions(texture_rect: TextureRect) -> Vector2: return texture_dimensions -func get_sprite_dimensions(sprite: Sprite2D) -> Vector2: +static func get_sprite_dimensions(sprite: Sprite2D) -> Vector2: var texture: Texture2D = sprite.texture var used_rect: Rect2i = get_texture_dimensions(texture) var sprite_dimensions: Vector2 = Vector2(used_rect.size) * sprite.scale