Exemplo n.º 1
0
        private void DoCall(Node Target)
        {
            switch (Type)
            {
            case TypeOfCall.RPC:
                MethodInfo methodInfo = MDStatics.GetMethodInfo(Target, Convert.ToInt32(Name));
                if (methodInfo == null)
                {
                    MDLog.Fatal(LOG_CAT, $"Could not find method {Target.GetType().ToString()}#{Name}");
                    return;
                }
                object[] convertedParams = MDStatics.ConvertParametersBackToObject(methodInfo, Parameters);
                MDStatics.GetReplicator().RpcSenderId = SenderPeerId;
                methodInfo.Invoke(Target, convertedParams);
                MDStatics.GetReplicator().RpcSenderId = -1;
                break;

            case TypeOfCall.RSET:
                MemberInfo       memberInfo = MDStatics.GetMemberInfo(Target, Name);
                IMDDataConverter Converter  = MDStatics.GetConverterForType(memberInfo.GetUnderlyingType());
                object           value      = Converter.ConvertBackToObject(memberInfo.GetValue(Target), Parameters);
                MDLog.Trace(LOG_CAT, $"Setting {Name} on {Target.Name} to value {value}");
                memberInfo.SetValue(Target, value);
                break;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Converts a set of parameters that were sent back to an object
        /// </summary>
        /// <param name="MethodInfo">The method info to convert for</param>
        /// <param name="Parameters">The parameters</param>
        /// <returns></returns>
        public static object[] ConvertParametersBackToObject(MethodInfo MethodInfo, params object[] Parameters)
        {
            if (Parameters == null || Parameters.Length == 0)
            {
                return(Parameters);
            }

            ParameterInfo[] CandidateParams = MethodInfo.GetParameters();

            List <object> ConvertedParams = new List <object>();

            for (int i = 0; i < Parameters.Length; i++)
            {
                // key0 = index, key1 = length
                object[] keys   = Parameters[i].ToString().Split(SEPARATOR);
                int      index  = Convert.ToInt32(keys[0].ToString());
                int      length = Convert.ToInt32(keys[1].ToString());

                // Extract parameters and use data converter
                object[]         converterParams = Parameters.SubArray(i + 1, i + length);
                IMDDataConverter Converter       = GetConverterForType(CandidateParams[index].ParameterType);
                object           convertedValue  = Converter.ConvertBackToObject(null, converterParams);

                // Add the value to our list
                ConvertedParams.Add(convertedValue);
                i += length;
            }

            return(ConvertedParams.ToArray());
        }
Exemplo n.º 3
0
        /// <summary>
        /// Parses the settings we know about
        /// </summary>
        /// <param name="SettingsValues">A setting array that has been run through MDReplicator.ParseParameters</param>
        protected void ParseSettings(MDReplicatedSetting[] SettingsValues)
        {
            foreach (MDReplicatedSetting setting in SettingsValues)
            {
                switch ((Settings)setting.Key)
                {
                case Settings.OnValueChangedEvent:
                    Node Node = NodeRef.GetRef() as Node;
                    OnValueChangedMethodCallback = Node.GetType().GetMethodRecursive(setting.Value.ToString());
                    if (OnValueChangedMethodCallback == null)
                    {
                        OnValueChangedEventCallback = Node.GetType().GetEvent(setting.Value.ToString());
                    }
                    MDLog.CError(OnValueChangedMethodCallback == null && OnValueChangedEventCallback == null, LOG_CAT, $"Failed to find method or event with name {setting.Value.ToString()} on Node {Node.GetPath()}");
                    break;

                case Settings.Converter:
                    Type DataConverterType = Type.GetType(setting.Value.ToString());
                    DataConverter = MDStatics.CreateConverterOfType(DataConverterType);
                    break;

                case Settings.CallOnValueChangedEventLocally:
                    ShouldCallOnValueChangedCallbackLocally = setting.Value as bool? ?? false;
                    break;
                }
            }

            // We got no data converter, get default one
            if (DataConverter == null)
            {
                DataConverter = MDStatics.GetConverterForType(Member.GetUnderlyingType());
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Sends a clocked rset to another client
        /// </summary>
        /// <param name="PeerId">The peer to send to</param>
        /// <param name="Reliability">Reliability to send at</param>
        /// <param name="Target">The node that is the target of our rpc call</param>
        /// <param name="MemberName">The name of the member to set</param>
        /// <param name="Value">The value to set</param>
        public void SendClockedRset(int PeerId, MDReliability Reliability, Node Target, string MemberName, object Value)
        {
            if (PeerId == MDStatics.GetPeerId())
            {
                // This is to ourselves so just set
                Target.SetMemberValue(MemberName, Value);
                return;
            }
            MDRemoteMode     Mode      = MDStatics.GetMemberRpcType(Target, MemberName);
            MemberInfo       info      = MDStatics.GetMemberInfo(Target, MemberName);
            IMDDataConverter Converter = MDStatics.GetConverterForType(info.GetUnderlyingType());

            switch (Mode)
            {
            case MDRemoteMode.Master:
                if (!Target.IsNetworkMaster())
                {
                    // Remote invoke master only
                    SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RSET, Reliability, Target.GetPath(),
                                    MemberName, Mode, Converter.ConvertForSending(Value, true));
                }

                break;

            case MDRemoteMode.MasterSync:
                if (!Target.IsNetworkMaster())
                {
                    // Remote invoke master only
                    SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RSET, Reliability, Target.GetPath(),
                                    MemberName, Mode, Converter.ConvertForSending(Value, true));
                }

                Target.SetMemberValue(MemberName, Value);
                break;

            case MDRemoteMode.Puppet:
            case MDRemoteMode.Remote:
                // Remote invoke
                SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RSET, Reliability, Target.GetPath(),
                                MemberName, Mode, Converter.ConvertForSending(Value, true));
                break;

            case MDRemoteMode.PuppetSync:
            case MDRemoteMode.RemoteSync:
                // Remote invoke and local invoke
                SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RSET, Reliability, Target.GetPath(),
                                MemberName, Mode, Converter.ConvertForSending(Value, true));
                Target.SetMemberValue(MemberName, Value);
                break;
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Adds a data converter to the cache for the given type. This converter will be returned when using
        /// MDstatics.GetConverterForType() once it is in the cache.
        /// </summary>
        /// <param name="Type">The type to add the converter for, include generic typing</param>
        /// <param name="DataConverter">The data converter</param>
        /// <returns>True if added, false if not</returns>
        public static bool AddDataConverterForTypeToCache(Type Type, IMDDataConverter DataConverter)
        {
            if (Type == null || DataConverter == null)
            {
                return(false);
            }

            if (!DataConverterCache.ContainsKey(Type))
            {
                DataConverterCache.Add(Type, DataConverter);
                return(true);
            }
            return(false);
        }
Exemplo n.º 6
0
 /// <summary>
 /// Get the data converter for the given type
 /// </summary>
 /// <param name="Type">The type to get the data converter for</param>
 /// <returns>The default data converter for this type</returns>
 public static IMDDataConverter GetConverterForType(Type Type)
 {
     if (!DataConverterCache.ContainsKey(Type))
     {
         IMDDataConverter converter = _InternalGetConverterForType(Type);
         if (converter.AllowCachingOfConverter())
         {
             DataConverterCache.Add(Type, converter);
         }
         else
         {
             return(converter);
         }
     }
     return(DataConverterCache[Type]);
 }
Exemplo n.º 7
0
        /// <summary>
        /// Adds a data converter to the cache for the given type. This converter will be returned when using
        /// MDstatics.GetConverterForType() once it is in the cache.
        /// </summary>
        /// <param name="Type">The type to add the converter for, include generic typing</param>
        /// <param name="DataConverterType">The type of the data converter</param>
        /// <returns>True if added, false if not</returns>
        public static bool AddDataConverterForTypeToCache(Type Type, Type DataConverterType)
        {
            if (Type == null || DataConverterType == null)
            {
                return(false);
            }

            if (DataConverterType.IsAssignableFrom(typeof(IMDDataConverter)) &&
                !DataConverterCache.ContainsKey(Type))
            {
                IMDDataConverter converter = Activator.CreateInstance(DataConverterType) as IMDDataConverter;
                DataConverterCache.Add(Type, converter);
                return(true);
            }
            return(false);
        }
Exemplo n.º 8
0
 /// <summary>
 /// Create a data converter of the given type or get it from the buffer if it already exists
 /// </summary>
 /// <param name="ConverterType">The data converter type to create</param>
 /// <returns>The data convert for that type or null if it is not a valid data converter</returns>
 public static IMDDataConverter CreateConverterOfType(Type DataConverterType)
 {
     if (DataConverterType != null && DataConverterType.IsAssignableFrom(typeof(IMDDataConverter)))
     {
         if (!DataConverterTypeCache.ContainsKey(DataConverterType))
         {
             IMDDataConverter converter = Activator.CreateInstance(DataConverterType) as IMDDataConverter;
             if (converter.AllowCachingOfConverter())
             {
                 DataConverterTypeCache.Add(DataConverterType, converter);
             }
             else
             {
                 return(converter);
             }
         }
         return(DataConverterTypeCache[DataConverterType]);
     }
     return(null);
 }
Exemplo n.º 9
0
        public object[] ConvertForSending(object Item, bool Complete)
        {
            ExtractMembers();
            if (Item == null)
            {
                return(new object[] { null });
            }

            List <object> ObjectArray   = new List <object>();
            List <object> newLastValues = new List <object>();

            for (int i = 0; i < Members.Count; i++)
            {
                object           value     = Members[i].GetValue(Item);
                IMDDataConverter Converter = DataConverters[i];
                if (Complete || LastValues.Count == 0 || Converter.ShouldObjectBeReplicated(LastValues[i], value))
                {
                    object[] dataArray = Converter.ConvertForSending(value, Complete);
                    if (dataArray != null)
                    {
                        ObjectArray.Add($"{i}{SEPARATOR}{dataArray.Length}");
                        ObjectArray.AddRange(dataArray);
                    }
                    else
                    {
                        ObjectArray.Add($"{i}{SEPARATOR}{1}");
                        ObjectArray.Add(null);
                    }
                }
                newLastValues.Add(value);
            }

            MDLog.Trace(LOG_CAT, $"MDCustomClass converting for sending ({MDStatics.GetParametersAsString(ObjectArray.ToArray())})");

            LastValues = newLastValues;
            return(ObjectArray.ToArray());
        }
Exemplo n.º 10
0
        /// <summary>
        /// Parses the settings we know about
        /// </summary>
        /// <param name="SettingsValues">A setting array that has been run through MDReplicator.ParseParameters</param>
        protected void ParseSettings(MDReplicatedSetting[] SettingsValues)
        {
            foreach (MDReplicatedSetting setting in SettingsValues)
            {
                switch ((Settings)setting.Key)
                {
                case Settings.OnValueChangedEvent:
                    Node Node = NodeRef.GetRef() as Node;
                    OnValueChangedCallback = Node.GetType().GetMethodRecursive(setting.Value.ToString());
                    break;

                case Settings.Converter:
                    Type DataConverterType = Type.GetType(setting.Value.ToString());
                    DataConverter = MDStatics.CreateConverterOfType(DataConverterType);
                    break;
                }
            }

            // We got no data converter, get default one
            if (DataConverter == null)
            {
                DataConverter = MDStatics.GetConverterForType(Member.GetUnderlyingType());
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Converts the parameters for sending
        /// </summary>
        /// <param name="MethodInfo">The method the parameters are for</param>
        /// <param name="Parameters">The parameters</param>
        /// <returns>List of converted parameters</returns>
        public static object[] ConvertParametersForSending(MethodInfo MethodInfo, params object[] Parameters)
        {
            ParameterInfo[] CandidateParams = MethodInfo.GetParameters();

            List <object> NewParams = new List <object>();

            for (int i = 0; i < CandidateParams.Length; i++)
            {
                IMDDataConverter Converter        = GetConverterForType(CandidateParams[i].ParameterType);
                object[]         paramsForSending = new object[] { null };
                if (Parameters != null && i < Parameters.Length)
                {
                    paramsForSending = Converter.ConvertForSending(Parameters[i], true);
                    NewParams.Add($"{i}{SEPARATOR}{paramsForSending.Length}");
                }
                else
                {
                    NewParams.Add($"{i}{SEPARATOR}{1}");
                }
                NewParams.AddRange(paramsForSending);
            }

            return(NewParams.ToArray());
        }