55using System ;
66using System . Collections . Generic ;
77using System . ComponentModel ;
8+ using System . Diagnostics . CodeAnalysis ;
89using System . Linq ;
910using System . Reactive . Disposables ;
1011using System . Reactive . Linq ;
@@ -22,11 +23,8 @@ namespace ReactiveMarbles.Core
2223 /// </summary>
2324 public class RxObject : IRxObject
2425 {
25- private readonly SourceList < RxPropertyChangedEventArgs < IRxObject > > _propertyChangedEvents = new ( ) ;
26- private readonly SourceList < RxPropertyChangingEventArgs < IRxObject > > _propertyChangingEvents = new ( ) ;
2726 private readonly Lazy < Subject < Exception > > _thrownExceptions = new ( ( ) => new Subject < Exception > ( ) , LazyThreadSafetyMode . PublicationOnly ) ;
28- private long _changeNotificationsDelayed ;
29- private long _changeNotificationsSuppressed ;
27+ private readonly Lazy < Notifications > _notification = new ( ( ) => new Notifications ( ) ) ;
3028
3129 /// <summary>
3230 /// Initializes a new instance of the <see cref="RxObject"/> class.
@@ -68,39 +66,39 @@ void Handler(object sender, PropertyChangingEventArgs args) =>
6866 public IObservable < RxPropertyChangedEventArgs < IRxObject > > Changed { get ; }
6967
7068 /// <inheritdoc/>
71- public bool AreChangeNotificationsEnabled ( ) => Interlocked . Read ( ref _changeNotificationsSuppressed ) == 0 ;
69+ public bool AreChangeNotificationsEnabled ( ) => ! _notification . IsValueCreated || Interlocked . Read ( ref _notification . Value . ChangeNotificationsSuppressed ) == 0 ;
7270
7371 /// <inheritdoc/>
74- public bool AreChangeNotificationsDelayed ( ) => Interlocked . Read ( ref _changeNotificationsDelayed ) > 0 ;
72+ public bool AreChangeNotificationsDelayed ( ) => _notification . IsValueCreated && Interlocked . Read ( ref _notification . Value . ChangeNotificationsDelayed ) > 0 ;
7573
7674 /// <inheritdoc/>
7775 public IDisposable SuppressChangeNotifications ( )
7876 {
79- Interlocked . Increment ( ref _changeNotificationsSuppressed ) ;
80- return Disposable . Create ( ( ) => Interlocked . Decrement ( ref _changeNotificationsSuppressed ) ) ;
77+ Interlocked . Increment ( ref _notification . Value . ChangeNotificationsSuppressed ) ;
78+ return Disposable . Create ( ( ) => Interlocked . Decrement ( ref _notification . Value . ChangeNotificationsSuppressed ) ) ;
8179 }
8280
8381 /// <inheritdoc/>
8482 public IDisposable DelayChangeNotifications ( )
8583 {
86- Interlocked . Increment ( ref _changeNotificationsDelayed ) ;
84+ Interlocked . Increment ( ref _notification . Value . ChangeNotificationsDelayed ) ;
8785
8886 return Disposable . Create ( ( ) =>
8987 {
90- if ( Interlocked . Decrement ( ref _changeNotificationsDelayed ) == 0 )
88+ if ( Interlocked . Decrement ( ref _notification . Value . ChangeNotificationsDelayed ) == 0 )
9189 {
92- foreach ( var distinctEvent in DistinctEvents ( _propertyChangingEvents . Items . ToList ( ) ) )
90+ foreach ( var distinctEvent in DistinctEvents ( _notification . Value . PropertyChangingEvents . Items . ToList ( ) ) )
9391 {
9492 PropertyChanging ? . Invoke ( this , new PropertyChangingEventArgs ( distinctEvent . PropertyName ) ) ;
9593 }
9694
97- foreach ( var distinctEvent in DistinctEvents ( _propertyChangedEvents . Items . ToList ( ) ) )
95+ foreach ( var distinctEvent in DistinctEvents ( _notification . Value . PropertyChangedEvents . Items . ToList ( ) ) )
9896 {
9997 PropertyChanged ? . Invoke ( this , new PropertyChangedEventArgs ( distinctEvent . PropertyName ) ) ;
10098 }
10199
102- _propertyChangedEvents . Clear ( ) ;
103- _propertyChangingEvents . Clear ( ) ;
100+ _notification . Value . PropertyChangingEvents . Clear ( ) ;
101+ _notification . Value . PropertyChangedEvents . Clear ( ) ;
104102 }
105103 } ) ;
106104 }
@@ -118,7 +116,7 @@ protected void RaisePropertyChanging(PropertyChangingEventArgs args)
118116
119117 if ( AreChangeNotificationsDelayed ( ) )
120118 {
121- _propertyChangingEvents . Add ( new RxPropertyChangingEventArgs < IRxObject > ( args . PropertyName , this ) ) ;
119+ _notification . Value . PropertyChangingEvents . Add ( new RxPropertyChangingEventArgs < IRxObject > ( args . PropertyName , this ) ) ;
122120 return ;
123121 }
124122
@@ -148,7 +146,7 @@ protected void RaisePropertyChanged(PropertyChangedEventArgs args)
148146
149147 if ( AreChangeNotificationsDelayed ( ) )
150148 {
151- _propertyChangedEvents . Add ( new RxPropertyChangedEventArgs < IRxObject > ( args . PropertyName , this ) ) ;
149+ _notification . Value . PropertyChangedEvents . Add ( new RxPropertyChangedEventArgs < IRxObject > ( args . PropertyName , this ) ) ;
152150 return ;
153151 }
154152
@@ -234,5 +232,14 @@ private static IEnumerable<TEventArgs> DistinctEvents<TEventArgs>(IList<TEventAr
234232 // Stack enumerates in LIFO order
235233 return uniqueEvents ;
236234 }
235+
236+ [ SuppressMessage ( "StyleCop" , "SA1401" , Justification = "Deliberate use of private field" ) ]
237+ private class Notifications
238+ {
239+ public readonly SourceList < RxPropertyChangedEventArgs < IRxObject > > PropertyChangedEvents = new ( ) ;
240+ public readonly SourceList < RxPropertyChangingEventArgs < IRxObject > > PropertyChangingEvents = new ( ) ;
241+ public long ChangeNotificationsDelayed = 0 ;
242+ public long ChangeNotificationsSuppressed = 0 ;
243+ }
237244 }
238245}
0 commit comments