Suppose I have the following 2 classes:
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
The problem is that I bypass the mutator if I cache the menu_item
property:
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")
While keeping both classes mutable, how would you ensure that Meal
always behaves as expected and updates its sprites when menu_item
is changed?
I would do that using custom signal, which I would emit from MenuItem
's member mutator and connect to a callback that updates the private Meal
's value.
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