in rd-net/RdFramework/Impl/RdMap.cs [117:188]
protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCtx ctx)
{
base.Init(lifetime, proto, ctx);
if (!OptimizeNested)
{
Change.Advise(lifetime, it =>
{
AssertNullability(it.Key);
if (it.Kind != AddUpdateRemove.Remove) AssertNullability(it.NewValue);
if (IsLocalChange)
{
var definitions = TryGetBindDefinitions(lifetime);
if (definitions == null)
return;
if (it.Kind != AddUpdateRemove.Add)
definitions[it.Key]?.Terminate();
if (it.Kind == AddUpdateRemove.Remove)
definitions.Remove(it.Key);
if (it.Kind != AddUpdateRemove.Remove)
{
it.NewValue.IdentifyPolymorphic(proto.Identities, proto.Identities.Next(RdId));
var definition = TryPreBindValue(lifetime, it.Key, it.NewValue, false);
definitions[it.Key] = definition;
}
}
});
}
using (UsingLocalChange())
{
Advise(lifetime, it =>
{
if (!IsLocalChange) return;
proto.Wire.Send(RdId, SendContext.Of(ctx, it, this), static (sendContext, stream) =>
{
var sContext = sendContext.SzrCtx;
var evt = sendContext.Event;
var me = sendContext.This;
var versionedFlag = me.IsMaster ? 1 << versionedFlagShift : 0;
stream.WriteInt32(versionedFlag | (int)evt.Kind);
var version = ++me.myNextVersion;
if (me.IsMaster)
{
lock(me.myPendingForAck)
me.myPendingForAck[evt.Key] = version;
stream.WriteInt64(version);
}
me.WriteKeyDelegate(sContext, stream, evt.Key);
if (evt.IsUpdate || evt.IsAdd)
{
me.WriteValueDelegate(sContext, stream, evt.NewValue);
}
SendTrace?.Log($"{me} :: {evt.Kind} :: key = {evt.Key.PrintToString()}"
+ (me.IsMaster ? " :: version = " + version : "")
+ (evt.Kind != AddUpdateRemove.Remove ? " :: value = " + evt.NewValue.PrintToString() : ""));
});
if (!OptimizeNested)
it.NewValue.BindPolymorphic();
});
}
}