Skip to content

Conversation

mattwalsh-unity
Copy link
Contributor

Resolves issue #1006 and jira MTT-1005

return m_Set.GetEnumerator();
}

/// <inheritdoc />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Git has made a mess of this diff; I just hoisted the Add functionality out of the interface-qualified definitions into a method and then made those interfaces call that method.

Copy link
Contributor

@JesseOlmer JesseOlmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 nit comments, otherwise lgtm


/// <inheritdoc />
bool ISet<T>.Add(T item)
public void Add(T item)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You don't need 3 methods for this. Just put the implementation in the ISet and call it from the ICollection.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the wackiness here is that we have ISet<T> which has its own Add method, and then ICollection<T> (which is a parent to ISet<T>) also has its own Add method, which differs only by return type, and so I have to implement both explicit interfaces.

But then if a user wants to call either one, they have to do a non-intuitive cast, e.g. ((ISet<int>)m_ServerComp.TheSet).Add(1234);. That's why I did the 3rd method. But maybe I'm missing another way?

I'm thinking about using a less grand interface than ISet / ICollection anyway vs. today where we promise to do everything those interfaces do, so that if we use native container underlying storage we don't have to make up for make of these calls that the native types don't support.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HashSet<T> is similar and it implements both ISet<T> and ICollection<T> at the same time — and yes, it implements both void returning and bool returning methods and they both call the exact same method behind the scenes. Let me get you some useful links to relevant points.

bool Add:

public bool Add(T item) => AddIfNotPresent(item, out _);

https://github.com/dotnet/runtime/blob/1a4675db08384e4f20cf4481e6eaf03e40f3d754/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs#L455

void Add:

void ICollection<T>.Add(T item) => AddIfNotPresent(item, out _);

https://github.com/dotnet/runtime/blob/1a4675db08384e4f20cf4481e6eaf03e40f3d754/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs#L181

underlying AddIfNotPresent (the actual code):

private bool AddIfNotPresent(T value, out int location)
{
    if (_buckets == null)
    {
        Initialize(0);
    }
    Debug.Assert(_buckets != null);

    Entry[]? entries = _entries;
// ...

https://github.com/dotnet/runtime/blob/1a4675db08384e4f20cf4481e6eaf03e40f3d754/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs#L1084

I think we could follow the same interface pattern closely to make our stuff more .NET-like :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I ended up sending Matt much the same thing in a DM & gist. The key here is you don't need explicit implementation on both of them, just enough to disambiguate. Explicit implementation of both is also what causes this required cast in the first place, as explicit implementations always need an explicit cast.

}

/// <inheritdoc />
void ICollection<T>.Add(T item)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Maybe use an expression-bodied method to make it SUPER clear this is just a remap... e.g.

bool Add(T item)
{
   ..
}

void ICollection<T>.Add(T item) => Add(item);

(you also only need the explicit implementation on one of them)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, cool, I can do that on ICollection, but I'm stuck on doing this for ISet because it has a different return type

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My code snippet should work. You need to change your implementation to return a bool, and then just ignore it on ICollection, that should meet both ISet and ICollection needs (but is a moot point if you do the suggestion in the other comment thread)

@mattwalsh-unity mattwalsh-unity merged commit 1da76b2 into develop Aug 5, 2021
@mattwalsh-unity mattwalsh-unity deleted the feature/improve_set branch August 5, 2021 13:40
SamuelBellomo added a commit that referenced this pull request Aug 11, 2021
…nsform

* develop: (32 commits)
  refactor: calling networkShow(NetworkObject) code in networkshow(List<NetworkObject>) (#1028)
  feat: snapshot. MTT-685 MTT-822 (#1021)
  test: adding a multi-instance test checking NetworkShow and NetworkHide on lists of objects (#1036)
  fix: corrected NetworkVariable WriteField/WriteDelta/ReadField/ReadDelta dropping the last byte if unaligned. (#1008)
  chore: run standards check over solution files (#1027)
  chore: replace MLAPI with Netcode in Markdown files (#1025)
  fix!: added plainly-callable Add() method to NetworkSet [MTT-1005] (#1022)
  fix: fixing incorrect merge done as part of commit 85842ee (#1023)
  chore: cleanup/upgrade serialized scenes (#1020)
  chore: replace MLAPI with Netcode in C# source files (#1019)
  test: add network collections, struct and class tests MTT-936 (#1000)
  test: add buildtests to test build pipeline on target platforms (#1018)
  chore: rename MLAPI types to Netcode (#1017)
  chore!: rename asmdefs, change top-level namespaces (#1015)
  Replacing community NetworkManagerHUD with a simpler implementation (#993)
  test: network prefab pools and INetworkPrefabInstanceHandler (#1004)
  fix: do not expose Runtime internals to TestProject.ManualTests asmdef (#1014)
  refactor: snapshot. merge preparation. Removing old acks, removing unused varia… (#1013)
  chore!: per-asmdef namespaces instead of per-folder (#1009)
  feat: snapshot. ground work, preparing depedencies. No impact on code behaviour (#1012)
  ...

# Conflicts:
#	com.unity.multiplayer.mlapi/Prototyping/NetworkTransform.cs
#	com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageHandler.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants