protected override void Init()

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();
        });
      }
    }