mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-02 19:38:24 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
125 lines
3.3 KiB
C#
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;
|
|
}
|
|
}
|