Beispiel #1
0
 /// <summary>
 ///     Handles the events raised by public events of the generic class and its instances
 /// </summary>
 /// <param name="instance">The instance that raised the event</param>
 /// <param name="eventName">The name of the raised event</param>
 /// <param name="isVoid">Indicates if the raised event has a return value</param>
 /// <param name="eventArgs">An array containing the parameters of the raised event</param>
 /// <returns>Returns the result of raising registered delegates</returns>
 protected virtual object RaiseEvent(object instance, string eventName, bool isVoid, object[] eventArgs)
 {
     if (instance != null)
     {
         if (Instances.ContainsKey(instance))
         {
             var instanceId = GlobalPool.GetInstanceId(instance);
             if (instanceId != null)
             {
                 return
                     (OnPushJavascript(
                          new PushJavascriptEventArgs(
                              // ReSharper disable once UseStringInterpolation
                              string.Format("{0}.__instances[\"{1}\"].raise_{2}({3});",
                                            Identification, instanceId, eventName,
                                            string.Join(", ", eventArgs.Select(JsonConvert.SerializeObject))))
                 {
                     FireAway = isVoid
                 }));
             }
         }
         return(null);
     }
     return
         (OnPushJavascript(
              // ReSharper disable once UseStringInterpolation
              new PushJavascriptEventArgs(string.Format("{0}.raise_{1}({2});", Identification, eventName,
                                                        string.Join(", ", eventArgs.Select(JsonConvert.SerializeObject))))
     {
         FireAway = isVoid
     }));
 }
Beispiel #2
0
 /// <summary>
 ///     Removes the requested instances
 /// </summary>
 /// <param name="instances">The instances to be removed from the Javascript side</param>
 /// <returns>Returns <see langword="this" /> instance to be used for other operations</returns>
 public virtual ClassBridge <T> RemoveInstance(params T[] instances)
 {
     foreach (var instance in instances.Where(instance => Instances.ContainsKey(instance)))
     {
         foreach (var variable in Instances[instance].ToArray())
         {
             AddInstance(null, variable);
         }
         if (InstancesEventsDelegates.ContainsKey(instance))
         {
             foreach (var eventDelegate in InstancesEventsDelegates[instance])
             {
                 eventDelegate.Key.RemoveEventHandler(instance, eventDelegate.Value);
             }
             InstancesEventsDelegates.Remove(instance);
         }
         Instances.Remove(instance);
         OnPushJavascript(
             new FireJavascriptEventArgs(ClassBridge.GenerateInstanceChange(Identification,
                                                                            GlobalPool.GetInstanceId(instance), true)));
     }
     return(this);
 }
Beispiel #3
0
 /// <summary>
 ///     Registers an instance of the generic type and adds it to the list of registered instances
 /// </summary>
 /// <param name="instance">The instance of the generic type to ad</param>
 /// <param name="variableName">The name of the variable that is accessible from the Javascript side</param>
 /// <returns>Returns <see langword="this" /> instance to be used for other operations</returns>
 public virtual ClassBridge <T> AddInstance(T instance, string variableName)
 {
     if (instance != null)
     {
         if (!Instances.ContainsKey(instance))
         {
             Instances.Add(instance, new List <string>());
             if (!InstancesEventsDelegates.ContainsKey(instance))
             {
                 InstancesEventsDelegates.Add(instance, new Dictionary <EventInfo, Delegate>());
             }
             foreach (
                 var info in
                 Events.Where(info => !info.GetAddMethod().IsStatic&& !info.GetRemoveMethod().IsStatic))
             {
                 var eventDelegate =
                     InstancesEventsDelegates[instance].FirstOrDefault(pair => pair.Key == info).Value;
                 if (eventDelegate == null)
                 {
                     var eventInvokerReturn = info.EventHandlerType.GetMethod("Invoke").ReturnType;
                     if ((eventInvokerReturn == typeof(void)) || (eventInvokerReturn == typeof(object)))
                     {
                         eventDelegate = ClassBridge.CreateProxyDelegateForEvent(info, instance, RaiseEvent);
                     }
                     else
                     {
                         eventDelegate = ClassBridge.CreateProxyDelegateForEvent(info, instance,
                                                                                 (o, s, arg3, arg4) =>
                                                                                 ClassBridge.NormalizeVariable(RaiseEvent(o, s, arg3, arg4), eventInvokerReturn,
                                                                                                               false));
                     }
                     InstancesEventsDelegates[instance].Add(info, eventDelegate);
                 }
                 info.AddEventHandler(instance, eventDelegate);
             }
             OnPushJavascript(
                 new FireJavascriptEventArgs(ClassBridge.GenerateInstanceChange(Identification,
                                                                                GlobalPool.GetInstanceId(instance), false)));
         }
     }
     if (!string.IsNullOrWhiteSpace(variableName))
     {
         foreach (
             var key in
             Instances.Keys.Where(key => key != instance)
             .Where(key => Instances[key].Contains(variableName))
             .ToArray())
         {
             RemoveInstance(variableName, key as T);
         }
         if (instance != null)
         {
             if (!Instances[instance].Contains(variableName))
             {
                 Instances[instance].Add(variableName);
                 OnPushJavascript(
                     new FireJavascriptEventArgs(ClassBridge.GenerateInstanceVariable(Identification,
                                                                                      GlobalPool.GetInstanceId(instance), variableName)));
             }
         }
         else
         {
             OnPushJavascript(
                 new FireJavascriptEventArgs(ClassBridge.GenerateInstanceVariable(Identification, null,
                                                                                  variableName)));
         }
     }
     return(this);
 }
