Skip to content

Commit

Permalink
chore: update docstring and minor refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
limebell committed Aug 1, 2023
1 parent 49b0c51 commit 53026e7
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Libplanet.Action.Tests/Mocks/MockWorldState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public MockWorldState()

IAccount? IWorldState.GetAccount(Address address)

Check warning on line 23 in Libplanet.Action.Tests/Mocks/MockWorldState.cs

View workflow job for this annotation

GitHub Actions / Run Benchmark.Net benchmarks (macos-latest)

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 23 in Libplanet.Action.Tests/Mocks/MockWorldState.cs

View workflow job for this annotation

GitHub Actions / docs

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 23 in Libplanet.Action.Tests/Mocks/MockWorldState.cs

View workflow job for this annotation

GitHub Actions / docs

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 23 in Libplanet.Action.Tests/Mocks/MockWorldState.cs

View workflow job for this annotation

GitHub Actions / check-build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 23 in Libplanet.Action.Tests/Mocks/MockWorldState.cs

View workflow job for this annotation

GitHub Actions / check-build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 23 in Libplanet.Action.Tests/Mocks/MockWorldState.cs

View workflow job for this annotation

GitHub Actions / Run Benchmark.Net benchmarks (ubuntu-latest)

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 23 in Libplanet.Action.Tests/Mocks/MockWorldState.cs

View workflow job for this annotation

GitHub Actions / Run Benchmark.Net benchmarks (windows-latest)

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
{
_accounts.TryGetValue(address, out IAccount? account);
_accounts.TryGetValue(address, out IAccount account);
return account;
}
}
Expand Down
13 changes: 7 additions & 6 deletions Libplanet.Action.Tests/State/WorldTest.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System.Collections.Immutable;
using Bencodex.Types;
using Libplanet.Action.State;
using Libplanet.Action.Tests.Mocks;
using Libplanet.Crypto;
using Xunit;

namespace Libplanet.Action.State.Tests
namespace Libplanet.Action.Tests.State
{
public class WorldTest
{
Expand Down Expand Up @@ -54,8 +55,8 @@ public void SetAccount()

// TestGetAccount() will retrieve account from World.Delta
world = world.SetAccount(accountAddress, mockAccount);
Assert.Single(world.Delta.UpdatedAccounts);
Assert.Equal(accountAddress, world.Delta.UpdatedAccounts.First());
Assert.Single(world.Delta.UpdatedAddresses);
Assert.Equal(accountAddress, world.Delta.UpdatedAddresses.First());
Assert.Equal(mockAccount, world.GetAccount(accountAddress));
}

Expand All @@ -69,12 +70,12 @@ public void Flush()
IAccount emptyAccount = Account.Create(MockAccountState.Empty);
Address accountAddress = RandomAddress;
world = world.SetAccount(accountAddress, emptyAccount);
Assert.Single(world.Delta.UpdatedAccounts);
Assert.Equal(accountAddress, world.Delta.UpdatedAccounts.First());
Assert.Single(world.Delta.UpdatedAddresses);
Assert.Equal(accountAddress, world.Delta.UpdatedAddresses.First());

// After flush, World.Delta moves to World._baseState.Delta
world = World.Flush(world);
Assert.Empty(world.Delta.UpdatedAccounts);
Assert.Empty(world.Delta.UpdatedAddresses);
Assert.NotNull(world.GetAccount(accountAddress));
}

Expand Down
49 changes: 49 additions & 0 deletions Libplanet.Action/State/IWorld.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,62 @@
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using Libplanet.Crypto;

