Skip to content

Commit

Permalink
added simple observable implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Malachi Griffie committed May 5, 2017
1 parent 199bcb4 commit 9908733
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 3 deletions.
20 changes: 20 additions & 0 deletions src/nexus.core/IUpdatable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright Malachi Griffie
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

namespace nexus.core
{
/// <summary>
/// Indicates that the provided value can be updated with new data <typeparamref name="T" />
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IUpdatable<in T>
{
/// <summary>
/// Update this object with new data
/// </summary>
void Update( T value );
}
}
96 changes: 96 additions & 0 deletions src/nexus.core/Observable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright Malachi Griffie
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

using System;
using System.Collections.Generic;

namespace nexus.core
{
/// <summary>
/// Simple implementation of <see cref="IObservable{T}" />
/// </summary>
public class Observable<T>
: IObservable<T>,
IUpdatable<T>,
IDisposable
{
private readonly List<IObserver<T>> m_observers;

/// <summary>
/// </summary>
public Observable()
{
m_observers = new List<IObserver<T>>();
}

/// <summary>
/// <c>true</c> if this observable has been disposed and can no longer be used or a <see cref="ObjectDisposedException" />
/// will be thrown
/// </summary>
public Boolean IsDisposed { get; private set; }

/// <inheritdoc />
public virtual void Dispose()
{
if(IsDisposed)
{
return;
}

IsDisposed = true;
var observers = new List<IObserver<T>>( m_observers );
foreach(var observer in observers)
{
observer.OnCompleted();
}
m_observers.Clear();
}

/// <inheritdoc />
public virtual void Error( Exception ex )
{
ThrowIfDisposed();

var observers = new List<IObserver<T>>( m_observers );
foreach(var observer in observers)
{
observer.OnError( ex );
}
}

/// <inheritdoc />
public virtual IDisposable Subscribe( IObserver<T> observer )
{
ThrowIfDisposed();

m_observers.Add( observer );
return new DisposeAction( () => m_observers.Remove( observer ) );
}

/// <inheritdoc />
public virtual void Update( T value )
{
ThrowIfDisposed();

var observers = new List<IObserver<T>>( m_observers );
foreach(var observer in observers)
{
observer.OnNext( value );
}
}

/// <summary>
/// Throw <see cref="ObjectDisposedException" /> if <see cref="IsDisposed" /> is <c>true</c>
/// </summary>
protected void ThrowIfDisposed()
{
if(IsDisposed)
{
throw new ObjectDisposedException( "Cannot perform operations on disposed {0}".F( GetType().Name ) );
}
}
}
}
7 changes: 4 additions & 3 deletions src/nexus.core/Observer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ public static class Observer
/// <summary>
/// Create a new observer using the provided methods to implement <see cref="IObserver{T}" />
/// </summary>
public static IObserver<T> Create<T>( Action<T> onNext, Action onComplete = null, Action<Exception> onError = null )
public static IObserver<T> Create<T>( Action<T> onNext, Action onComplete = null,
Action<Exception> onError = null )
{
return new FunctionObserver<T>( onNext, onComplete, onError );
}

/// <summary>
/// Subscribe to this <paramref name="observable" /> using the provided methods to create a new <see cref="IObserver{T}" />
/// </summary>
public static IDisposable Subscribe<T>( this IObservable<T> observable, Action<T> onNext, Action onComplete = null,
Action<Exception> onError = null )
public static IDisposable Subscribe<T>( this IObservable<T> observable, Action<T> onNext,
Action onComplete = null, Action<Exception> onError = null )
{
Contract.Requires( observable != null );
return observable.Subscribe( Create( onNext, onComplete, onError ) );
Expand Down
2 changes: 2 additions & 0 deletions src/nexus.core/nexus.core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ActionAsync.cs" />
<Compile Include="IUpdatable.cs" />
<Compile Include="ObjectConverter.cs" />
<Compile Include="Observable.cs" />
<Compile Include="Properties\BaseAssemblyInfo.cs" />
<Compile Include="Bytes.cs" />
<Compile Include="ByteUtils.cs" />
Expand Down

0 comments on commit 9908733

Please sign in to comment.