Beispiel #4
0
        /// <summary>
        ///     Initialize the handler and generates the needed Javascript code
        /// </summary>
        /// <param name="bridge">The <see cref="BridgeController" /> object requesting initialization</param>
        public virtual void Initialize(BridgeController bridge)
        {
            var builder = new StringBuilder();

            builder.Append(ClassBridge.GenerateNameSpace(GenericType));
            builder.Append(ClassBridge.GenerateProxyClass(Identification, false));
            lock (Lock)
            {
                if (Fields != null)
                {
                    foreach (var field in Fields)
                    {
                        builder.Append(ClassBridge.GenerateProxyField(Identification, field));
                    }
                }
                if (Methods != null)
                {
                    if (Properties != null)
                    {
                        foreach (var property in Properties)
                        {
                            var get = property.GetGetMethod();
                            if ((get != null) && !Methods.ContainsKey(get))
                            {
                                get = null;
                            }
                            var set = property.GetSetMethod();
                            if ((set != null) && !Methods.ContainsKey(set))
                            {
                                set = null;
                            }
                            builder.Append(ClassBridge.GenerateProxyProperty(Identification, property, get, set));
                        }
                    }
                    foreach (
                        var method in
                        Methods.Where(
                            pair =>
                            (Events == null) ||
                            !Events.Any(
                                info => (pair.Key == info.GetAddMethod()) || (pair.Key == info.GetRemoveMethod()))))
                    {
                        builder.Append(ClassBridge.GenerateProxyMethod(Identification, method.Key, method.Value));
                    }
                }
                if (Events != null)
                {
                    foreach (var info in Events)
                    {
                        var isStatic = info.GetAddMethod().IsStatic || info.GetRemoveMethod().IsStatic;
                        builder.Append(ClassBridge.GenerateProxyField(Identification, info.Name, isStatic, true,
                                                                      new object[0]));
                        builder.Append(ClassBridge.GenerateProxyEventMethods(Identification, info, isStatic));
                    }
                }
            }
            foreach (var instance in Instances.Where(pair => pair.Key != null).ToArray())
            {
                var instanceId = GlobalPool.GetInstanceId(instance.Key);
                if (instanceId != null)
                {
                    builder.AppendLine(ClassBridge.GenerateInstanceChange(Identification, instanceId, false));
                    foreach (var variableName in instance.Value.Where(s => !string.IsNullOrWhiteSpace(s)))
                    {
                        builder.AppendLine(ClassBridge.GenerateInstanceVariable(Identification, instanceId, variableName));
                    }
                }
            }
            OnPushJavascript(new FireJavascriptEventArgs(builder.ToString(), bridge));
            lock (Lock)
            {
                if (SubEnumerations != null)
                {
                    foreach (var subEnum in SubEnumerations)
                    {
                        subEnum.Initialize(bridge);
                    }
                }
                if (SubClasses != null)
                {
                    foreach (var subClass in SubClasses)
                    {
                        subClass.Initialize(bridge);
                    }
                }
            }
        }
