Beispiel #1
0
        //------------------------------------------------------------------------------------------------------------------------
        public static bool Convert(object value, Type ToType, out object result)
        {
            result = null;
            //try convert
            try
            {
                //get value type
                var fromType = value == null ? typeof(object) : value.GetType();

                //nothing to do?
                if (fromType == ToType)
                {
                    result = value;
                    return(true);
                }

                //are both single values?
                if ((!fromType.IsArray && !ToType.IsArray) || (value == null))
                {
                    if (SingleValueConvert(value, ToType, out result))
                    {
                        return(true);
                    }
                    else if (value is string && value != null && (value as string).Contains(ArraySeparator))
                    {
                        //we may be able to convert this string if we split it by the separator and pick the first element
                        var elems = (value as string).Split(ArraySeparator);
                        return(SingleValueConvert(elems[0], ToType, out result));
                    }
                    else
                    {
                        return(false);
                    }
                }

                //get parameters
                var src_arr       = (value as Array);
                var src_length    = src_arr == null ? 0 : src_arr.Length;
                var ToTypeElement = ToType.IsArray ? ToType.GetElementType() : ToType;

                //zero length array?
                if (fromType.IsArray && src_length == 0)
                {
                    //create a zero-length result array
                    result = Array.CreateInstance(ToTypeElement, 0);
                    return(true);
                }

                //is source only an array?
                if (fromType.IsArray && !ToType.IsArray)
                {
                    //if target is string then we can join them up into a nice string, else just pick the first value
                    if (ToType == typeof(string))
                    {
                        //build result string by joining up elements
                        string res = "";
                        for (int n = 0; n < src_length; n++)
                        {
                            object v;
                            if (SingleValueConvert(src_arr.GetValue(n), ToTypeElement, out v) == false)
                            {
                                return(false);
                            }
                            res += v.ToStringInvariant() + ArraySeparator;
                        }
                        result = res;
                        return(true);
                    }
                    else
                    {
                        return(SingleValueConvert(src_arr.GetValue(0), ToType, out result));
                    }
                }
                //is only destination an array?
                else if (!fromType.IsArray && ToType.IsArray)
                {
                    //if source is string try to split it into elements
                    if (fromType == typeof(string))
                    {
                        //split using separator
                        var elems = (value as string).Split(ArraySeparator);
                        //create result array
                        var dst_arr = Array.CreateInstance(ToTypeElement, elems.Length);
                        for (int n = 0; n < elems.Length; n++)
                        {
                            object v;
                            if (SingleValueConvert(elems[n], ToTypeElement, out v) == false)
                            {
                                return(false);
                            }
                            dst_arr.SetValue(v, n);
                        }
                        result = dst_arr;
                        return(true);
                    }
                    else
                    {
                        //create a zero-length result array
                        var    dst_arr = Array.CreateInstance(ToTypeElement, 1);
                        object v;
                        if (SingleValueConvert(value, ToTypeElement, out v) == false)
                        {
                            return(false);
                        }
                        dst_arr.SetValue(v, 0);
                        result = dst_arr;
                        return(true);
                    }
                }
                //are both arrays?
                else if (fromType.IsArray && ToType.IsArray)
                {
                    //create result array
                    var dst_arr = Array.CreateInstance(ToTypeElement, src_length);
                    //fill with a per-element convert
                    for (int n = 0; n < src_length; n++)
                    {
                        object v;
                        if (SingleValueConvert(src_arr.GetValue(n), ToTypeElement, out v) == false)
                        {
                            return(false);
                        }
                        dst_arr.SetValue(v, n);
                    }
                    result = dst_arr;
                    return(true);
                }
                else
                {
                    DebugEx.Assert("Should not be here (Convert from=" + fromType + ",  to=" + ToType + ")");
                    return(false);
                }
            }
            catch { result = null; return(false); } //pokemon exception handler
        }
