Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add "Temp" and "Persistent" flags for RpcTarget options #2792

Merged
merged 4 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;

namespace Unity.Netcode
{
public abstract class BaseRpcTarget
public abstract class BaseRpcTarget : IDisposable
{
protected NetworkManager m_NetworkManager;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,10 @@ internal DirectSendRpcTarget(NetworkManager manager) : base(manager)
{

}

internal DirectSendRpcTarget(ulong clientId, NetworkManager manager) : base(manager)
{
ClientId = clientId;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ public enum SendTo
SpecifiedInParams
}

public enum RpcTargetUse
{
Temp,
Persistent
}

/// <summary>
/// Implementations of the various <see cref="SendTo"/> options, as well as additional runtime-only options
/// <see cref="Single"/>,
Expand Down Expand Up @@ -182,15 +188,13 @@ public void Dispose()

/// <summary>
/// Send to a specific single client ID.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="clientId"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Single().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Single(ulong clientId)
public BaseRpcTarget Single(ulong clientId, RpcTargetUse use)
{
if (clientId == m_NetworkManager.LocalClientId)
{
Expand All @@ -199,34 +203,54 @@ public BaseRpcTarget Single(ulong clientId)

if (m_NetworkManager.IsServer || clientId == NetworkManager.ServerClientId)
{
if (use == RpcTargetUse.Persistent)
{
return new DirectSendRpcTarget(clientId, m_NetworkManager);
}
m_CachedDirectSendTarget.SetClientId(clientId);
return m_CachedDirectSendTarget;
}

if (use == RpcTargetUse.Persistent)
{
return new ProxyRpcTarget(clientId, m_NetworkManager);
}
m_CachedProxyRpcTarget.SetClientId(clientId);
return m_CachedProxyRpcTarget;
}

/// <summary>
/// Send to everyone EXCEPT a specific single client ID.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="excludedClientId"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Not() or Group().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Not(ulong excludedClientId)
public BaseRpcTarget Not(ulong excludedClientId, RpcTargetUse use)
{
IGroupRpcTarget target;
if (m_NetworkManager.IsServer)
{
target = m_CachedTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new RpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedTargetGroup;
}
}
else
{
target = m_CachedProxyRpcTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new ProxyRpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedProxyRpcTargetGroup;
}
}
target.Clear();
foreach (var clientId in m_NetworkManager.ConnectedClientsIds)
Expand All @@ -250,24 +274,36 @@ public BaseRpcTarget Not(ulong excludedClientId)
/// Sends to a group of client IDs.
/// NativeArrays can be trivially constructed using Allocator.Temp, making this an efficient
/// Group method if the group list is dynamically constructed.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="clientIds"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Not() or Group().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Group(NativeArray<ulong> clientIds)
public BaseRpcTarget Group(NativeArray<ulong> clientIds, RpcTargetUse use)
{
IGroupRpcTarget target;
if (m_NetworkManager.IsServer)
{
target = m_CachedTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new RpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedTargetGroup;
}
}
else
{
target = m_CachedProxyRpcTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new ProxyRpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedProxyRpcTargetGroup;
}
}
target.Clear();
foreach (var clientId in clientIds)
Expand All @@ -282,36 +318,32 @@ public BaseRpcTarget Group(NativeArray<ulong> clientIds)
/// Sends to a group of client IDs.
/// NativeList can be trivially constructed using Allocator.Temp, making this an efficient
/// Group method if the group list is dynamically constructed.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="clientIds"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Not() or Group().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Group(NativeList<ulong> clientIds)
public BaseRpcTarget Group(NativeList<ulong> clientIds, RpcTargetUse use)
{
var asArray = clientIds.AsArray();
return Group(asArray);
return Group(asArray, use);
}

/// <summary>
/// Sends to a group of client IDs.
/// Constructing arrays requires garbage collected allocations. This override is only recommended
/// if you either have no strict performance requirements, or have the group of client IDs cached so
/// it is not created each time.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="clientIds"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Not() or Group().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Group(ulong[] clientIds)
public BaseRpcTarget Group(ulong[] clientIds, RpcTargetUse use)
{
return Group(new NativeArray<ulong>(clientIds, Allocator.Temp));
return Group(new NativeArray<ulong>(clientIds, Allocator.Temp), use);
}

/// <summary>
Expand All @@ -320,24 +352,36 @@ public BaseRpcTarget Group(ulong[] clientIds)
/// a garbage collected allocation (even if the type itself is a struct type, due to boxing).
/// This override is only recommended if you either have no strict performance requirements,
/// or have the group of client IDs cached so it is not created each time.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="clientIds"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Not() or Group().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Group<T>(T clientIds) where T : IEnumerable<ulong>
public BaseRpcTarget Group<T>(T clientIds, RpcTargetUse use) where T : IEnumerable<ulong>
{
IGroupRpcTarget target;
if (m_NetworkManager.IsServer)
{
target = m_CachedTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new RpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedTargetGroup;
}
}
else
{
target = m_CachedProxyRpcTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new ProxyRpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedProxyRpcTargetGroup;
}
}
target.Clear();
foreach (var clientId in clientIds)
Expand All @@ -352,24 +396,36 @@ public BaseRpcTarget Group<T>(T clientIds) where T : IEnumerable<ulong>
/// Sends to everyone EXCEPT a group of client IDs.
/// NativeArrays can be trivially constructed using Allocator.Temp, making this an efficient
/// Group method if the group list is dynamically constructed.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="excludedClientIds"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Not() or Group().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Not(NativeArray<ulong> excludedClientIds)
public BaseRpcTarget Not(NativeArray<ulong> excludedClientIds, RpcTargetUse use)
{
IGroupRpcTarget target;
if (m_NetworkManager.IsServer)
{
target = m_CachedTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new RpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedTargetGroup;
}
}
else
{
target = m_CachedProxyRpcTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new ProxyRpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedProxyRpcTargetGroup;
}
}
target.Clear();

