This PR brings automatic trait dependencies injection with cyclic dependency detection
Using this Healthable trait : it depends on a Killable and a Loggable. When assigning this trait to an object, if it is already killable or loggable, those traits are automatically injected to the Healthable instance. Else, they are automatically instantiated (recursively!) and saved into the receiver for futur usage.
This simplify trait usage, and guarantee that an object owns one and only one instance of each trait.
# @trait
class_name Healthable
extends RefCounted
var max_health:int = 100
var health:int = max_health:
set(value):
var old_health:int = health
health = clamp(value, 0, max_health)
if old_health != health:
_loggable.log("HP : %s/%s" % [health, max_health])
if value <= 0:
_killable.kill()
# Reference to the Loggable, needed for this trait to print messages
var _loggable:Loggable
# Reference to the Killable, needed for this trait to handle death !
var _killable:Killable
# Automatically requires that the trait receiver is also a Killable and a Loggable object
# If the receiver does not have those traits yet, they will be automatically instantiated and
# registered into the receiver for future usages.
func _init(killable:Killable, loggable:Loggable) -> void:
_killable = killable
_loggable = loggable
This PR brings automatic trait dependencies injection with cyclic dependency detection
Using this
Healthable
trait : it depends on aKillable
and aLoggable
. When assigning this trait to an object, if it is already killable or loggable, those traits are automatically injected to theHealthable
instance. Else, they are automatically instantiated (recursively!) and saved into the receiver for futur usage.This simplify trait usage, and guarantee that an object owns one and only one instance of each trait.
Cyclic dependency error/detection: