Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 20 additions & 27 deletions src/ReactiveUI/ReactiveObject/ReactiveObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,27 @@ namespace ReactiveUI;
[DataContract]
public class ReactiveObject : IReactiveNotifyPropertyChanged<IReactiveObject>, IHandleObservableErrors, IReactiveObject
{
private readonly Lazy<IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>>> _changing;
private readonly Lazy<IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>>> _changed;
private readonly Lazy<Unit> _propertyChangingEventsSubscribed;
private readonly Lazy<Unit> _propertyChangedEventsSubscribed;
private readonly Lazy<IObservable<Exception>> _thrownExceptions;
private bool _propertyChangingEventsSubscribed;
private bool _propertyChangedEventsSubscribed;

/// <summary>
/// Initializes a new instance of the <see cref="ReactiveObject"/> class.
/// </summary>
public ReactiveObject()
{
_changing = new Lazy<IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>>>(() => ((IReactiveObject)this).GetChangingObservable(), LazyThreadSafetyMode.PublicationOnly);
_changed = new Lazy<IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>>>(() => ((IReactiveObject)this).GetChangedObservable(), LazyThreadSafetyMode.PublicationOnly);
_propertyChangingEventsSubscribed = new Lazy<Unit>(
() =>
{
this.SubscribePropertyChangingEvents();
return Unit.Default;
},
LazyThreadSafetyMode.PublicationOnly);
_propertyChangedEventsSubscribed = new Lazy<Unit>(
() =>
{
this.SubscribePropertyChangedEvents();
return Unit.Default;
},
LazyThreadSafetyMode.PublicationOnly);
_thrownExceptions = new Lazy<IObservable<Exception>>(this.GetThrownExceptionsObservable, LazyThreadSafetyMode.PublicationOnly);
}

/// <inheritdoc/>
public event PropertyChangingEventHandler? PropertyChanging
{
add
{
_ = _propertyChangingEventsSubscribed.Value;
if (!_propertyChangingEventsSubscribed)
{
this.SubscribePropertyChangingEvents();
_propertyChangingEventsSubscribed = true;
}

PropertyChangingHandler += value;
}
remove => PropertyChangingHandler -= value;
Expand All @@ -59,7 +44,12 @@ public event PropertyChangedEventHandler? PropertyChanged
{
add
{
_ = _propertyChangedEventsSubscribed.Value;
if (!_propertyChangedEventsSubscribed)
{
this.SubscribePropertyChangedEvents();
_propertyChangedEventsSubscribed = true;
}

PropertyChangedHandler += value;
}
remove => PropertyChangedHandler -= value;
Expand All @@ -78,7 +68,8 @@ public event PropertyChangedEventHandler? PropertyChanged
[Browsable(false)]
[Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)]
#endif
public IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>> Changing => _changing.Value;
public IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>> Changing =>
Volatile.Read(ref field) ?? Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangingObservable(), null) ?? field;

/// <inheritdoc />
[IgnoreDataMember]
Expand All @@ -87,7 +78,8 @@ public event PropertyChangedEventHandler? PropertyChanged
[Browsable(false)]
[Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)]
#endif
public IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>> Changed => _changed.Value;
public IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>> Changed =>
Volatile.Read(ref field) ?? Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangedObservable(), null) ?? field;

/// <inheritdoc/>
[IgnoreDataMember]
Expand All @@ -96,7 +88,8 @@ public event PropertyChangedEventHandler? PropertyChanged
[Browsable(false)]
[Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)]
#endif
public IObservable<Exception> ThrownExceptions => _thrownExceptions.Value;
public IObservable<Exception> ThrownExceptions =>
Volatile.Read(ref field) ?? Interlocked.CompareExchange(ref field, this.GetThrownExceptionsObservable(), null) ?? field;

