Skip to content

Commit a4b2eb9

Browse files
committed
Add SyncVar/Field change events
- Implemented `ISyncFieldChanged<T>` interface for syncable fields to handle value changes. - Added `ValueChanged` event in relevant classes to notify when values change. - Updated methods to include field names in processing for better tracking. - Introduced a callback registry to manage and invoke user-defined callbacks on type value changes.
1 parent 9f647e8 commit a4b2eb9

File tree

8 files changed

+307
-91
lines changed

8 files changed

+307
-91
lines changed

LiteEntitySystem/ClientEntityManager.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -511,11 +511,11 @@ private unsafe void GoToNextState()
511511
if (field.FieldType == FieldType.SyncableSyncVar)
512512
{
513513
var syncableField = RefMagic.RefFieldValue<SyncableField>(entity, field.Offset);
514-
field.TypeProcessor.SetFrom(syncableField, field.SyncableSyncVarOffset, predictedData + field.PredictedOffset);
514+
field.TypeProcessor.SetFrom(syncableField, field.SyncableSyncVarOffset, predictedData + field.PredictedOffset, field.Name);
515515
}
516516
else
517517
{
518-
field.TypeProcessor.SetFrom(entity, field.Offset, predictedData + field.PredictedOffset);
518+
field.TypeProcessor.SetFrom(entity, field.Offset, predictedData + field.PredictedOffset, field.Name);
519519
}
520520
}
521521
}
@@ -649,7 +649,7 @@ protected override unsafe void OnLogicTick()
649649
for(int i = 0; i < classData.InterpolatedCount; i++)
650650
{
651651
var field = classData.Fields[i];
652-
field.TypeProcessor.SetFrom(entity, field.Offset, currentDataPtr + field.FixedOffset);
652+
field.TypeProcessor.SetFrom(entity, field.Offset, currentDataPtr + field.FixedOffset, field.Name);
653653
}
654654

655655
//update
@@ -1002,7 +1002,7 @@ private unsafe bool ReadEntityState(byte* rawData, bool fistSync)
10021002
if (field.FieldType == FieldType.SyncableSyncVar)
10031003
{
10041004
var syncableField = RefMagic.RefFieldValue<SyncableField>(entity, field.Offset);
1005-
field.TypeProcessor.SetFrom(syncableField, field.SyncableSyncVarOffset, readDataPtr);
1005+
field.TypeProcessor.SetFrom(syncableField, field.SyncableSyncVarOffset, readDataPtr, field.Name);
10061006
}
10071007
else
10081008
{
@@ -1023,7 +1023,7 @@ private unsafe bool ReadEntityState(byte* rawData, bool fistSync)
10231023
}
10241024
else
10251025
{
1026-
field.TypeProcessor.SetFrom(entity, field.Offset, readDataPtr);
1026+
field.TypeProcessor.SetFrom(entity, field.Offset, readDataPtr, field.Name);
10271027
}
10281028
}
10291029
//Logger.Log($"E {entity.Id} Field updated: {field.Name}");

LiteEntitySystem/Extensions/SyncNetSerializable.cs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
using System;
2+
using System.Collections.Generic;
23
using K4os.Compression.LZ4;
34
using LiteNetLib.Utils;
45

56
namespace LiteEntitySystem.Extensions
67
{
7-
public class SyncNetSerializable<T> : SyncableField where T : INetSerializable
8+
public class SyncNetSerializable<T> : SyncableField, ISyncFieldChanged<T> where T : INetSerializable
89
{
910
private static readonly NetDataWriter WriterCache = new();
1011
private static readonly NetDataReader ReaderCache = new();
1112
private static byte[] CompressionBuffer;
12-
13+
1314
private T _value;
1415

16+
public event Action<T, T> ValueChanged;
17+
1518
public T Value
1619
{
1720
get => _value;
@@ -45,8 +48,9 @@ protected internal override void OnSyncRequested()
4548
Logger.LogError("Too much sync data!");
4649
return;
4750
}
51+
4852
int bufSize = LZ4Codec.MaximumOutputSize(WriterCache.Length) + 2;
49-
if(CompressionBuffer == null || CompressionBuffer.Length < bufSize)
53+
if (CompressionBuffer == null || CompressionBuffer.Length < bufSize)
5054
CompressionBuffer = new byte[bufSize];
5155
FastBitConverter.GetBytes(CompressionBuffer, 0, (ushort)WriterCache.Length);
5256
int encodedLength = LZ4Codec.Encode(
@@ -55,20 +59,36 @@ protected internal override void OnSyncRequested()
5559
WriterCache.Length,
5660
CompressionBuffer,
5761
2,
58-
CompressionBuffer.Length-2,
62+
CompressionBuffer.Length - 2,
5963
LZ4Level.L00_FAST);
60-
ExecuteRPC(_initAction, new ReadOnlySpan<byte>(CompressionBuffer, 0, encodedLength+2));
64+
ExecuteRPC(_initAction, new ReadOnlySpan<byte>(CompressionBuffer, 0, encodedLength + 2));
6165
}
6266

6367
private void Init(ReadOnlySpan<byte> data)
6468
{
69+
// Read uncompressed size
6570
ushort origSize = BitConverter.ToUInt16(data);
71+
6672
if (CompressionBuffer == null || CompressionBuffer.Length < origSize)
6773
CompressionBuffer = new byte[origSize];
6874
LZ4Codec.Decode(data[2..], new Span<byte>(CompressionBuffer));
6975
ReaderCache.SetSource(CompressionBuffer, 0, origSize);
70-
_value ??= _constructor();
71-
_value.Deserialize(ReaderCache);
76+
77+
// Capture the old reference
78+
T oldValue = _value;
79+
80+
// Always create a fresh instance for deserialization
81+
T newValue = _constructor();
82+
newValue.Deserialize(ReaderCache);
83+
84+
// Update _value
85+
_value = newValue;
86+
87+
// Compare old and new. If changed, raise event.
88+
if (oldValue == null || !EqualityComparer<T>.Default.Equals(oldValue, _value))
89+
{
90+
ValueChanged?.Invoke(oldValue, newValue);
91+
}
7292
}
7393

7494
public static implicit operator T(SyncNetSerializable<T> field)

LiteEntitySystem/Extensions/SyncString.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System;
2+
using System.Runtime.CompilerServices;
23
using System.Text;
4+
using LiteEntitySystem.Internal;
35

46
namespace LiteEntitySystem.Extensions
57
{
6-
public class SyncString : SyncableField
8+
public class SyncString : SyncableField, ISyncFieldChanged<string>
79
{
810
private static readonly UTF8Encoding Encoding = new(false, true);
911
private byte[] _stringData;
@@ -12,6 +14,7 @@ public class SyncString : SyncableField
1214

1315
private static RemoteCallSpan<byte> _setStringClientCall;
1416

17+
public event Action<string, string> ValueChanged;
1518
public string Value
1619
{
1720
get => _string;
@@ -43,7 +46,9 @@ public static implicit operator string(SyncString s)
4346

4447
private void SetNewString(ReadOnlySpan<byte> data)
4548
{
46-
_string = Encoding.GetString(data);
49+
var newString = Encoding.GetString(data);
50+
ValueChanged?.Invoke(_string, newString);
51+
_string = newString;
4752
}
4853

4954
protected internal override void OnSyncRequested()

0 commit comments

Comments
 (0)