in rd-net/RdFramework/Impl/RdList.cs [196:276]
public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, UnsafeReader stream, IRdWireableDispatchHelper dispatchHelper)
{
var header = stream.ReadLong();
var opType = header & ((1 << versionedFlagShift) - 1);
var version = header >> versionedFlagShift;
var index = stream.ReadInt();
var kind = (AddUpdateRemove) opType;
var value = default(V);
var isPut = kind is AddUpdateRemove.Add or AddUpdateRemove.Update;
if (isPut)
value = ReadValueDelegate(ctx, stream);
var lifetime = dispatchHelper.Lifetime;
var definition = value != null ? TryPreBindValue(lifetime, value, index, true) : null;
dispatchHelper.Dispatch(() =>
{
ReceiveTrace?.Log($"list `{Location}` ({RdId}) :: {kind} :: index={index} :: version = {version}{(isPut ? " :: value = " + value.PrintToString() : "")}");
if (version != myNextVersion)
{
definition?.Terminate();
Assertion.Fail("Version conflict for {0} Expected version {1} received {2}. Are you modifying a list from two sides?",
Location,
myNextVersion,
version);
}
myNextVersion++;
switch (kind)
{
case AddUpdateRemove.Add:
{
if (index < 0)
{
TryGetBindDefinitions(lifetime)?.Add(definition);
myList.Add(value);
}
else
{
TryGetBindDefinitions(lifetime)?.Insert(index, definition);
myList.Insert(index, value);
}
break;
}
case AddUpdateRemove.Update:
{
if (TryGetBindDefinitions(lifetime) is {} definitions)
{
definitions[index]?.Terminate();
definitions[index] = definition;
}
myList[index] = value;
break;
}
case AddUpdateRemove.Remove:
{
if (TryGetBindDefinitions(lifetime) is {} definitions)
{
definitions[index]?.Terminate();
definitions.RemoveAt(index);
}
myList.RemoveAt(index);
break;
}
default:
throw new ArgumentOutOfRangeException(kind.ToString());
}
});
}