using System.Collections.Generic; using Chernobyl.Event; namespace Chernobyl.Values { /// /// An that gets its value from another /// that may not always be present. /// public class SourceValue : BasicValue { /// /// Initializes a new instance of the class /// that uses null for the and /// for the /// . /// public SourceValue() : this(null) {} /// /// Initializes a new instance of the class /// that uses /// for the . /// /// The that acts as the /// source for or null if this source has not yet /// been provided. public SourceValue(IValue source) : this(source, EqualityComparer.Default) {} /// /// Initializes a new instance of the class. /// /// The that acts as the /// source for or null if this source has not yet /// been provided. /// The instance used to compare new and previous /// values of to determine if /// should be raised. public SourceValue(IValue source, IEqualityComparer comparer) : base(comparer) { Source = source; } /// /// The that acts as the source for this instance /// or null if this source has not yet been provided. /// public IValue Source { get { return _source; } set { if (_source != value) { IValue previousValue = _source; _source = value; // Don't call NotNeeded() here since we don't want to modify // any internal state when IsNeeded is true. if (previousValue != null && IsNeeded) previousValue.Provide -= OnSourceProvided; bool haveValue = _source != null; if (haveValue && IsNeeded) Needed(); IsReady = haveValue; } } } /// /// Invoked when is changed to true. /// Implementations of this method should invoke the base class method. /// protected override void Needed() { if(_source != null) _source.Provide += OnSourceProvided; base.Needed(); } /// /// Invoked when is changed to false. /// Implementations of this method should invoke the base class method. /// protected override void NotNeeded() { if (_source != null) _source.Provide -= OnSourceProvided; base.NotNeeded(); } /// /// The backing property or implementation to . This /// property should just set and get the value. The /// property handles setting of and /// and the raising of /// . /// protected override T BackingValue { get; set; } /// /// The previous value of . /// protected override T PreviousValue { get; set; } /// /// An event handler that invokes /// on this instance when invoked. This method is used to forward /// through this. /// /// The sender of the event. /// The instance /// containing the event data. void OnSourceProvided(object sender, ValueChangedEventArgs e) { if (ProvideHandler != null) ProvideHandler(this, e); } /// /// The backing field to . /// IValue _source; } }