Skip to content

Commit

Permalink
Change TMessage constraint from class to notnull
Browse files Browse the repository at this point in the history
  • Loading branch information
experiarms1 committed Feb 15, 2024
1 parent a6f0938 commit 6fb953f
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 33 deletions.
21 changes: 7 additions & 14 deletions docs/BasicConcept.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,6 @@ The default message type is string if unspecified, such as in ```Store<TState>``
## Usage

Define the message type.
You can't define message as value type (enum, struct, int, double etc...)
because the message type must be class or record.
Wrap value types with reference types like record if you need.

```cs

Expand All @@ -169,15 +166,13 @@ public enum StateChangedType {
Increment
}

public record StateChangedTypeMessage(StateChangedType StateChangedType);

```

The message type is specified in Store Type params in the following way.

```Store<AsyncCounterState, StateChangedTypeMessage>```
```Store<AsyncCounterState, StateChangedType>```

If you set message as the second argument of ```Mutate(..., new(StateChangedType.Increment))```, you can get the message from the StateHasChangedEventArgs.
If you set message as the second argument of ```Mutate(..., StateChangedType.Increment)```, you can get the message from the StateHasChangedEventArgs.

```cs

Expand All @@ -204,17 +199,15 @@ public enum StateChangedType {
Increment
}

public record StateChangedMessage(StateChangedType StateChangedType);

public class CounterStore() : Store<CounterStoreState, StateChangedMessage>(() => new()) {
public class CounterStore() : Store<CounterStoreState, StateChangedType>(() => new()) {

public async Task CountUpAsync() {
Mutate(state => state with { IsLoading = true }, new(StateChangedType.BeginLoading));
Mutate(state => state with { IsLoading = true }, StateChangedType.BeginLoading);

await Task.Delay(500);

Mutate(HandleIncrement, new(StateChangedType.Increment));
Mutate(state => state with { IsLoading = false }, new(StateChangedType.EndLoading));
Mutate(HandleIncrement, StateChangedType.Increment);
Mutate(state => state with { IsLoading = false }, StateChangedType.EndLoading);
}

private static CounterStoreState HandleIncrement(CounterStoreState state) {
Expand All @@ -229,7 +222,7 @@ public class CounterStore() : Store<CounterStoreState, StateChangedMessage>(() =
Mutate(state => state with {
Count = num,
History = state.History.Add(num),
}, new(StateChangedType.SetCount));
}, StateChangedType.SetCount);
}
}

Expand Down
16 changes: 7 additions & 9 deletions samples/Memento.Sample.Blazor/Stores/AsyncCounterStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,42 @@ public enum StateChangedType {
CountUpWithAmount
}

public record Message(StateChangedType StateChangedType);

public class AsyncCounterStore() : Store<AsyncCounterState, Message>(() => new()) {
public class AsyncCounterStore() : Store<AsyncCounterState, StateChangedType>(() => new()) {
public void CountUp() {
Mutate(state => state with {
Count = state.Count + 1,
IsLoading = false,
Histories = [.. state.Histories, state.Count + 1],
}, new(StateChangedType.CountUp));
}, StateChangedType.CountUp);
}

public async Task CountUpAsync() {
Mutate(state => state with { IsLoading = true, }, new(StateChangedType.Loading));
Mutate(state => state with { IsLoading = true, }, StateChangedType.Loading);
await Task.Delay(800);
Mutate(state => state with {
Count = state.Count + 1,
IsLoading = false,
Histories = [.. state.Histories, state.Count + 1],
}, new(StateChangedType.CountUp));
}, StateChangedType.CountUp);
}

public void CountUpManyTimes(int count) {
for (var i = 0; i < count; i++) {
Mutate(state => state with {
Count = state.Count + 1,
}, new(StateChangedType.CountUpAsync));
}, StateChangedType.CountUpAsync);
}
}

public void SetCount(int count) {
Mutate(state => state with {
Count = count,
}, new(StateChangedType.SetCount));
}, StateChangedType.SetCount);
}

public void CountUpWithAmount(int amount) {
Mutate(state => state with {
Count = state.Count + amount,
}, new(StateChangedType.CountUpWithAmount));
}, StateChangedType.CountUpWithAmount);
}
}
2 changes: 1 addition & 1 deletion src/Memento.Core/AbstractStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Reducer<TState, TMessage> reducer
IStore<TState, TMessage>,
IDisposable
where TState : class
where TMessage : class {
where TMessage : notnull {
readonly Reducer<TState, TMessage> _reducer = (state, command) => reducer(state, command);
readonly ConcurrentBag<IDisposable> _disposables = [];

Expand Down
2 changes: 1 addition & 1 deletion src/Memento.Core/IStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Memento.Core;
public interface IStore<out TState, out TMessage>
: IObservable<IStateChangedEventArgs<TState, TMessage>>, IDisposable
where TState : class
where TMessage : class {
where TMessage : notnull {
/// <summary>
/// Gets the current state of the store.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Memento.Core/Internals/StoreSubscription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ public void Dispose() {
/// <exception cref="InvalidOperationException">Thrown if the object is collected without being disposed</exception>
~StoreSubscription() {
if (!_isDisposed && _wasCreated)
throw new InvalidOperationException($"{nameof(StoreSubscription)} with _id \"{_id}\" was not disposed. ");
throw new InvalidOperationException($"{nameof(StoreSubscription)} with id \"{_id}\" was not disposed. "+ new Exception().StackTrace);
}
}
2 changes: 1 addition & 1 deletion src/Memento.Core/Store.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
public class Store<TState, TMessage>(Func<TState> initializer)
: AbstractStore<TState, TMessage>(initializer, Reducer)
where TState : class
where TMessage : class {
where TMessage : notnull {

/// <summary>
/// Initializes a new instance of the Store class with the specified initial state.
Expand Down
3 changes: 1 addition & 2 deletions test/Memento.Test/Core/Mock/RedoUndoTodoStore.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using Memento.Core;
using Memento.Test.Core.Mock;
using System.Collections.Immutable;

namespace Memento.Sample.Blazor.Stores;
namespace Memento.Test.Core.Mock;

public record RedoUndoTodoState {
public ImmutableArray<Todo> Todos { get; init; } = [];
Expand Down
6 changes: 2 additions & 4 deletions test/Memento.Test/Core/ReDoUnDoStoreTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using FluentAssertions;
using Memento.Core;
using Memento.Sample.Blazor.Stores;
using Memento.Test.Core.Mock;
using Microsoft.Extensions.DependencyInjection;

Expand All @@ -11,8 +10,8 @@ public class ReDoUnDoStoreTest {
public async Task Test1() {
var services = new ServiceCollection().BuildServiceProvider();

var store = new RedoUndoTodoStore(new MockTodoService());
var provider = new StoreProvider(services, new[] { store });
using var store = new RedoUndoTodoStore(new MockTodoService());
using var provider = new StoreProvider(services, [store]);
await provider.InitializeAsync();

Assert.Equal(store.State, new()); // Should().Be() is not working
Expand All @@ -22,7 +21,6 @@ public async Task Test1() {
store.FutureHistories.Count.Should().Be(0);
store.Present.Should().BeNull();


var todoStates = new List<RedoUndoTodoState>();
await store.CreateNewAsync("test1");
todoStates.Add(store.State);
Expand Down

0 comments on commit 6fb953f

Please sign in to comment.