Beispiel #2
0
        //------------------------------------------------------------------------------------------------------------------------
        public static Type GetType(string name, bool DeFriendlify = true)
        {
            //sanity check
            if (string.IsNullOrWhiteSpace(name))
            {
                return(null);
            }

            //find type
            Type result = null;

            lock (cache)
                if (cache.TryGetValue(name, out result) == false)
                {
                    try
                    {
                        //resolve type
                        result = Type.GetType(name);

                        //If null go for fallback mechanisms
                        if (result == null)
                        {
                            //This is now in fallback. do not keep lock since what follows are expensive operations
                            Monitor.Exit(cache);
                            try
                            {
                                //if not found and not fully qualified search in all assemblies
                                if (result == null)
                                {
                                    string strippedName;
                                    //process name (strip assembly and recersivly extract generic types)
                                    if (name.Contains('['))
                                    {
                                        var lefovers = name.RightOf("[");
                                        var generics = new List <string>();
                                        int i        = 0;
                                        int start    = 0;
                                        for (int n = 0; n < lefovers.Length; n++)
                                        {
                                            var c = lefovers[n];
                                            if (c == '[')
                                            {
                                                if (i == 0)
                                                {
                                                    start = n + 1;
                                                }
                                                i++;
                                            }
                                            else if (c == ']')
                                            {
                                                i--;
                                                if (i == 0)
                                                {
                                                    generics.Add(lefovers.Substring(start, n - start));
                                                    start = n + 1;
                                                }
                                            }
                                        }
                                        //get types for each generic
                                        var genericsTypes = new List <Type>();
                                        foreach (var entry in generics)
                                        {
                                            var gt = GetType(entry);
                                            if (gt == null)
                                            {
                                                return(null);
                                            }
                                            genericsTypes.Add(gt);
                                        }
                                        //process found generics recursively
                                        strippedName = name.LeftOf("`") + "`" + generics.Count + "[" + string.Join(", ", genericsTypes.Select(t => "[" + t.AssemblyQualifiedName + "]")) + "]";
                                        //try a fast re-check of processed name
                                        result = Type.GetType(strippedName);
                                    }
                                    else
                                    {
                                        strippedName = name.LeftOf(",");
                                    }

                                    //search assemblies
                                    if (result == null)
                                    {
                                        foreach (var entry in GetAssemblies())
                                        {
                                            result = entry.GetType(strippedName);
                                            if (result != null)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }

                                //Try to find friendly named types
                                if (result == null && DeFriendlify)
                                {
                                    try { result = Type.GetType(Extensions.DeFriendlifyName(name)); }
                                    catch (Exception ex) { DebugEx.Assert(ex, "DeFriendlifyName failed"); }
                                }
                            }
                            catch (Exception ex) { DebugEx.Assert(ex, "Caught unhandled exception during type resolve"); }
                            finally { Monitor.Enter(cache); } //re-aquire lock before continuing
                        }
                    }
                    catch (Exception ex) { DebugEx.Assert(ex, "Unhandled excpetion while trying to resolve type"); }

                    //cache it
                    cache.ForceAdd(name, result);
                }

            //done and done
            return(result);
        }
Beispiel #3
0
        //------------------------------------------------------------------------------------------------------------------------
        public static bool SingleValueConvert(object value, Type toType, out object result)
        {
            result = null;
            //try convert
            try
            {
                //if nullable extract wrapped type
#if NETFX
                var isNullable = toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(Nullable <>);
#elif UNIVERSAL
                var isNullable = toType.GetTypeInfo().IsGenericType&& toType.GetGenericTypeDefinition() == typeof(Nullable <>);
#endif
                if (isNullable)
                {
                    toType = toType.GenericTypeArguments[0];
                }

                try
                {
                    //get value type
                    var fromType        = value == null ? typeof(object) : value.GetType();
                    var ToTypeIsInteger = toType.IsInteger();
                    var ToTypeIsDecimal = toType.IsDecimal();
                    var ToTypeIsNumber  = ToTypeIsInteger || ToTypeIsDecimal;

                    //universal helpers
#if NETFX
                    var ToTypeInfo   = toType;
                    var FromTypeInfo = fromType;
#elif UNIVERSAL
                    var ToTypeInfo   = toType.GetTypeInfo();
                    var FromTypeInfo = fromType.GetTypeInfo();
#endif

                    //nothing to do?
                    if (fromType == toType)
                    {
                        result = value;
                        return(true);
                    }

                    //check for enums
                    if (ToTypeInfo.IsEnum && fromType != typeof(string) && toType.GetEnumUnderlyingType() != fromType)
                    {
                        //try to convert to target type
                        object convValue = null;
                        if (Convert(value, toType.GetEnumUnderlyingType(), out convValue))
                        {
                            value    = convValue?.ToStringInvariant();
                            fromType = typeof(string);
#if UNIVERSAL
                            FromTypeInfo = fromType.GetTypeInfo();
#endif
                        }
                    }

                    //check easy stuff
                    if (value != null && ToTypeInfo.IsAssignableFrom(FromTypeInfo))
                    {
                        result = value;
                        return(true);
                    }
#if NETFX
                    else if (value is string && typeof(IFillFromString).IsAssignableFrom(toType))
#elif UNIVERSAL
                    else if (value is string && typeof(IFillFromString).GetTypeInfo().IsAssignableFrom(ToTypeInfo))
#endif
                    {
                        var box = Activator.CreateInstance(toType) as IFillFromString;
                        box.FillFromString((string)value);
                        result = box;
                        return(true);
                    }

                    //special string cases
                    if (value is string)
                    {
                        var str = value as string;
                        if (str != null)
                        {
                            str = str.ToLowerInvariant().Trim();
                        }

                        //string->boolean cases
                        if (toType == typeof(Boolean))
                        {
                            double fv;
                            Int64  iv;
                            if (str.TryParse(out fv))
                            {
                                result = fv != 0;
                                return(true);
                            }
                            else if (str.TryParse(out iv))
                            {
                                result = iv != 0;
                                return(true);
                            }
                        }

                        //special cases for string
                        if (!ToTypeInfo.IsEnum)
                        {
                            if (string.IsNullOrEmpty(str) && ToTypeInfo.IsPrimitive && toType != typeof(string))
                            {
                                fromType = typeof(bool);
                                value    = false;
                            }
                            else if (str == "true" || str == "false")
                            {
                                fromType = typeof(bool);
                                value    = str == "true" ? true : false;
                            }
                            else if (str == "yes" || str == "no")
                            {
                                fromType = typeof(bool);
                                value    = str == "yes" ? true : false;
                            }
                            else if (str == "on" || str == "off")
                            {
                                fromType = typeof(bool);
                                value    = str == "on" ? true : false;
                            }
                            else if (str == "enabled" || str == "disabled")
                            {
                                fromType = typeof(bool);
                                value    = str == "enabled" ? true : false;
                            }
                            else if (str == "enable" || str == "disable")
                            {
                                fromType = typeof(bool);
                                value    = str == "enable" ? true : false;
                            }
                            else if (str == "active" || str == "inactive")
                            {
                                fromType = typeof(bool);
                                value    = str == "active" ? true : false;
                            }
                            else if (str == "activate" || str == "deactivate")
                            {
                                fromType = typeof(bool);
                                value    = str == "activate" ? true : false;
                            }
                            else if (str == "activated" || str == "deactivated")
                            {
                                fromType = typeof(bool);
                                value    = str == "activated" ? true : false;
                            }
                        }

                        //nothing to do?
                        if (fromType == toType)
                        {
                            result = value;
                            return(true);
                        }

                        //number converter
                        if (ToTypeIsNumber)
                        {
                            double dv;
                            if (str.TryParse(out dv))
                            {
                                value    = dv;
                                fromType = typeof(double);
                            }
                        }
                    }

                    //custom converters
                    if (fromType == typeof(Boolean))
                    {
                        if (toType == typeof(float))
                        {
                            result = (bool)value ? 1f : 0f;
                            return(true);
                        }
                        else if (toType == typeof(byte))
                        {
                            result = (bool)value ? (byte)1 : (byte)0;
                            return(true);
                        }
                        else if (toType == typeof(sbyte))
                        {
                            result = (bool)value ? (sbyte)1 : (sbyte)0;
                            return(true);
                        }
                        else if (toType == typeof(double))
                        {
                            result = (bool)value ? 1d : 0d;
                            return(true);
                        }
                        else if (toType == typeof(decimal))
                        {
                            result = (bool)value ? (decimal)1 : (decimal)0;
                            return(true);
                        }
                        else if (toType == typeof(Int16))
                        {
                            result = (bool)value ? (Int16)1 : (Int16)0;
                            return(true);
                        }
                        else if (toType == typeof(Int32))
                        {
                            result = (bool)value ? (Int32)1 : (Int32)0;
                            return(true);
                        }
                        else if (toType == typeof(Int64))
                        {
                            result = (bool)value ? (Int64)1 : (Int64)0;
                            return(true);
                        }
                        else if (toType == typeof(UInt16))
                        {
                            result = (bool)value ? (UInt16)1 : (UInt16)0;
                            return(true);
                        }
                        else if (toType == typeof(UInt32))
                        {
                            result = (bool)value ? (UInt32)1 : (UInt32)0;
                            return(true);
                        }
                        else if (toType == typeof(UInt64))
                        {
                            result = (bool)value ? (UInt64)1 : (UInt64)0;
                            return(true);
                        }
                        else if (toType == typeof(string))
                        {
                            result = (bool)value ? "True" : "False";
                            return(true);
                        }
                        else
                        {
                            result = null;
                            return(false);
                        }
                    }

                    //if input is null then give null back
                    if (value == null)
                    {
                        result = ToTypeInfo.IsClass ? null : Activator.CreateInstance(toType);
                        return(true);
                    }

#if NETFX
                    //try forward convert
                    {
                        var convValue = TypeDescriptor.GetConverter(fromType);
                        if (convValue.CanConvertTo(toType))
                        {
                            result = convValue.ConvertTo(null, System.Globalization.CultureInfo.InvariantCulture, value, toType);

                            //special object->string case (use json if objects ToString is the default typename)
                            if (fromType.IsClass && toType == typeof(string) && (result as string) == fromType.FullName)
                            {
#if NEWTONSOFT
                                result = value.ToJSON();
#endif
                            }

                            return(true);
                        }
                    }

                    //try the other way around
                    {
                        var convType = TypeDescriptor.GetConverter(toType);
                        if (convType.CanConvertFrom(fromType))
                        {
                            //try the other way around
                            result = convType.ConvertFrom(null, System.Globalization.CultureInfo.InvariantCulture, value);
                            return(true);
                        }
                    }
#endif

                    //last attempt
                    try
                    {
                        result = System.Convert.ChangeType(value, toType);
                        //special object->string case (use json if objects ToString is the default typename)
                        if (FromTypeInfo.IsClass && toType == typeof(string) && (result as string) == fromType.FullName)
                        {
#if NEWTONSOFT
                            result = value.ToJSON();
#endif
                        }

                        return(true);
                    }
                    catch { }

                    //string<->object special case using json
                    if (fromType == typeof(string) && ToTypeInfo.IsClass)
                    {
#if NEWTONSOFT
                        try
                        {
                            result = (value as string).FromJSON(toType);
                            if (result != null && result.GetType() == toType)
                            {
                                return(true);
                            }
                            else
                            {
                                result = null;
                            }
                        }
                        catch { }
#endif
                    }


                    //failed
                    result = null;
                    return(false);
                }
                finally
                {
                    //re-wrap with nullable (not sure if this is needed, because from debugger it will not do it anyway and c# will handle it internally.. but what-the-heck)
                    if (isNullable)
                    {
                        var nullableType = typeof(Nullable <>).MakeGenericType(toType);
                        try { result = Activator.CreateInstance(nullableType, new object[] { result }); } catch { }
                    }
                }
            }
            catch (Exception ex) { DebugEx.TraceLog(ex, "Convert Error"); result = null; return(false); } //pokemon exception handler
        }
Beispiel #4
0
        public static void StartTest()
        {
            var       evr        = new YEventRouter();
            const int iterations = 1000000;
            //TimeSpan total_derived = TimeSpan.Zero;
            //TimeSpan total_direct = TimeSpan.Zero;

            Stopwatch watch = new Stopwatch();
            int       g     = 0;

            //add 2 event handlers
            DebugEx.TraceLog("Adding handler1a/b and handler2");
            evr.AddEventHandler <Payload1>((s, i, e) =>
            {
                g++;
            }, 5);
            //evr.AddEventHandler<Payload1>(Handler1b);
            evr.AddEventHandler <Payload2>((s, i, e) =>
            {
                g++;
            }, 6);

            //evr.AddEventHandler<Payload2>((s, i, e) =>
            //    {
            //        DebugEx.TraceLog("HANDLER2 " + e + " called");

            //        //create new handler for this Type route (altering the internal hashset)
            //        evr.AddEventHandler<Payload2>((x, y, z) => DebugEx.TraceLog("HANDLER2 created from within handler"));

            //        //create new handler for a new Type route
            //        evr.AddEventHandler<Payload2_3>((x, y, z) => DebugEx.TraceLog("HANDLER2_3 created from within handler"));
            //    });
            //evr.AddEventHandler<Payload2_2>((s, i, e) => DebugEx.TraceLog("DERIVED HANDLER2_2 " + e + " called"));

            //scale cpu clock up
            for (int i = 0; i < iterations; i++)
            {
                evr.TriggerEvent <Payload2_2>(null, new Payload2_2()
                {
                    b = "Payload2_2"
                });
            }

            //trigger events
            DebugEx.TraceLog("Trigger events");
            watch.Start();
            for (int i = 0; i < iterations; i++)
            {
                evr.TriggerEvent <Payload2_2>(null, new Payload2_2()
                {
                    b = "Payload2_2"
                });
            }
            watch.Stop();
            var total_derived = watch.ElapsedMilliseconds;

            DebugEx.TraceLog("Total time for " + g + " derived iterations = " + total_derived);

            g = 0;
            watch.Restart();
            for (int i = 0; i < iterations; i++)
            {
                evr.TriggerEvent <Payload2>(null, new Payload2()
                {
                    b = "Payload1"
                });
            }

            watch.Stop();
            var total_direct = watch.ElapsedMilliseconds;

            DebugEx.TraceLog("Total time for " + g + " direct iterations = " + total_direct);


            evr.TriggerEvent <Payload2>(null, new Payload2()
            {
                b = "Payload2"
            });
            evr.TriggerEvent <Payload1>(null, new Payload1()
            {
                a = "Payload1", c = "newtest"
            });
            Task.Delay(3000).Wait();
            evr.TriggerEvent <Payload1>(null, new Payload1()
            {
                a = "Payload1", c = "newtest"
            });
            evr.TriggerEvent <Payload2>(null, new Payload2()
            {
                b = "Payload2"
            });

            //remove handler1b
            DebugEx.TraceLog("removing handler1b");
            evr.RemoveEventHandler <Payload1>(Handler1b);

            //trigger same events
            DebugEx.TraceLog("Trigger events");
            evr.TriggerEvent <Payload1>(null, new Payload1()
            {
                a = "Payload1", c = "newtest"
            });
            evr.TriggerEvent <Payload2>(null, new Payload2()
            {
                b = "Payload2"
            });
            Task.Delay(3000).Wait();
            evr.TriggerEvent <Payload1>(null, new Payload1()
            {
                a = "Payload1", c = "newtest"
            });
            Task.Delay(3000).Wait();
            evr.TriggerEvent <Payload1>(null, new Payload1()
            {
                a = "Payload1", c = "newtest"
            });
            evr.TriggerEvent <Payload2>(null, new Payload2()
            {
                b = "Payload2"
            });

            DebugEx.TraceLog("END");
        }
Beispiel #5
0
 public static void Handler1b(object sender, YEventRouter.EvInfo info, object ev)
 {
     DebugEx.TraceLog("HANDLER1b " + ev + " called");
 }
Beispiel #6
0
        //--------------------------------------------------------------------------------------------------------------------------------------
        private void _ExecuteHandler <T>(object sender, T ev)
        {
            //declares
            SortedSetTS <EvHandler> allRoutesForType = null;
            var evType = typeof(T);

            //null check
            if (ev == null)
            {
                return;
            }

            //create event info
            var evInfo = new EvInfo()
            {
                priv           = null,
                IsDerivedMatch = false,
            };

            //Execute
            var executedCallbacks = new HashSet <object>();

            while (evType != null && evType != typeof(object))
            {
                //get routes for type
                allRoutesForType = _ActiveRoutes.TryGetOrDefault(evType);
                if (allRoutesForType != null)
                {
                    //Broadcast event
                    foreach (var evhandle in allRoutesForType)
                    {
                        if (!evInfo.IsDerivedMatch || evhandle.ReceiveDerivedTypeEvents)
                        {
                            try
                            {
                                //check that we haven't already run this callback
                                if (!executedCallbacks.Contains(evhandle.Cb))
                                {
                                    //use Dynamic callback if derived type; use known type otherwise
                                    if (evInfo.IsDerivedMatch)
                                    {
                                        ((dynamic)evhandle.Cb)(sender, evInfo, ev);
                                    }
                                    else
                                    {
                                        ((EventCb <T>)evhandle.Cb)(sender, evInfo, ev);
                                    }

                                    //add to hashset so that it's not executed again
                                    executedCallbacks.Add(evhandle.Cb);
                                }
                            }
                            catch (Exception ex)
                            {
                                DebugEx.TraceErrorException(ex);
                            }
                        }
                    }
                }

                //now moving up the inheritance tree (toward object)
#if NETFX
                evType = evType.BaseType;
#elif UNIVERSAL
                evType = evType.GetTypeInfo().BaseType;
#endif
                evInfo.IsDerivedMatch = true;
            }
        }
Beispiel #7
0
        //------------------------------------------------------------------------------------------------------------------------
        #endregion


        #region Functions
        //------------------------------------------------------------------------------------------------------------------------
        void HeartBeatEntryPoint()
        {
            try
            {
                //declares
                TimeSpan?timeout = null;
                //spin
                while (isRunning)
                {
                    lock (locker)
                    {
                        //check pending requests.. if none the sleep the good sleep
                        if (RequestQueue.Count == 0)
                        {
                            timeout = TimeSpan.MaxValue; //infinite
                        }
                        else
                        {
                            //get first pending request (has smallest wake timestamp)
                            var req = RequestQueue.First();
                            //get remaining time
                            var rem = req.WakeupTimestamp - DateTime.UtcNow;
                            if (rem.TotalMilliseconds > 0.5d)
                            {
                                timeout = rem;
                            }
                            else
                            {
                                //consume event
                                RequestQueue.Dequeue();
                                RequestLookup.Remove(req.RequestID);
                                //callback
                                if (req.AsyncCallback)
                                {
                                    Task.Run(() =>
                                    {
                                        try
                                        {
                                            //fire event
                                            if (req.Callback != null)
                                            {
                                                req.Callback(req.UserData);
                                            }
                                            else if (req.WeakCallback != null)
                                            {
                                                req.WeakCallback.Invoke(req.UserData);
                                            }
                                            else
                                            {
                                                DebugEx.Assert("FutureCallbackQueue reqId:" + req.RequestID + " has no callback to invoke");
                                            }
                                        }
                                        catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception in callback caught by FutureCallbackQueue"); }
                                    });
                                }
                                else
                                {
                                    //exit lock to fire event
                                    Monitor.Exit(locker);
                                    try
                                    {
                                        //fire event
                                        if (req.Callback != null)
                                        {
                                            req.Callback(req.UserData);
                                        }
                                        else if (req.WeakCallback != null)
                                        {
                                            req.WeakCallback.Invoke(req.UserData);
                                        }
                                        else
                                        {
                                            DebugEx.Assert("FutureCallbackQueue reqId:" + req.RequestID + " has no callback to invoke");
                                        }
                                    }
                                    catch (Exception ex) { DebugEx.Assert(ex, "Unhandled exception in callback caught by FutureCallbackQueue"); }
                                    finally { Monitor.Enter(locker); }
                                }
                                //no timeout..keep spinning
                                timeout = null;
                            }
                        }

                        //sleep/wait manager
                        if (timeout.HasValue)
                        {
                            int _clampedTimeout = (int)timeout.Value.TotalMilliseconds.ClampCeil(MaxSleepMilisecondsD);
                            Monitor.Wait(locker, _clampedTimeout);
                            if (!isRunning)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex) { DebugEx.TraceError(ex, "FutureCallbackQueue heartbeat failed"); }
        }