Index: Core/Common/src/Core.Common.Base/Core.Common.Base.csproj
===================================================================
diff -u -r0dbf681489bfe1d279eef99030f9ee13abebbb23 -r07b0e83704b56684d617cd6e8b8570417654912a
--- Core/Common/src/Core.Common.Base/Core.Common.Base.csproj (.../Core.Common.Base.csproj) (revision 0dbf681489bfe1d279eef99030f9ee13abebbb23)
+++ Core/Common/src/Core.Common.Base/Core.Common.Base.csproj (.../Core.Common.Base.csproj) (revision 07b0e83704b56684d617cd6e8b8570417654912a)
@@ -98,6 +98,7 @@
+
Index: Core/Common/src/Core.Common.Base/Observer.cs
===================================================================
diff -u -r0dbf681489bfe1d279eef99030f9ee13abebbb23 -r07b0e83704b56684d617cd6e8b8570417654912a
--- Core/Common/src/Core.Common.Base/Observer.cs (.../Observer.cs) (revision 0dbf681489bfe1d279eef99030f9ee13abebbb23)
+++ Core/Common/src/Core.Common.Base/Observer.cs (.../Observer.cs) (revision 07b0e83704b56684d617cd6e8b8570417654912a)
@@ -24,7 +24,7 @@
namespace Core.Common.Base
{
///
- /// Class that implements the pattern.
+ /// Class that implements in a way that a single can be observed.
///
///
/// The being observed by instances of this class can be dynamically changed.
@@ -75,10 +75,7 @@
public void Dispose()
{
- if (observable != null)
- {
- observable.Detach(this);
- }
+ Observable = null;
}
}
}
\ No newline at end of file
Index: Core/Common/src/Core.Common.Base/RecursiveObserver.cs
===================================================================
diff -u
--- Core/Common/src/Core.Common.Base/RecursiveObserver.cs (revision 0)
+++ Core/Common/src/Core.Common.Base/RecursiveObserver.cs (revision 07b0e83704b56684d617cd6e8b8570417654912a)
@@ -0,0 +1,119 @@
+// Copyright (C) Stichting Deltares 2016. All rights reserved.
+//
+// This file is part of Ringtoets.
+//
+// Ringtoets is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+
+namespace Core.Common.Base
+{
+ ///
+ /// Class that implements in a way that a hierarchy of objects can be observed recursively.
+ ///
+ ///
+ /// The root being observed by instances of this class can be dynamically changed.
+ ///
+ /// The type of objects to observe recursively.
+ public class RecursiveObserver : IObserver, IDisposable where T : class, IObservable
+ {
+ private T rootObservable;
+ private readonly Action updateObserverAction;
+ private readonly Func> getChildObservables;
+ private readonly IList observedObjects = new List();
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ /// The action to perform on notifications coming from one of the items of the hierarchy of observed objects.
+ /// The method used for recursively obtaining the objects to observe.
+ public RecursiveObserver(Action updateObserverAction, Func> getChildObservables)
+ {
+ this.updateObserverAction = updateObserverAction;
+ this.getChildObservables = getChildObservables;
+ }
+
+ ///
+ /// Gets or sets the root object to observe.
+ ///
+ public T Observable
+ {
+ get
+ {
+ return rootObservable;
+ }
+ set
+ {
+ rootObservable = value;
+
+ UpdateObservedObjects();
+ }
+ }
+
+ public void UpdateObserver()
+ {
+ updateObserverAction();
+
+ // Update the list of observed objects as observables might have been added/removed
+ UpdateObservedObjects();
+ }
+
+ private void UpdateObservedObjects()
+ {
+ // Detach from the currently observed objects
+ foreach (var observedObject in observedObjects)
+ {
+ observedObject.Detach(this);
+ }
+
+ // Clear the list of observed objects
+ observedObjects.Clear();
+
+ // If relevant, start observing objects again
+ if (rootObservable != null)
+ {
+ foreach (var objectToObserve in GetObservablesRecursive(rootObservable))
+ {
+ objectToObserve.Attach(this);
+ observedObjects.Add(objectToObserve);
+ }
+ }
+ }
+
+ private IEnumerable GetObservablesRecursive(T observable)
+ {
+ var observables = new List
+ {
+ observable
+ };
+
+ foreach (var childObservable in getChildObservables(observable))
+ {
+ observables.AddRange(GetObservablesRecursive(childObservable));
+ }
+
+ return observables;
+ }
+
+ public void Dispose()
+ {
+ Observable = null;
+ }
+ }
+}
Index: Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj
===================================================================
diff -u -r0dbf681489bfe1d279eef99030f9ee13abebbb23 -r07b0e83704b56684d617cd6e8b8570417654912a
--- Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj (.../Core.Common.Base.Test.csproj) (revision 0dbf681489bfe1d279eef99030f9ee13abebbb23)
+++ Core/Common/test/Core.Common.Base.Test/Core.Common.Base.Test.csproj (.../Core.Common.Base.Test.csproj) (revision 07b0e83704b56684d617cd6e8b8570417654912a)
@@ -93,6 +93,7 @@
+
Index: Core/Common/test/Core.Common.Base.Test/ObserverTest.cs
===================================================================
diff -u -r0dbf681489bfe1d279eef99030f9ee13abebbb23 -r07b0e83704b56684d617cd6e8b8570417654912a
--- Core/Common/test/Core.Common.Base.Test/ObserverTest.cs (.../ObserverTest.cs) (revision 0dbf681489bfe1d279eef99030f9ee13abebbb23)
+++ Core/Common/test/Core.Common.Base.Test/ObserverTest.cs (.../ObserverTest.cs) (revision 07b0e83704b56684d617cd6e8b8570417654912a)
@@ -29,12 +29,19 @@
[Test]
public void DefaultConstructor_DefaultValues()
{
+ // Setup
+ var counter = 0;
+
// Call
- var observer = new Observer(() => { });
+ var observer = new Observer(() => { counter++; });
// Assert
Assert.IsInstanceOf(observer);
Assert.IsNull(observer.Observable);
+ Assert.AreEqual(0, counter);
+
+ observer.UpdateObserver();
+ Assert.AreEqual(1, counter);
}
[Test]
Index: Core/Common/test/Core.Common.Base.Test/RecursiveObserverTest.cs
===================================================================
diff -u
--- Core/Common/test/Core.Common.Base.Test/RecursiveObserverTest.cs (revision 0)
+++ Core/Common/test/Core.Common.Base.Test/RecursiveObserverTest.cs (revision 07b0e83704b56684d617cd6e8b8570417654912a)
@@ -0,0 +1,169 @@
+// Copyright (C) Stichting Deltares 2016. All rights reserved.
+//
+// This file is part of Ringtoets.
+//
+// Ringtoets is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System.Collections.Generic;
+using NUnit.Framework;
+
+namespace Core.Common.Base.Test
+{
+ [TestFixture]
+ public class RecursiveObserverTest
+ {
+ [Test]
+ public void DefaultConstructor_DefaultValues()
+ {
+ // Setup
+ var counter = 0;
+
+ // Call
+ var recursiveObserver = new RecursiveObserver(() => { counter++; }, GetChildObservables);
+
+ // Assert
+ Assert.IsInstanceOf(recursiveObserver);
+ Assert.IsNull(recursiveObserver.Observable);
+ Assert.AreEqual(0, counter);
+
+ recursiveObserver.UpdateObserver();
+ Assert.AreEqual(1, counter);
+ }
+
+ [TestCase(0)]
+ [TestCase(1)]
+ [TestCase(2)]
+ [TestCase(100)]
+ public void RecursiveObserver_WithObservableHierarchy_NotifyObserversAtSpecifiedLevelResultsInPerformingUpdateObserversAction(int nestingLevel)
+ {
+ // Setup
+ var counter = 0;
+ var rootObservable = new TestObservable();
+
+ var currentNestedObservable = rootObservable;
+
+ for (var i = 0; i < nestingLevel; i++)
+ {
+ var newObservable = new TestObservable();
+
+ currentNestedObservable.ChildTestObservables.Add(newObservable);
+
+ currentNestedObservable = newObservable;
+ }
+
+ var recursiveObserver = new RecursiveObserver(() => counter++, GetChildObservables)
+ {
+ Observable = rootObservable
+ };
+
+ // Call
+ currentNestedObservable.NotifyObservers();
+
+ // Assert
+ Assert.AreEqual(1, counter);
+ }
+
+ [TestCase(0)]
+ [TestCase(1)]
+ [TestCase(2)]
+ [TestCase(100)]
+ public void RecursiveObserver_WithObservableHierarchySetAndThenUnset_NotifyObserversNoLongerResultsInPerformingUpdateObserversAction(int nestingLevel)
+ {
+ // Setup
+ var counter = 0;
+ var rootObservable = new TestObservable();
+
+ var currentNestedObservable = rootObservable;
+
+ for (var i = 0; i < nestingLevel; i++)
+ {
+ var newObservable = new TestObservable();
+
+ currentNestedObservable.ChildTestObservables.Add(newObservable);
+
+ currentNestedObservable = newObservable;
+ }
+
+ var recursiveObserver = new RecursiveObserver(() => counter++, GetChildObservables)
+ {
+ Observable = rootObservable
+ };
+
+ recursiveObserver.Observable = null;
+
+ // Call
+ currentNestedObservable.NotifyObservers();
+
+ // Assert
+ Assert.AreEqual(0, counter);
+ }
+
+ [TestCase(0)]
+ [TestCase(1)]
+ [TestCase(2)]
+ [TestCase(100)]
+ public void RecursiveObserver_WithObservableHierarchySetAndThenDisposed_NotifyObserversNoLongerResultsInPerformingUpdateObserversAction(int nestingLevel)
+ {
+ // Setup
+ var counter = 0;
+ var rootObservable = new TestObservable();
+
+ var currentNestedObservable = rootObservable;
+
+ for (var i = 0; i < nestingLevel; i++)
+ {
+ var newObservable = new TestObservable();
+
+ currentNestedObservable.ChildTestObservables.Add(newObservable);
+
+ currentNestedObservable = newObservable;
+ }
+
+ var recursiveObserver = new RecursiveObserver(() => counter++, GetChildObservables)
+ {
+ Observable = rootObservable
+ };
+
+ recursiveObserver.Dispose();
+
+ // Call
+ currentNestedObservable.NotifyObservers();
+
+ // Assert
+ Assert.AreEqual(0, counter);
+ }
+
+ private class TestObservable : Observable
+ {
+ private readonly IList childTestObservables = new List();
+
+ public IList ChildTestObservables
+ {
+ get
+ {
+ return childTestObservables;
+ }
+ }
+ }
+
+ private IEnumerable GetChildObservables(TestObservable testObservable)
+ {
+ return testObservable.ChildTestObservables;
+ }
+ }
+}
Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingCalculationsView.cs
===================================================================
diff -u -r0dbf681489bfe1d279eef99030f9ee13abebbb23 -r07b0e83704b56684d617cd6e8b8570417654912a
--- Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingCalculationsView.cs (.../PipingCalculationsView.cs) (revision 0dbf681489bfe1d279eef99030f9ee13abebbb23)
+++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingCalculationsView.cs (.../PipingCalculationsView.cs) (revision 07b0e83704b56684d617cd6e8b8570417654912a)
@@ -19,7 +19,6 @@
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
-using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
@@ -228,78 +227,6 @@
#region Nested types
- private class RecursiveObserver : IObserver where T : IObservable
- {
- private T observable;
- private readonly Action updateObserverAction;
- private readonly Func> getChildObservables;
- private readonly IList observedObjects = new List();
-
- public RecursiveObserver(Action updateObserverAction, Func> getChildObservables)
- {
- this.updateObserverAction = updateObserverAction;
- this.getChildObservables = getChildObservables;
- }
-
- public T Observable
- {
- get
- {
- return observable;
- }
- set
- {
- observable = value;
-
- UpdateObservedObjects();
- }
- }
-
- public void UpdateObserver()
- {
- updateObserverAction();
-
- UpdateObservedObjects();
- }
-
- private void UpdateObservedObjects()
- {
- // Detach from the currently attached observable items
- foreach (var observedObject in observedObjects)
- {
- observedObject.Detach(this);
- }
-
- // Clear the list
- observedObjects.Clear();
-
- // If relevant, start observing objects again
- if (observable != null)
- {
- foreach (var objectToObserve in GetObservablesRecursive(observable))
- {
- objectToObserve.Attach(this);
- observedObjects.Add(objectToObserve);
- }
- }
- }
-
- private IEnumerable GetObservablesRecursive(T parentObservable)
- {
- var observables = new List
- {
- parentObservable
- };
-
- foreach (var childObservable in getChildObservables(parentObservable))
- {
- observables.AddRange(GetObservablesRecursive(childObservable));
- }
-
- return observables;
- }
- }
-
private class PipingCalculationRow
{
private readonly PipingCalculation pipingCalculation;