namespace Libplanet.Action.State
{
/// <summary>
/// An interface to manipulate an world state with
/// maintaining <see cref="Delta"/>.
/// <para>It is like a map which is virtually initialized such
/// that every possible <see cref="Address"/> exists and
/// is mapped to <see langword="null"/>. That means that:</para>
/// <list type="bullet">
/// <item>
/// <description>it does not have length,</description>
/// </item>
/// <item>
/// <description>its index getter never throws
/// <see cref="KeyNotFoundException"/>,
/// but returns <see langword="null"/> instead, and</description>
/// </item>
/// <item>
/// <description>filling an <see cref="Address"/> with
/// <see langword="null"/> account cannot be distinguished from
/// the <see cref="Address"/> having never been set to
/// any account.</description>
/// </item>
/// </list>
/// </summary>
/// <remarks>
/// This interface is immutable. <see cref="SetAccount(Address, IAccount)"/>
/// method does not manipulate the instance, but returns a new
/// <see cref="IWorld"/> instance with updated states.
/// </remarks>
internal interface IWorld : IWorldState
{
/// <summary>
/// The <see cref="IWorld"/> representing the delta part of
/// this <see cref="IWorld"/>.
/// </summary>
[Pure]
IWorldDelta Delta { get; }

/// <summary>
/// Gets a new instance that the world state of the given
/// <paramref name="address"/> is set to the given
/// <paramref name="account"/>.
/// </summary>
/// <param name="address">The <see cref="Address"/> referring
/// the account to set its account.</param>
/// <param name="account">The new account to fill the account with.</param>
/// <returns>A new <see cref="IWorld"/> instance that
/// the account state of the given <paramref name="address"/>
/// is set to the given <paramref name="account"/>.</returns>
/// <remarks>
/// This method method does not manipulate the instance,
/// but returns a new <see cref="IWorld"/> instance
/// with updated world instead.
/// </remarks>
[Pure]
IWorld SetAccount(Address address, IAccount account);
}
Expand Down
11 changes: 10 additions & 1 deletion Libplanet.Action/State/IWorldDelta.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,19 @@ namespace Libplanet.Action.State
{
public interface IWorldDelta
{
/// <summary>
/// A dictionary representing changed accounts for each <see cref="Address"/>.
/// </summary>
[Pure]
IImmutableDictionary<Address, IAccount> Accounts { get; }

/// <summary>
/// <para>
/// A set of <seealso cref="Address"/>es where each <see cref="Address"/> has
/// its account changed.
/// </para>
/// </summary>
[Pure]
IImmutableSet<Address> UpdatedAccounts { get; }
IImmutableSet<Address> UpdatedAddresses { get; }
}
}
35 changes: 34 additions & 1 deletion Libplanet.Action/State/IWorldState.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using Libplanet.Crypto;

namespace Libplanet.Action.State
{
/// <summary>
/// An interface to fetch world states.
/// <para>It is like a readonly map which is virtually initialized such
/// that every possible <see cref="Address"/> exists and
/// is mapped to <see langword="null"/>. That means that:</para>
/// <list type="bullet">
/// <item>
/// <description>it does not have length,</description>
/// </item>
/// <item>
/// <description>its index getter never throws
/// <see cref="KeyNotFoundException"/>,
/// but returns <see langword="null"/> instead, and</description>
/// </item>
/// <item>
/// <description>filling an <see cref="Address"/> with
/// <see langword="null"/> state cannot be distinguished from
/// the <see cref="Address"/> having never been set to
/// any state.</description>
/// </item>
/// </list>
/// </summary>
public interface IWorldState
{
[Pure]
/// <summary>
/// Whether <see cref="IWorldState"/> is in legacy state or not
/// </summary>
bool Legacy { get; }

/// <summary>
/// Gets the world state of the given <paramref name="address"/>.
/// </summary>
/// <param name="address">The <see cref="Address"/> referring
/// the world to get its state.</param>
/// <returns>The world state of the given <paramref name="address"/>.
/// If it has never been set to any state it returns <see langword="null"/>
/// instead.</returns>
[Pure]
IAccount? GetAccount(Address address);
}
Expand Down
7 changes: 7 additions & 0 deletions Libplanet.Action/State/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace Libplanet.Action.State
{
/// <summary>
/// An internal implementation of <see cref="IWorld"/>.
/// </summary>
[Pure]
internal class World : IWorld
{
Expand All @@ -21,12 +24,15 @@ private World(IWorldState baseState, IWorldDelta delta)
Legacy = false;
}

/// <inheritdoc/>
[Pure]
public IWorldDelta Delta { get; private set; }

/// <inheritdoc/>
[Pure]
public bool Legacy { get; private set; }

/// <inheritdoc/>
[Pure]
public IAccount? GetAccount(Address address)
{
Expand All @@ -35,6 +41,7 @@ private World(IWorldState baseState, IWorldDelta delta)
: _baseState.GetAccount(address);
}

/// <inheritdoc/>
[Pure]
public IWorld SetAccount(Address address, IAccount account) =>
new World(this, new WorldDelta(Delta.Accounts.SetItem(address, account)))
Expand Down
4 changes: 3 additions & 1 deletion Libplanet.Action/State/WorldDelta.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ internal WorldDelta(IImmutableDictionary<Address, IAccount> accounts)
Accounts = accounts;
}

public IImmutableSet<Address> UpdatedAccounts => Accounts.Keys.ToImmutableHashSet();
/// <inheritdoc cref="IWorldDelta.UpdatedAddresses"/>
public IImmutableSet<Address> UpdatedAddresses => Accounts.Keys.ToImmutableHashSet();

/// <inheritdoc cref="IWorldDelta.Accounts"/>
public IImmutableDictionary<Address, IAccount> Accounts { get; }
}
}

0 comments on commit 53026e7

Please sign in to comment.