干净的代码:在缓存可变实例时防止意外行为
Clean code: preventing unexpected behavior when caching mutable instances
假设我有以下 2 类:
extends Resource
class_name MenuItem
export var food: Texture = preload("Burger.png")
export var drink: Texture = preload("Soda.png")
extends Node
class_name Meal
# "Public" variable
var menu_item: MenuItem setget _set_menu_item
# "Private" variables
onready var _food: Sprite = $Food
onready var _drink: Sprite = $Drink
func _set_menu_item(value: MenuItem) -> void:
menu_item = value
_food.texture = menu_item.food
_drink.texture = menu_item.drink
问题是,如果我缓存 menu_item
属性:
,我会绕过修改器
extends Node
onready var meal: Meal = $Meal
onready var menu_item: MenuItem = meal.menu_item
func _ready() -> void:
# Will trigger `_set_menu_item` and update `_food.texture`
meal.menu_item.food = load("Salad.png")
# Won't trigger `_set_menu_item` and won't update `_food.texture`
menu_item.food = load("Soup.png")
在保持 类 可变的同时, 你如何确保 Meal
始终按预期运行并在 menu_item
时更新其精灵改变了吗?
我会使用自定义信号来做到这一点,我会从 MenuItem
的成员修改器发出并连接到更新私有 Meal
值的回调。
extends Resource
class_name MenuItem
# I use floating point "weight" instead of your Texture variables "food" and "drink"
# But everything should be same for Textures
export var weight: float = 0.0 setget _set_weight
signal weight_changed
func _set_weight(value: float) -> void:
if weight != value:
weight = value
emit_signal("weight_changed")
extends Node
class_name Meal
# "Public" variable
var menu_item: MenuItem = MenuItem.new()
# "Private" variables
var _weigth: float = 0.0
func _ready():
menu_item.connect("weight_changed", self, "_set_weight")
func _set_weight():
_weigth = menu_item.weight
extends Node
onready var meal: Meal = $Meal
onready var menu_item: MenuItem = meal.menu_item
func _ready():
# Will trigger `_set_weight` and update `_weight`
meal.menu_item.weight = 2.0
# Will do that also
menu_item.weight = -2.0
假设我有以下 2 类:
extends Resource
class_name MenuItem
export var food: Texture = preload("Burger.png")
export var drink: Texture = preload("Soda.png")
extends Node
class_name Meal
# "Public" variable
var menu_item: MenuItem setget _set_menu_item
# "Private" variables
onready var _food: Sprite = $Food
onready var _drink: Sprite = $Drink
func _set_menu_item(value: MenuItem) -> void:
menu_item = value
_food.texture = menu_item.food
_drink.texture = menu_item.drink
问题是,如果我缓存 menu_item
属性:
extends Node
onready var meal: Meal = $Meal
onready var menu_item: MenuItem = meal.menu_item
func _ready() -> void:
# Will trigger `_set_menu_item` and update `_food.texture`
meal.menu_item.food = load("Salad.png")
# Won't trigger `_set_menu_item` and won't update `_food.texture`
menu_item.food = load("Soup.png")
在保持 类 可变的同时, 你如何确保 Meal
始终按预期运行并在 menu_item
时更新其精灵改变了吗?
我会使用自定义信号来做到这一点,我会从 MenuItem
的成员修改器发出并连接到更新私有 Meal
值的回调。
extends Resource
class_name MenuItem
# I use floating point "weight" instead of your Texture variables "food" and "drink"
# But everything should be same for Textures
export var weight: float = 0.0 setget _set_weight
signal weight_changed
func _set_weight(value: float) -> void:
if weight != value:
weight = value
emit_signal("weight_changed")
extends Node
class_name Meal
# "Public" variable
var menu_item: MenuItem = MenuItem.new()
# "Private" variables
var _weigth: float = 0.0
func _ready():
menu_item.connect("weight_changed", self, "_set_weight")
func _set_weight():
_weigth = menu_item.weight
extends Node
onready var meal: Meal = $Meal
onready var menu_item: MenuItem = meal.menu_item
func _ready():
# Will trigger `_set_weight` and update `_weight`
meal.menu_item.weight = 2.0
# Will do that also
menu_item.weight = -2.0