Fix critical memory leaks, race conditions, and improve code quality
- Fix memory leaks in match3_gameplay.gd with proper queue_free() usage - Add comprehensive error handling and fallback mechanisms to SettingsManager - Resolve scene loading race conditions in GameManager with state protection - Remove problematic static variables from tile.gd, replace with instance-based approach - Consolidate duplicate debug menu classes into shared DebugMenuBase - Add input validation across all user input paths for security and stability
This commit is contained in:
@@ -25,11 +25,8 @@ var all_gem_textures = [
|
||||
preload("res://assets/sprites/gems/sg_19.png"), # 7 - Silver gem
|
||||
]
|
||||
|
||||
# Static variable to store the current gem pool for all tiles
|
||||
static var current_gem_pool = [0, 1, 2, 3, 4] # Start with first 5 gems
|
||||
|
||||
# Currently active gem types (indices into all_gem_textures)
|
||||
var active_gem_types = [] # Will be set from current_gem_pool
|
||||
var active_gem_types = [] # Will be set from TileManager
|
||||
|
||||
func _set_tile_type(value: int) -> void:
|
||||
tile_type = value
|
||||
@@ -54,65 +51,59 @@ func _scale_sprite_to_fit() -> void:
|
||||
sprite.scale = original_scale
|
||||
DebugManager.log_debug("Set original scale to %s for tile (%d,%d)" % [original_scale, grid_position.x, grid_position.y], "Match3")
|
||||
|
||||
# Gem pool management functions
|
||||
static func set_active_gem_pool(gem_indices: Array) -> void:
|
||||
# Update static gem pool for new tiles
|
||||
current_gem_pool = gem_indices.duplicate()
|
||||
func set_active_gem_types(gem_indices: Array) -> void:
|
||||
if not gem_indices or gem_indices.is_empty():
|
||||
DebugManager.log_error("Empty gem indices array provided", "Tile")
|
||||
return
|
||||
|
||||
# Update all existing tile instances to use new gem pool
|
||||
var scene_tree = Engine.get_main_loop() as SceneTree
|
||||
if scene_tree:
|
||||
var tiles = scene_tree.get_nodes_in_group("tiles")
|
||||
for tile in tiles:
|
||||
if tile.has_method("_update_active_gems"):
|
||||
tile._update_active_gems(gem_indices)
|
||||
|
||||
func _update_active_gems(gem_indices: Array) -> void:
|
||||
active_gem_types = gem_indices.duplicate()
|
||||
|
||||
# Validate all gem indices are within bounds
|
||||
for gem_index in active_gem_types:
|
||||
if gem_index < 0 or gem_index >= all_gem_textures.size():
|
||||
DebugManager.log_error("Invalid gem index: %d (valid range: 0-%d)" % [gem_index, all_gem_textures.size() - 1], "Tile")
|
||||
# Use default fallback
|
||||
active_gem_types = [0, 1, 2, 3, 4]
|
||||
break
|
||||
|
||||
# Re-validate current tile type
|
||||
if tile_type >= active_gem_types.size():
|
||||
# Generate a new random tile type within valid range
|
||||
tile_type = randi() % active_gem_types.size()
|
||||
|
||||
_set_tile_type(tile_type)
|
||||
|
||||
static func get_active_gem_count() -> int:
|
||||
# Get from any tile instance or default
|
||||
var scene_tree = Engine.get_main_loop() as SceneTree
|
||||
if scene_tree:
|
||||
var tiles = scene_tree.get_nodes_in_group("tiles")
|
||||
if tiles.size() > 0:
|
||||
return tiles[0].active_gem_types.size()
|
||||
return 5 # Default
|
||||
func get_active_gem_count() -> int:
|
||||
return active_gem_types.size()
|
||||
|
||||
static func add_gem_to_pool(gem_index: int) -> void:
|
||||
var scene_tree = Engine.get_main_loop() as SceneTree
|
||||
if scene_tree:
|
||||
var tiles = scene_tree.get_nodes_in_group("tiles")
|
||||
for tile in tiles:
|
||||
if tile.has_method("_add_gem_type"):
|
||||
tile._add_gem_type(gem_index)
|
||||
func add_gem_type(gem_index: int) -> bool:
|
||||
if gem_index < 0 or gem_index >= all_gem_textures.size():
|
||||
DebugManager.log_error("Invalid gem index: %d" % gem_index, "Tile")
|
||||
return false
|
||||
|
||||
func _add_gem_type(gem_index: int) -> void:
|
||||
if gem_index >= 0 and gem_index < all_gem_textures.size():
|
||||
if not active_gem_types.has(gem_index):
|
||||
active_gem_types.append(gem_index)
|
||||
if not active_gem_types.has(gem_index):
|
||||
active_gem_types.append(gem_index)
|
||||
return true
|
||||
|
||||
static func remove_gem_from_pool(gem_index: int) -> void:
|
||||
var scene_tree = Engine.get_main_loop() as SceneTree
|
||||
if scene_tree:
|
||||
var tiles = scene_tree.get_nodes_in_group("tiles")
|
||||
for tile in tiles:
|
||||
if tile.has_method("_remove_gem_type"):
|
||||
tile._remove_gem_type(gem_index)
|
||||
return false
|
||||
|
||||
func _remove_gem_type(gem_index: int) -> void:
|
||||
func remove_gem_type(gem_index: int) -> bool:
|
||||
var type_index = active_gem_types.find(gem_index)
|
||||
if type_index != -1 and active_gem_types.size() > 2: # Keep at least 2 gem types
|
||||
active_gem_types.erase(gem_index)
|
||||
# Update tiles that were using removed type
|
||||
if tile_type >= active_gem_types.size():
|
||||
tile_type = 0
|
||||
_set_tile_type(tile_type)
|
||||
if type_index == -1:
|
||||
return false
|
||||
|
||||
if active_gem_types.size() <= 2: # Keep at least 2 gem types
|
||||
DebugManager.log_warn("Cannot remove gem type - minimum 2 types required", "Tile")
|
||||
return false
|
||||
|
||||
active_gem_types.erase(gem_index)
|
||||
|
||||
# Update tile if it was using the removed type
|
||||
if tile_type >= active_gem_types.size():
|
||||
tile_type = 0
|
||||
_set_tile_type(tile_type)
|
||||
|
||||
return true
|
||||
|
||||
func _set_selected(value: bool) -> void:
|
||||
var old_value = is_selected
|
||||
@@ -184,8 +175,11 @@ func force_reset_visual_state() -> void:
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
add_to_group("tiles") # Add to group for gem pool management
|
||||
# Initialize with current static gem pool
|
||||
active_gem_types = current_gem_pool.duplicate()
|
||||
|
||||
# Initialize with default gem pool if not already set
|
||||
if active_gem_types.is_empty():
|
||||
active_gem_types = [0, 1, 2, 3, 4] # Default to first 5 gems
|
||||
|
||||
_set_tile_type(tile_type)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user