Files
sbox-public/engine/Sandbox.Engine/Scene/Components/Component.Network.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

125 lines
3.3 KiB
C#

using System.ComponentModel;
using System.Runtime.CompilerServices;
using Sandbox.Network;
namespace Sandbox;
public abstract partial class Component
{
[ActionGraphInclude, Icon( "wifi" )]
public GameObject.NetworkAccessor Network => GameObject.Network;
private readonly Dictionary<string, IInterpolatedSyncVar> InterpolatedVars = new();
/// <summary>
/// True if this is a networked object and is owned by another client. This means that we're
/// not controlling this object, so shouldn't try to move it or anything.
/// </summary>
public bool IsProxy => GameObject.IsProxy;
[EditorBrowsable( EditorBrowsableState.Never )]
protected void __sync_SetValue<T>( in WrappedPropertySet<T> p )
{
try
{
// If we aren't valid then just set the property value anyway.
if ( !IsValid )
{
p.Setter?.Invoke( p.Value );
return;
}
var root = GameObject.FindNetworkRoot();
var slot = NetworkObject.GetPropertySlot( p.MemberIdent, Id );
if ( root is null )
{
p.Setter?.Invoke( p.Value );
return;
}
var net = root._net;
if ( !net.dataTable.IsRegistered( slot ) )
{
p.Setter?.Invoke( p.Value );
return;
}
if ( !net.dataTable.HasControl( slot ) )
{
if ( !NetworkTable.IsReadingChanges )
return;
var attribute = p.GetAttribute<SyncAttribute>();
var interpolate = attribute?.Flags.HasFlag( SyncFlags.Interpolate ) ?? false;
if ( interpolate && p.Value is not null )
{
var interpolated = GetOrCreateInterpolatedVar( p.Value, p.PropertyName );
interpolated?.Update( p.Value );
}
p.Setter?.Invoke( p.Value );
return;
}
net.dataTable.UpdateSlotHash( slot, p.Value );
p.Setter?.Invoke( p.Value );
}
catch ( Exception e )
{
Log.Error( e, $"Exception when setting {p.TypeName}.{p.PropertyName} - {e.Message}" );
}
}
[EditorBrowsable( EditorBrowsableState.Never )]
protected T __sync_GetValue<T>( WrappedPropertyGet<T> p )
{
var attribute = p.GetAttribute<SyncAttribute>();
var interpolate = attribute?.Flags.HasFlag( SyncFlags.Interpolate ) ?? false;
if ( !interpolate ) return p.Value;
var root = GameObject.FindNetworkRoot();
if ( root is null ) return p.Value;
var slot = NetworkObject.GetPropertySlot( p.MemberIdent, Id );
var net = root._net;
if ( !net.dataTable.IsRegistered( slot ) || net.dataTable.HasControl( slot ) )
return p.Value;
if ( InterpolatedVars.TryGetValue( p.PropertyName, out var i ) )
return (T)i.Query( Time.Now );
return p.Value;
}
[EditorBrowsable( EditorBrowsableState.Never )]
[MethodImpl( MethodImplOptions.AggressiveInlining )]
protected void __rpc_Wrapper( in WrappedMethod m, params object[] argumentList )
{
Rpc.OnCallInstanceRpc( GameObject, this, m, argumentList );
}
/// <summary>
/// Get or create a new interpolated variable. This will set the current interpolated value to the
/// provided one if it hasn't been created yet.
/// </summary>
private InterpolatedSyncVar<T> GetOrCreateInterpolatedVar<T>( T value, string propertyName )
{
if ( InterpolatedVars.TryGetValue( propertyName, out var i ) )
return (InterpolatedSyncVar<T>)i;
var interpolator = IInterpolatedSyncVar.Create( value );
if ( interpolator is null )
return null;
var interpolated = new InterpolatedSyncVar<T>( interpolator );
InterpolatedVars[propertyName] = interpolated;
return interpolated;
}
}