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;
}
}