Skip to content

Commit

Permalink
Merge branch 'decouple-reactive-data'
Browse files Browse the repository at this point in the history
  • Loading branch information
grofit committed May 26, 2021
2 parents d476ad2 + d18d204 commit 6785e4d
Show file tree
Hide file tree
Showing 19 changed files with 875 additions and 29 deletions.
1 change: 1 addition & 0 deletions src/EcsRx.Examples/EcsRx.Examples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<PackageReference Include="LazyData.Numerics" Version="3.0.17" />
<PackageReference Include="Ninject" Version="3.3.4" />
<PackageReference Include="Persistity.Endpoints.Http" Version="1.1.30" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EcsRx.Infrastructure.Ninject\EcsRx.Infrastructure.Ninject.csproj" />
Expand Down
9 changes: 9 additions & 0 deletions src/EcsRx.MicroRx/Disposables/ICancelable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;

namespace EcsRx.MicroRx.Disposables
{
public interface ICancelable : IDisposable
{
bool IsDisposed { get; }
}
}
62 changes: 62 additions & 0 deletions src/EcsRx.MicroRx/Disposables/SingleAssignmentDisposable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;

namespace EcsRx.MicroRx.Disposables
{
public class SingleAssignmentDisposable : IDisposable, ICancelable
{
readonly object gate = new object();
IDisposable current;
bool disposed;

public bool IsDisposed { get { lock (gate) { return disposed; } } }

public IDisposable Disposable
{
get
{
return current;
}
set
{
var old = default(IDisposable);
bool alreadyDisposed;
lock (gate)
{
alreadyDisposed = disposed;
old = current;
if (!alreadyDisposed)
{
if (value == null) return;
current = value;
}
}

if (alreadyDisposed && value != null)
{
value.Dispose();
return;
}

if (old != null) throw new InvalidOperationException("Disposable is already set");
}
}


public void Dispose()
{
IDisposable old = null;

lock (gate)
{
if (!disposed)
{
disposed = true;
old = current;
current = null;
}
}

if (old != null) old.Dispose();
}
}
}
21 changes: 21 additions & 0 deletions src/EcsRx.MicroRx/Operators/Empty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using EcsRx.MicroRx.Disposables;

namespace EcsRx.MicroRx.Operators
{
public class ImmutableEmptyObservable<T> : IObservable<T>
{
public static ImmutableEmptyObservable<T> Instance = new ImmutableEmptyObservable<T>();

ImmutableEmptyObservable()
{

}

public IDisposable Subscribe(IObserver<T> observer)
{
observer.OnCompleted();
return Disposable.Empty;
}
}
}
29 changes: 29 additions & 0 deletions src/EcsRx.MicroRx/Operators/ObservableBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using EcsRx.MicroRx.Disposables;

namespace EcsRx.MicroRx.Operators
{
public abstract class OperatorObservableBase<T> : IObservable<T>
{
readonly bool isRequiredSubscribeOnCurrentThread;

public OperatorObservableBase(bool isRequiredSubscribeOnCurrentThread)
{
this.isRequiredSubscribeOnCurrentThread = isRequiredSubscribeOnCurrentThread;
}

public bool IsRequiredSubscribeOnCurrentThread()
{
return isRequiredSubscribeOnCurrentThread;
}

public IDisposable Subscribe(IObserver<T> observer)
{
var subscription = new SingleAssignmentDisposable();
subscription.Disposable = SubscribeCore(observer, subscription);
return subscription;
}

protected abstract IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel);
}
}
41 changes: 41 additions & 0 deletions src/EcsRx.MicroRx/Unit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;