Beispiel #5
0
        /// <summary>
        ///     Handles the passed request and returns the result
        /// </summary>
        /// <param name="method">The method name to handle</param>
        /// <param name="parameters">The method parameters</param>
        /// <param name="hasResult">A boolean value indicting if the handling process resulted in a value</param>
        /// <returns>Returns the value that created from the handling of the request</returns>
        public virtual object InterceptRequest(string method, Dictionary <string, object> parameters, out bool hasResult)
        {
            hasResult = false;
            MethodInfo      methodInfo       = null;
            ConstructorInfo constructorInfo  = null;
            var             methodParameters = new object[0];
            FieldInfo       fieldInfo        = null;
            object          fieldValue       = null;
            object          classInstance    = null;
            var             methodParts      = method.Split('/');

            if (methodParts.Length > 1)
            {
                method        = string.Join("/", methodParts, 1, methodParts.Length - 1);
                classInstance =
                    Instances.FirstOrDefault(
                        instance => GlobalPool.GetInstanceId(instance.Key) == methodParts[0]).Key;
            }
            lock (Lock)
            {
                if (string.IsNullOrWhiteSpace(method))
                {
                    if ((Constructors != null) && parameters.ContainsKey("arguments"))
                    {
                        var constructorParameters = parameters["arguments"] as JArray;
                        foreach (var pair in Constructors)
                        {
                            var matchedArguments = 0;
                            try
                            {
                                var param = new List <object>();
                                for (var i = 0; i < pair.Value.Length; i++)
                                {
                                    if ((constructorParameters != null) && (i < constructorParameters.Count))
                                    {
                                        param.Add(ClassBridge.NormalizeVariable(constructorParameters.ToArray()[i],
                                                                                pair.Value[i].ParameterType, true));
                                        matchedArguments++;
                                    }
                                    else
                                    {
                                        if (pair.Value[i].IsOptional)
                                        {
                                            param.Add(pair.Value[i].DefaultValue);
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                                if ((param.Count != pair.Value.Length) ||
                                    (matchedArguments != (constructorParameters?.Count ?? 0)))
                                {
                                    continue;
                                }
                                methodParameters = param.ToArray();
                            }
                            catch (InvalidCastException)
                            {
                                // ignore
                            }
                            constructorInfo = pair.Key;
                        }
                    }
                }
                else
                {
                    if (Methods != null)
                    {
                        foreach (var pair in Methods.Where(pair => pair.Key.Name.Equals(method)))
                        {
                            var matchedArguments = 0;
                            try
                            {
                                var param = new List <object>();
                                for (var i = 0; i < pair.Value.Length; i++)
                                {
                                    if (i < parameters.Count)
                                    {
                                        if (pair.Value[i].Name == parameters.Keys.ToArray()[i])
                                        {
                                            param.Add(ClassBridge.NormalizeVariable(parameters.Values.ToArray()[i],
                                                                                    pair.Value[i].ParameterType, true));
                                            matchedArguments++;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (pair.Value[i].IsOptional)
                                        {
                                            param.Add(pair.Value[i].DefaultValue);
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                                if ((param.Count != pair.Value.Length) || (matchedArguments != parameters.Count))
                                {
                                    continue;
                                }
                                methodParameters = param.ToArray();
                            }
                            catch (InvalidCastException)
                            {
                                // ignore
                            }
                            methodInfo = pair.Key;
                        }
                    }
                    if ((methodInfo == null) && (Fields != null))
                    {
                        foreach (
                            var field in
                            Fields.Where(info => info.Name.Equals(method, StringComparison.OrdinalIgnoreCase)))
                        {
                            if (parameters.Keys.Contains("value"))
                            {
                                try
                                {
                                    fieldValue = ClassBridge.NormalizeVariable(parameters["value"], field.FieldType,
                                                                               true);
                                }
                                catch (InvalidCastException)
                                {
                                    // ignore
                                }
                            }
                            fieldInfo = field;
                        }
                    }
                }
            }
            if (constructorInfo != null)
            {
                var newObject = constructorInfo.Invoke(methodParameters) as T;
                if (newObject != null)
                {
                    AddInstance(newObject);
                    var instanceId = GlobalPool.GetInstanceId(newObject);
                    if (!string.IsNullOrWhiteSpace(instanceId))
                    {
                        hasResult = true;
                        return(instanceId);
                    }
                }
                return(null);
            }
            if (methodInfo != null)
            {
                if (methodInfo.ReturnType != typeof(void))
                {
                    hasResult = true;
                    return(methodInfo.Invoke(classInstance, methodParameters.ToArray()));
                }
                // Let's not block the UI/Javascript thread if there is no result for the requested method
                Task.Factory.StartNew(() => methodInfo.Invoke(classInstance, methodParameters.ToArray()));
                return(null);
            }
            if (fieldInfo != null)
            {
                if (fieldValue != null)
                {
                    fieldInfo.SetValue(classInstance, fieldValue);
                    return(null);
                }
                hasResult = true;
                return(fieldInfo.GetValue(classInstance));
            }
            return(null);
        }
Beispiel #6
0
        /// <summary>
        ///     Initialize the handler and generates the needed Javascript code
        /// </summary>
        /// <param name="bridge">The <see cref="BridgeController" /> object requesting initialization</param>
        public virtual void Initialize(BridgeController bridge)
        {
            var identification = typeof(ProxyClass).FullName.Replace('+', '.');
            var builder        = new StringBuilder();

            HybridMessagingBridge.Initialize(bridge);
            builder.Append(ClassBridge.GenerateProxyField(identification, "__subscriptions", false, true,
                                                          new Dictionary <string, object>()));
            builder.Append(ClassBridge.GenerateProxyMethod(identification, "Subscribe",
                                                           new[]
            {
                new ClassBridge.InternalParameterInfo("messageString"),
                new ClassBridge.InternalParameterInfo("callback")
            }, @"
    var_messageString = var_messageString.toLowerCase().trim();
    if (this.__subscriptions[var_messageString] === undefined) {
        this.__subscriptions[var_messageString] = [];
    }
    var index = this.__subscriptions[var_messageString].indexOf(var_callback);
    if (index < 0) {
        this.__subscriptions[var_messageString].push(var_callback);
        return true;
    }
    return false;", false));
            builder.Append(ClassBridge.GenerateProxyMethod(identification, "UnSubscribe",
                                                           new[]
            {
                new ClassBridge.InternalParameterInfo("messageString"),
                new ClassBridge.InternalParameterInfo("callback")
            }, @"
    var_messageString = var_messageString.toLowerCase().trim();
    if (this.__subscriptions[var_messageString] === undefined) {
        return false;
    }
    var index = this.__subscriptions[var_messageString].indexOf(var_callback);
    if (index < 0) {
        return false;
    }
    this.__subscriptions[var_messageString].splice(index, 1);
    if (this.__subscriptions[var_messageString].length < 1) {
        this.__subscriptions[var_messageString] = undefined;
    }
    return true;", false));
            builder.Append(ClassBridge.GenerateProxyMethod(identification, "__raise",
                                                           new[]
            {
                new ClassBridge.InternalParameterInfo("messageString"),
                new ClassBridge.InternalParameterInfo("arguments", true, null)
            }, @"
    var result = undefined;
    var_messageString = var_messageString.toLowerCase().trim();
    for (var messageString in this.__subscriptions) {
        if (!messageString || !var_messageString || messageString == var_messageString) {
            for (index = 0; index < this.__subscriptions[messageString].length; ++index) {
                result = this.__subscriptions[messageString][index].apply(this, [ var_arguments ]);
            }
        }
    }
    return result;", false));
            var instanceId = GlobalPool.GetInstanceId(HybridMessagingProxy);

            if (!string.IsNullOrEmpty(instanceId))
            {
                builder.AppendFormat("\r\n{0}.__instances[\"{1}\"].add_NewMessage({0}.__instances[\"{1}\"].__raise);",
                                     identification, instanceId);
            }
            OnPushJavascript(this, new FireJavascriptEventArgs(builder.ToString()));
        }