/// <inheritdoc/>
void IReactiveObject.RaisePropertyChanging(PropertyChangingEventArgs args) =>
Expand Down
44 changes: 17 additions & 27 deletions src/ReactiveUI/ReactiveObject/ReactiveRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@ namespace ReactiveUI;
[DataContract]
public record ReactiveRecord : IReactiveNotifyPropertyChanged<IReactiveObject>, IHandleObservableErrors, IReactiveObject
{
private readonly Lazy<IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>>> _changing;
private readonly Lazy<IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>>> _changed;
private readonly Lazy<Unit> _propertyChangingEventsSubscribed;
private readonly Lazy<Unit> _propertyChangedEventsSubscribed;
private readonly Lazy<IObservable<Exception>> _thrownExceptions;
private bool _propertyChangingEventsSubscribed;
private bool _propertyChangedEventsSubscribed;

/// <summary>
/// Initializes a new instance of the <see cref="ReactiveRecord"/> class.
Expand All @@ -28,31 +25,19 @@ public record ReactiveRecord : IReactiveNotifyPropertyChanged<IReactiveObject>,
#endif
public ReactiveRecord()
{
_changing = new Lazy<IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>>>(() => ((IReactiveObject)this).GetChangingObservable(), LazyThreadSafetyMode.PublicationOnly);
_changed = new Lazy<IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>>>(() => ((IReactiveObject)this).GetChangedObservable(), LazyThreadSafetyMode.PublicationOnly);
_propertyChangingEventsSubscribed = new Lazy<Unit>(
() =>
{
this.SubscribePropertyChangingEvents();
return Unit.Default;
},
LazyThreadSafetyMode.PublicationOnly);
_propertyChangedEventsSubscribed = new Lazy<Unit>(
() =>
{
this.SubscribePropertyChangedEvents();
return Unit.Default;
},
LazyThreadSafetyMode.PublicationOnly);
_thrownExceptions = new Lazy<IObservable<Exception>>(this.GetThrownExceptionsObservable, LazyThreadSafetyMode.PublicationOnly);
}

/// <inheritdoc/>
public event PropertyChangingEventHandler? PropertyChanging
{
add
{
_ = _propertyChangingEventsSubscribed.Value;
if (!_propertyChangingEventsSubscribed)
{
this.SubscribePropertyChangingEvents();
_propertyChangingEventsSubscribed = true;
}

PropertyChangingHandler += value;
}
remove => PropertyChangingHandler -= value;
Expand All @@ -63,7 +48,12 @@ public event PropertyChangedEventHandler? PropertyChanged
{
add
{
_ = _propertyChangedEventsSubscribed.Value;
if (!_propertyChangedEventsSubscribed)
{
this.SubscribePropertyChangedEvents();
_propertyChangedEventsSubscribed = true;
}

PropertyChangedHandler += value;
}
remove => PropertyChangedHandler -= value;
Expand All @@ -83,7 +73,7 @@ public event PropertyChangedEventHandler? PropertyChanged
[Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)]
#endif
public IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>> Changing => // TODO: Create Test
_changing.Value;
Volatile.Read(ref field) ?? Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangingObservable(), null) ?? field;

/// <inheritdoc />
[IgnoreDataMember]
Expand All @@ -93,7 +83,7 @@ public event PropertyChangedEventHandler? PropertyChanged
[Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)]
#endif
public IObservable<IReactivePropertyChangedEventArgs<IReactiveObject>> Changed => // TODO: Create Test
_changed.Value;
Volatile.Read(ref field) ?? Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangedObservable(), null) ?? field;

/// <inheritdoc/>
[IgnoreDataMember]
Expand All @@ -102,7 +92,7 @@ public event PropertyChangedEventHandler? PropertyChanged
[Browsable(false)]
[Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)]
#endif
public IObservable<Exception> ThrownExceptions => _thrownExceptions.Value;
public IObservable<Exception> ThrownExceptions => Volatile.Read(ref field) ?? Interlocked.CompareExchange(ref field, this.GetThrownExceptionsObservable(), null) ?? field;

/// <inheritdoc/>
void IReactiveObject.RaisePropertyChanging(PropertyChangingEventArgs args) => PropertyChangingHandler?.Invoke(this, args);
Expand Down
Loading