Expand Down Expand Up @@ -400,36 +456,32 @@ public BaseRpcTarget Not(NativeArray<ulong> excludedClientIds)
/// Sends to everyone EXCEPT a group of client IDs.
/// NativeList can be trivially constructed using Allocator.Temp, making this an efficient
/// Group method if the group list is dynamically constructed.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="excludedClientIds"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Not() or Group().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Not(NativeList<ulong> excludedClientIds)
public BaseRpcTarget Not(NativeList<ulong> excludedClientIds, RpcTargetUse use)
{
var asArray = excludedClientIds.AsArray();
return Not(asArray);
return Not(asArray, use);
}

/// <summary>
/// Sends to everyone EXCEPT a group of client IDs.
/// Constructing arrays requires garbage collected allocations. This override is only recommended
/// if you either have no strict performance requirements, or have the group of client IDs cached so
/// it is not created each time.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="excludedClientIds"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Not() or Group().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Not(ulong[] excludedClientIds)
public BaseRpcTarget Not(ulong[] excludedClientIds, RpcTargetUse use)
{
return Not(new NativeArray<ulong>(excludedClientIds, Allocator.Temp));
return Not(new NativeArray<ulong>(excludedClientIds, Allocator.Temp), use);
}

/// <summary>
Expand All @@ -438,24 +490,36 @@ public BaseRpcTarget Not(ulong[] excludedClientIds)
/// a garbage collected allocation (even if the type itself is a struct type, due to boxing).
/// This override is only recommended if you either have no strict performance requirements,
/// or have the group of client IDs cached so it is not created each time.
/// <br />
/// <br />
/// Do not cache or reuse the result of this method.
/// For performance reasons, the same object is used each time to avoid garbage-collected allocations,
/// and its contents are simply changed.
/// </summary>
/// <param name="excludedClientIds"></param>
/// <param name="use"><see cref="RpcTargetUse.Temp"/> will return a cached target, which should not be stored as it will
/// be overwritten in future calls to Not() or Group().<br /><br /><see cref="RpcTargetUse.Persistent"/> will
/// return a new target, which can be stored, but should not be done frequently because it results in a GC allocation.</param>
/// <returns></returns>
public BaseRpcTarget Not<T>(T excludedClientIds) where T : IEnumerable<ulong>
public BaseRpcTarget Not<T>(T excludedClientIds, RpcTargetUse use) where T : IEnumerable<ulong>
{
IGroupRpcTarget target;
if (m_NetworkManager.IsServer)
{
target = m_CachedTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new RpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedTargetGroup;
}
}
else
{
target = m_CachedProxyRpcTargetGroup;
if (use == RpcTargetUse.Persistent)
{
target = new ProxyRpcTargetGroup(m_NetworkManager);
}
else
{
target = m_CachedProxyRpcTargetGroup;
}
}
target.Clear();

Expand Down
Loading
Loading