namespace EcsRx.MicroRx
{
[Serializable]
public struct Unit : IEquatable<Unit>
{
static readonly Unit @default = new Unit();

public static Unit Default { get { return @default; } }

public static bool operator ==(Unit first, Unit second)
{
return true;
}

public static bool operator !=(Unit first, Unit second)
{
return false;
}

public bool Equals(Unit other)
{
return true;
}
public override bool Equals(object obj)
{
return obj is Unit;
}

public override int GetHashCode()
{
return 0;
}

public override string ToString()
{
return "()";
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Reactive;
using EcsRx.MicroRx;

namespace EcsRx.ReactiveData.Collections
{
Expand Down
25 changes: 11 additions & 14 deletions src/EcsRx.ReactiveData/Collections/ReactiveCollection.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using EcsRx.MicroRx;
using EcsRx.MicroRx.Operators;
using EcsRx.MicroRx.Subjects;

/*
* This code was taken from UniRx project by neuecc
Expand Down Expand Up @@ -93,56 +93,53 @@ protected override void SetItem(int index, T item)
Subject<int> countChanged = null;
public IObservable<int> ObserveCountChanged(bool notifyCurrentCount = false)
{
if (isDisposed) return Observable.Empty<int>();
if (isDisposed) return ImmutableEmptyObservable<int>.Instance;

var subject = countChanged ?? (countChanged = new Subject<int>());
if (notifyCurrentCount)
{
return subject.StartWith(Count);
}
else
{
return subject;
subject.OnNext(Count);
}
return subject;
}

[NonSerialized]
Subject<Unit> collectionReset = null;
public IObservable<Unit> ObserveReset()
{
if (isDisposed) return Observable.Empty<Unit>();
if (isDisposed) return ImmutableEmptyObservable<Unit>.Instance;
return collectionReset ?? (collectionReset = new Subject<Unit>());
}

[NonSerialized]
Subject<CollectionAddEvent<T>> collectionAdd = null;
public IObservable<CollectionAddEvent<T>> ObserveAdd()
{
if (isDisposed) return Observable.Empty<CollectionAddEvent<T>>();
if (isDisposed) return ImmutableEmptyObservable<CollectionAddEvent<T>>.Instance;
return collectionAdd ?? (collectionAdd = new Subject<CollectionAddEvent<T>>());
}

[NonSerialized]
Subject<CollectionMoveEvent<T>> collectionMove = null;
public IObservable<CollectionMoveEvent<T>> ObserveMove()
{
if (isDisposed) return Observable.Empty<CollectionMoveEvent<T>>();
if (isDisposed) return ImmutableEmptyObservable<CollectionMoveEvent<T>>.Instance;
return collectionMove ?? (collectionMove = new Subject<CollectionMoveEvent<T>>());
}

[NonSerialized]
Subject<CollectionRemoveEvent<T>> collectionRemove = null;
public IObservable<CollectionRemoveEvent<T>> ObserveRemove()
{
if (isDisposed) return Observable.Empty<CollectionRemoveEvent<T>>();
if (isDisposed) return ImmutableEmptyObservable<CollectionRemoveEvent<T>>.Instance;
return collectionRemove ?? (collectionRemove = new Subject<CollectionRemoveEvent<T>>());
}

[NonSerialized]
Subject<CollectionReplaceEvent<T>> collectionReplace = null;
public IObservable<CollectionReplaceEvent<T>> ObserveReplace()
{
if (isDisposed) return Observable.Empty<CollectionReplaceEvent<T>>();
if (isDisposed) return ImmutableEmptyObservable<CollectionReplaceEvent<T>>.Instance;
return collectionReplace ?? (collectionReplace = new Subject<CollectionReplaceEvent<T>>());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Reactive;
using EcsRx.MicroRx;

namespace EcsRx.ReactiveData.Dictionaries
{
Expand Down
16 changes: 8 additions & 8 deletions src/EcsRx.ReactiveData/Dictionaries/ReactiveDictionary.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using EcsRx.MicroRx;
using EcsRx.MicroRx.Operators;
using EcsRx.MicroRx.Subjects;

/*
* This code was taken from UniRx project by neuecc
Expand Down Expand Up @@ -159,39 +159,39 @@ public void Dispose()
Subject<int> countChanged = null;
public IObservable<int> ObserveCountChanged()
{
if (isDisposed) return Observable.Empty<int>();
if (isDisposed) return ImmutableEmptyObservable<int>.Instance;
return countChanged ?? (countChanged = new Subject<int>());
}

[NonSerialized]
Subject<Unit> collectionReset = null;
public IObservable<Unit> ObserveReset()
{
if (isDisposed) return Observable.Empty<Unit>();
if (isDisposed) return ImmutableEmptyObservable<Unit>.Instance;
return collectionReset ?? (collectionReset = new Subject<Unit>());
}

[NonSerialized]
Subject<DictionaryAddEvent<TKey, TValue>> dictionaryAdd = null;
public IObservable<DictionaryAddEvent<TKey, TValue>> ObserveAdd()
{
if (isDisposed) return Observable.Empty<DictionaryAddEvent<TKey, TValue>>();
if (isDisposed) return ImmutableEmptyObservable<DictionaryAddEvent<TKey, TValue>>.Instance;
return dictionaryAdd ?? (dictionaryAdd = new Subject<DictionaryAddEvent<TKey, TValue>>());
}

[NonSerialized]
Subject<DictionaryRemoveEvent<TKey, TValue>> dictionaryRemove = null;
public IObservable<DictionaryRemoveEvent<TKey, TValue>> ObserveRemove()
{
if (isDisposed) return Observable.Empty<DictionaryRemoveEvent<TKey, TValue>>();
if (isDisposed) return ImmutableEmptyObservable<DictionaryRemoveEvent<TKey, TValue>>.Instance;
return dictionaryRemove ?? (dictionaryRemove = new Subject<DictionaryRemoveEvent<TKey, TValue>>());
}

[NonSerialized]
Subject<DictionaryReplaceEvent<TKey, TValue>> dictionaryReplace = null;
public IObservable<DictionaryReplaceEvent<TKey, TValue>> ObserveReplace()
{
if (isDisposed) return Observable.Empty<DictionaryReplaceEvent<TKey, TValue>>();
if (isDisposed) return ImmutableEmptyObservable<DictionaryReplaceEvent<TKey, TValue>>.Instance;
return dictionaryReplace ?? (dictionaryReplace = new Subject<DictionaryReplaceEvent<TKey, TValue>>());
}

Expand Down
5 changes: 2 additions & 3 deletions src/EcsRx.ReactiveData/EcsRx.ReactiveData.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@
<Description>Reactive data objects for extending the dotnet reactive library, unirx provides this out of the box</Description>
<PackageTags>ecs rx reactive patterns ioc game-development xna monogame unity</PackageTags>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Reactive.Core" Version="4.1.0" />
<PackageReference Include="System.Reactive.Linq" Version="4.1.0" />
<ProjectReference Include="..\EcsRx.MicroRx\EcsRx.MicroRx.csproj" />
</ItemGroup>

</Project>
27 changes: 27 additions & 0 deletions src/EcsRx.ReactiveData/Extensions/IObservableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;

namespace EcsRx.ReactiveData.Extensions
{
public static class IObservableExtensions
{
public static IReactiveProperty<T> ToReactiveProperty<T>(this IObservable<T> source)
{
return new ReactiveProperty<T>(source);
}

public static IReactiveProperty<T> ToReactiveProperty<T>(this IObservable<T> source, T initialValue)
{
return new ReactiveProperty<T>(source, initialValue);
}

public static IReadOnlyReactiveProperty<T> ToReadOnlyReactiveProperty<T>(this IObservable<T> source)
{
return new ReactiveProperty<T>(source);
}

public static IReadOnlyReactiveProperty<T> ToReadOnlyReactiveProperty<T>(this IObservable<T> source, T initialValue)
{
return new ReactiveProperty<T>(source, initialValue);
}
}
}
4 changes: 2 additions & 2 deletions src/EcsRx.ReactiveData/ReactiveProperty.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using EcsRx.MicroRx.Disposables;
using EcsRx.MicroRx.Subjects;

/*
* This code was taken from UniRx project by neuecc
Expand Down
1 change: 1 addition & 0 deletions src/EcsRx.Tests/EcsRx.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<ProjectReference Include="..\EcsRx.Plugins.GroupBinding\EcsRx.Plugins.GroupBinding.csproj" />
<ProjectReference Include="..\EcsRx.Plugins.ReactiveSystems\EcsRx.Plugins.ReactiveSystems.csproj" />
<ProjectReference Include="..\EcsRx.Plugins.Views\EcsRx.Plugins.Views.csproj" />
<ProjectReference Include="..\EcsRx.ReactiveData\EcsRx.ReactiveData.csproj" />
<ProjectReference Include="..\EcsRx\EcsRx.csproj">
<Project>{5F5B6094-C56A-47E9-A835-127D0FFBF4C6}</Project>
<Name>EcsRx</Name>
Expand Down
Loading

0 comments on commit 6785e4d

Please sign in to comment.