-
Notifications
You must be signed in to change notification settings - Fork 456
Description
I recently hopped back for another NGO project, and am attempting to use a NetworkList<MyStruct>
with a separate custom Tracker<MyStruct>
class to make local behavior instances follow what the values in the NetworkList
. In attempt to make sure all ChangeEvent types are handled correctly, I tried to figure out how to compare the new values to the old ones, when I stumbled upon a bigger problem reading the NetworkList's source....
It doesn't call OnListChanged
with ChangeEvent.Full
, ever.
I don't see any other callback either. It seems the only time this kind of event is called is if the list itself is Dirty. I don't know when will such a thing happen, but it concerns me that it is currently impossible to even know if the entire set of values in my list just ups and swaps itself.
The List itself does not seem to have a changed event for itself so there is no way to detect this Full change even separately...
Is there a way this could be better implemented on the whole? the goal is to have local stateful POCOs that are paired to each MyStruct
in the list without needing to sync the POCOs.
Attached below is an example of a way this could work but as mentioned, EventType.Full
is problematic...
I don't know if I'm missing something obvious but I've tried to read NetworkList's entire source, checked NetworkBehaviourBase for good measure, and went through the available documentation with no proper recourse on this problem. Help would be appreciated, please.
public abstract class ANetworkListPairTracker<T> where T : unmanaged, IEquatable<T>
{
public void Pair(NetworkList<T> list) => list.OnListChanged += TrackChange;
public void Release(NetworkList<T> list) => list.OnListChanged -= TrackChange;
private void TrackChange(NetworkListEvent<T> changeEvent)
{
switch (changeEvent.Type)
{
case NetworkListEvent<T>.EventType.Add:
case NetworkListEvent<T>.EventType.Insert:
Create(changeEvent.Index, changeEvent.Value);
break;
case NetworkListEvent<T>.EventType.Remove:
case NetworkListEvent<T>.EventType.RemoveAt:
Remove(changeEvent.Index);
break;
case NetworkListEvent<T>.EventType.Value:
Update(changeEvent.Index, changeEvent.Value);
break;
case NetworkListEvent<T>.EventType.Clear:
Clear();
break;
case NetworkListEvent<T>.EventType.Full:
// ???
break;
}
}
protected abstract void Create(int index, T record);
protected abstract void Update(int index, T record);
protected abstract void Remove(int index);
protected abstract void Clear();
}
public class ExampleCardEffect
{
//details here
}
public class CardInstancePairTracker : ANetworkListPairTracker<CardRecord>
{
private List<ExampleCardEffect> _instances = new();
private CardOwner _owner;
public CardInstancePairTracker(CardOwner owner) => _owner = owner;
protected override void Create(int index, CardRecord record)
{
var instance = CardFactory.CreateFrom(record.CardId);
instance.SetOwner(_owner);
_instances.Insert(index, instance);
}
protected override void Update(int index, CardRecord record)
{
if (_instances[index].TryUpdate(record))
return;
_instances[index].EndEffect();
_instances[index] = CardFactory.CreateFrom(record.CardId);
_instances[index].SetOwner(_owner);
}
protected override void Remove(int index)
{
_instances[index].EndEffect();
_instances.RemoveAt(index);
}
protected override void Clear()
{
foreach (var instance in _instances)
instance.EndEffect();
_instances.Clear();
}
}