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
12 changes: 6 additions & 6 deletions .github/workflows/nuget-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ jobs:
steps:
- name: 🗂️ Checkout the repository
uses: actions/checkout@main
with:
fetch-depth: 0

- name: 🔖 Get version from latest tag
- name: 🔖 Get version from release tag
id: version
run: |
latest=$(git describe --tags $(git rev-list --tags --max-count=1))
echo Current version: $latest
echo "version=$latest" >> $GITHUB_OUTPUT
# The release that triggered this run, not the newest tag in the repository.
tag="${{ github.event.release.tag_name }}"
version="${tag#v}"
echo Current version: $version
echo "version=$version" >> $GITHUB_OUTPUT

- name: ⬇️ Install .NET 10
uses: actions/setup-dotnet@v5
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ This library also has extension methods for scheduling. Every scheduling method

### Common options

Every timespan must be positive; zero or negative values throw an `ArgumentOutOfRangeException`.

All scheduling methods share three optional parameters:

**resetTimerOnConsecutiveTrue / resetTimerOnConsecutiveFalse (default `false`)**
Expand Down
4 changes: 2 additions & 2 deletions src/Reactive.Boolean/BlinkWhileTrueOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal sealed class BlinkWhileTrueOperator(
// Under CompleteAfterTimer only the current "true" phase is finished, so an "off" phase has nothing pending.
protected override bool HasPendingValue => TimerRunning && LastEmittedValue == true;

protected override void OnSourceValue(bool value)
protected override void OnSourceValue(bool value, bool? previous)
{
if (!value)
{
Expand All @@ -26,7 +26,7 @@ protected override void OnSourceValue(bool value)
return;
}

if (LastSourceValue != true || resetTimerOnConsecutiveTrue)
if (previous != true || resetTimerOnConsecutiveTrue)
{
Emit(true);
StartTimer();
Expand Down
30 changes: 23 additions & 7 deletions src/Reactive.Boolean/BooleanObservableExtensions.Operators.And.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,28 @@ public static IObservable<bool> And(
{
ArgumentNullException.ThrowIfNull(source);

var observables = source.ToArray();
if (observables.Any(o => o is null))
{
throw new ArgumentException("The collection contains a null observable.", nameof(source));
}
if (observables.Length == 0)
{
// CombineLatest over no sources never emits; the conjunction of nothing is vacuously true.
return Observable.Return(true);
}

if (operatorDistinctness == OperatorDistinctness.InputDistinctUntilChanged)
{
source = source.Select(o => o.DistinctUntilChanged());
observables = observables.Select(o => o.DistinctUntilChanged()).ToArray();
}
if (operatorDistinctness == OperatorDistinctness.OutputDistinctUntilChanged)
{
return source
return observables
.CombineLatest(values => values.All(v => v))
.DistinctUntilChanged();
}
return source.CombineLatest(values => values.All(v => v));
return observables.CombineLatest(values => values.All(v => v));
}

/// <summary>
Expand All @@ -86,8 +97,13 @@ public static IObservable<bool> And(
public static IObservable<bool> And(
this IObservable<bool> observable,
IEnumerable<IObservable<bool>> observables,
OperatorDistinctness operatorDistinctness = OperatorDistinctness.OutputDistinctUntilChanged) =>
new[] { observable }.Concat(observables).And(operatorDistinctness);
OperatorDistinctness operatorDistinctness = OperatorDistinctness.OutputDistinctUntilChanged)
{
ArgumentNullException.ThrowIfNull(observable);
ArgumentNullException.ThrowIfNull(observables);

return new[] { observable }.Concat(observables).And(operatorDistinctness);
}

/// <summary>
/// Returns an observable that combines the latest results of all observables using an AND operator.
Expand All @@ -97,7 +113,7 @@ public static IObservable<bool> And(
public static IObservable<bool> And(
this IObservable<bool> observable,
params IObservable<bool>[] observables) =>
new[] { observable }.Concat(observables).And();
observable.And(observables, OperatorDistinctness.OutputDistinctUntilChanged);

/// <summary>
/// Returns an observable that combines the latest results of all observables using an AND operator.
Expand Down Expand Up @@ -296,7 +312,7 @@ public static IObservable<bool> AndOp(
public static IObservable<bool> AndOp(
this IObservable<bool> observable,
params IObservable<bool>[] observables) =>
new[] { observable }.Concat(observables).And();
observable.And(observables);

/// <summary>
/// Returns an observable that combines the latest results of all observables using an AND operator.
Expand Down
32 changes: 24 additions & 8 deletions src/Reactive.Boolean/BooleanObservableExtensions.Operators.Or.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,28 @@ public static IObservable<bool> Or(
{
ArgumentNullException.ThrowIfNull(source);

var observables = source.ToArray();
if (observables.Any(o => o is null))
{
throw new ArgumentException("The collection contains a null observable.", nameof(source));
}
if (observables.Length == 0)
{
// CombineLatest over no sources never emits; the disjunction of nothing is vacuously false.
return Observable.Return(false);
}

if (operatorDistinctness == OperatorDistinctness.InputDistinctUntilChanged)
{
source = source.Select(o => o.DistinctUntilChanged());
observables = observables.Select(o => o.DistinctUntilChanged()).ToArray();
}
if (operatorDistinctness == OperatorDistinctness.OutputDistinctUntilChanged)
{
return source
return observables
.CombineLatest(values => values.Any(v => v))
.DistinctUntilChanged();
}
return source.CombineLatest(values => values.Any(v => v));
return observables.CombineLatest(values => values.Any(v => v));
}

/// <summary>
Expand All @@ -82,8 +93,13 @@ public static IObservable<bool> Or(
public static IObservable<bool> Or(
this IObservable<bool> observable,
IEnumerable<IObservable<bool>> observables,
OperatorDistinctness operatorDistinctness = OperatorDistinctness.OutputDistinctUntilChanged) =>
new[] { observable }.Concat(observables).Or(operatorDistinctness);
OperatorDistinctness operatorDistinctness = OperatorDistinctness.OutputDistinctUntilChanged)
{
ArgumentNullException.ThrowIfNull(observable);
ArgumentNullException.ThrowIfNull(observables);

return new[] { observable }.Concat(observables).Or(operatorDistinctness);
}

/// <summary>
/// Returns an observable that combines the latest results of two observables using an OR operator.
Expand All @@ -93,7 +109,7 @@ public static IObservable<bool> Or(
public static IObservable<bool> Or(
this IObservable<bool> observable,
params IObservable<bool>[] observables) =>
new[] { observable }.Concat(observables).Or();
observable.Or(observables, OperatorDistinctness.OutputDistinctUntilChanged);

/// <summary>
/// Returns an observable that combines the latest results of two observables using an OR operator.
Expand Down Expand Up @@ -210,7 +226,7 @@ public static IObservable<bool> Nor(
IObservable<bool> observable2,
IObservable<bool> observable3,
OperatorDistinctness operatorDistinctness) =>
new[] { observable1, observable2, observable3 }.Or(operatorDistinctness);
observable1.Or(observable2, observable3, operatorDistinctness).Not();

/// <summary>
/// Returns an observable that combines the latest results of two observables using an NOR operator.
Expand All @@ -231,6 +247,6 @@ public static IObservable<bool> Nor(
IObservable<bool> observable3,
IObservable<bool> observable4,
OperatorDistinctness operatorDistinctness) =>
new[] { observable1, observable2, observable3, observable4 }.Or(operatorDistinctness);
observable1.Or(observable2, observable3, observable4, operatorDistinctness).Not();
}
}
Loading