Пример #1
0
        internal static void SendMauVariable(MauComponent holder, string mauVarName)
        {
            PropertyInfo pInfo = holder.GetType().GetProperty(mauVarName);

            if (pInfo == null)
            {
                throw new ArgumentException("Variable not found", nameof(mauVarName));
            }
            if (!HasAttribute(pInfo))
            {
                throw new ArgumentException("Variable not 'MauVariable'", nameof(mauVarName));
            }

            // Ui not register yet (RegisterComponent function not called)
            if (string.IsNullOrWhiteSpace(holder.MauId))
            {
                return;
            }

            // Get Data
            var data = new JObject
            {
                { "varName", mauVarName },
                { "varValue", MyAngularUi.ParseMauDataToFrontEnd(pInfo.PropertyType, pInfo.GetValue(holder)) }
            };

            MyAngularUi.SendRequestAsync(holder.MauId, MyAngularUi.RequestType.SetVarValue, data);
        }
Пример #2
0
        public void AddClass(string className)
        {
            var data = new JObject
            {
                { "className", className }
            };

            MyAngularUi.SendRequestAsync(MauId, MyAngularUi.RequestType.AddClass, data);
        }
Пример #3
0
        public void RemoveStyle(string styleName)
        {
            var data = new JObject
            {
                { "styleName", styleName }
            };

            MyAngularUi.SendRequestAsync(MauId, MyAngularUi.RequestType.RemoveStyle, data);
        }
Пример #4
0
        internal static Task <MyAngularUi.RequestState> SendMauEventsAsync(MauComponent holder)
        {
            var ret = new JObject
            {
                { "events", new JArray(holder.MauEvents) }
            };

            // Send response
            return(MyAngularUi.SendRequestAsync(holder.MauId, MyAngularUi.RequestType.SetEvents, ret));
        }
Пример #5
0
        internal void FireEvent(string eventName, string eventType, JObject eventData)
        {
            if (!HandledEvents.ContainsKey(eventName))
            {
                return;
            }

            string    netEventName = HandledEvents[eventName].Name;
            Type      t            = this.GetType();
            FieldInfo fi           = null;

            // Search for that event
            while (t != null)
            {
                fi = t.GetField(netEventName, BindingFlags.Instance | BindingFlags.NonPublic);
                if (fi != null)
                {
                    break;
                }
                t = t.BaseType;
            }

            if (fi == null)
            {
                return;
            }

            // Get event
            var eventDelegate = (MulticastDelegate)fi.GetValue(this);

            // There any subscriber .?
            if (eventDelegate is null)
            {
                return;
            }

            // Invoke all subscribers
            foreach (Delegate handler in eventDelegate.GetInvocationList())
            {
                // https://stackoverflow.com/questions/20350397/how-can-i-tell-if-a-c-sharp-method-is-async-await-via-reflection
                // Fire & Forget
                Task.Run(async() =>
                {
                    try
                    {
                        object[] param = { this, new MauEventInfo(eventName, eventType, eventData) };
                        await((ValueTask)handler.Method.Invoke(handler.Target, param)).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        MyAngularUi.RaiseException(ex);
                    }
                });
            }
        }
Пример #6
0
        public void SetStyle(string styleName, string styleValue, string childQuerySelector = "")
        {
            var data = new JObject
            {
                { "styleName", styleName },
                { "styleValue", styleValue },
                { "childQuerySelector", childQuerySelector },
            };

            MyAngularUi.SendRequestAsync(MauId, MyAngularUi.RequestType.SetStyle, data);
        }
Пример #7
0
        public override void OnExit(MethodExecutionArgs args)
        {
            Type retType = ((MethodInfo)args.Method).ReturnType;

            if (MethodCallType == MauMethodCallType.ExecuteFromAngular || !MyAngularUi.IsConnected)
            {
                base.OnExit(args);
                return;
            }

            // Prepare Args
            List <object> argsToSend = args.Arguments.ToList();

            for (int i = 0; i < argsToSend.Count; i++)
            {
                object param = argsToSend[i];
                if (!param.GetType().IsEnum || !MauEnumMemberAttribute.HasAttribute((Enum)param))
                {
                    continue;
                }

                argsToSend[i] = MauEnumMemberAttribute.GetValue((Enum)param);
            }

            // Send
            var holder = (MauComponent)args.Instance;
            var data   = new JObject
            {
                { "methodType", (int)MethodType },
                { "methodName", MethodName },
                { "methodArgs", JArray.FromObject(argsToSend) }
            };

            MyAngularUi.RequestState request = MyAngularUi.SendRequestAsync(holder.MauId, MyAngularUi.RequestType.CallMethod, data).GetAwaiter().GetResult();

            // Wait return
            // If its void function then just wait until execution finish
            if (retType == typeof(void))
            {
                // Wait function
                holder.GetMethodRetValue(request.RequestId);
                return;
            }

            // Wait and set return value of function
            object ret = holder.GetMethodRetValue(request.RequestId);

            if (ret is not null)
            {
                args.ReturnValue = ret /*?? Activator.CreateInstance(retType)*/;
            }
        }
Пример #8
0
        public override void OnEntry(MethodExecutionArgs args)
        {
            if (MyAngularUi.IsConnected)
            {
                var holder = (MauComponent)args.Instance;

                if (!MyAngularUi.IsComponentRegistered(holder.MauId))
                {
                    throw new Exception("Register MauComponent first. And don't call methods before register the MauComponent.");
                }
            }

            base.OnEntry(args);
        }
Пример #9
0
        internal void SetMethodRetValue(int callMethodRequestId, string methodName, JToken methodRetValueJson)
        {
            if (!HandledMethods.ContainsKey(methodName))
            {
                return;
            }

            Type   methodRetType = GetMethodReturnType(methodName);
            object methodRet     = MyAngularUi.ParseMauDataFromFrontEnd(methodRetType, methodRetValueJson);

            // Make valid enum value
            MauEnumMemberAttribute.GetValidEnumValue(methodRetType, ref methodRet);

            MyAngularUi.OrdersResponse.TryAdd(callMethodRequestId, methodRet);
        }
Пример #10
0
        protected MauComponent(string mauId)
        {
            if (MyAngularUi.IsComponentRegistered(mauId))
            {
                throw new ArgumentOutOfRangeException(nameof(mauId), "MauComponent with same mauId was registered.");
            }

            MauId          = mauId;
            HandledEvents  = new Dictionary <string, EventInfo>();
            HandledProps   = new Dictionary <string, MauPropertyHolder>();
            HandledVars    = new Dictionary <string, PropertyInfo>();
            HandledMethods = new Dictionary <string, MethodInfo>();

            Init();
        }
Пример #11
0
        internal void SetPropValue(string propName, JToken propValueJson)
        {
            if (!HandledProps.ContainsKey(propName))
            {
                return;
            }

            Type   propValType = GetPropType(propName);
            object propValue   = MyAngularUi.ParseMauDataFromFrontEnd(propValType, propValueJson);

            // Make valid enum value
            MauEnumMemberAttribute.GetValidEnumValue(propValType, ref propValue);

            // Deadlock will not happen because of 'HandledProps[propName].HandleOnSet'
            lock (HandledProps[propName])
                HandledProps[propName].DoWithoutHandling(p => p.Holder.SetValue(this, propValue));
        }
Пример #12
0
        /// <summary>
        /// Send request to angular side to send property value via <see cref="MyAngularUi.OnMessage"/>
        /// </summary>
        /// <param name="propName">Property name</param>
        internal void RequestPropValue(string propName)
        {
            if (!HandledProps.ContainsKey(propName))
            {
                return;
            }

            MauPropertyHolder mauProperty = GetMauPropHolder(propName);
            var data = new JObject
            {
                { "propName", propName },
                { "propType", (int)mauProperty.PropAttr.PropType },
                { "propStatus", (int)mauProperty.PropAttr.PropStatus }, // Needed by `SetPropHandler`
                { "propForce", mauProperty.PropAttr.ForceSet } // Needed by `SetPropHandler`
            };

            MyAngularUi.SendRequestAsync(MauId, MyAngularUi.RequestType.GetPropValue, data);
        }
Пример #13
0
        internal object CallMethod(string methodCallerName, List <object> methodArgs)
        {
            if (!HandledMethods.ContainsKey(methodCallerName))
            {
                return(null);
            }

            try
            {
                return(HandledMethods[methodCallerName].Invoke(this, methodArgs.ToArray()));
            }
            catch (Exception ex)
            {
                MyAngularUi.RaiseException(ex);
            }

            return(null);
        }
Пример #14
0
        private void Init()
        {
            // Events
            {
                EventInfo[] eventInfos = this.GetType().GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                foreach (EventInfo eventInfo in eventInfos.Where(MauEventAttribute.HasAttribute))
                {
                    var attr = eventInfo.GetCustomAttribute <MauEventAttribute>();
                    HandledEvents.Add(attr.EventName, eventInfo);
                }
            }

            // Properties
            {
                PropertyInfo[] propertyInfos = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                foreach (PropertyInfo propertyInfo in propertyInfos.Where(MauProperty.HasAttribute))
                {
                    var attr = propertyInfo.GetCustomAttribute <MauProperty>();
                    HandledProps.Add(attr.PropertyName, new MauPropertyHolder(propertyInfo, true));
                }
            }

            // Vars
            {
                PropertyInfo[] varInfos = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                foreach (PropertyInfo varInfo in varInfos.Where(MauVariable.HasAttribute))
                {
                    HandledVars.Add(varInfo.Name, varInfo);
                }
            }

            // Methods
            {
                MethodInfo[] methodInfos = this.GetType().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                foreach (MethodInfo methodInfo in methodInfos.Where(MauMethod.HasAttribute))
                {
                    var attr = methodInfo.GetCustomAttribute <MauMethod>();
                    HandledMethods.Add(attr.MethodName, methodInfo);
                }
            }

            MyAngularUi.RegisterComponent(this);
        }
Пример #15
0
 public override void OnException(MethodExecutionArgs args)
 {
     MyAngularUi.RaiseException(args.Exception);
 }
Пример #16
0
        internal static void SendMauProp(MauComponent holder, string mauPropName)
        {
            MauPropertyHolder mauPropHolder = holder.GetMauPropHolder(mauPropName);
            Type   propType  = holder.HandledProps[mauPropName].Holder.PropertyType;
            object propValue = holder.HandledProps[mauPropName].Holder.GetValue(holder);

            // bypass is for props not yet changed from .Net side
            // so it's just to not override angular prop value
            bool bypass = false;

            if (!mauPropHolder.Touched)
            {
                bypass = true;
            }
            else if (mauPropHolder.PropAttr.PropStatus == MauPropertyStatus.ReadOnly)
            {
                bypass = true;
            }
            else if (propType.IsEnum)
            {
                if (!MauEnumMemberAttribute.HasNotSetValue(propValue.GetType()))
                {
                    throw new Exception($"NotSet must to be in any MauProperty value is 'Enum', {propValue.GetType().FullName}");
                }

                if (MauEnumMemberAttribute.HasAttribute((Enum)propValue))
                {
                    propValue = MauEnumMemberAttribute.GetValue((Enum)propValue);
                }

                // If it's NotSet just ignore so the angular value will be set,
                // Angular value will be in .Net side, so the value will be correct here.
                // E.g: Color prop if it's NotSet in .Net then use and don't change
                // Angular value.
                switch (propValue)
                {
                case int:
                case long and 0:
                case string propValStr when string.IsNullOrWhiteSpace(propValStr):
                    bypass = true;

                    break;
                }
            }
            else if (propValue == null && propType == typeof(string))
            {
                // null not same as empty string
                bypass = true;
            }

            // Don't send .Net value and ask angular for it's value
            if (bypass)
            {
                holder.RequestPropValue(mauPropName);
                return;
            }

            var data = new JObject
            {
                { "propType", (int)mauPropHolder.PropAttr.PropType },
                { "propStatus", (int)mauPropHolder.PropAttr.PropStatus },
                { "propForce", mauPropHolder.PropAttr.ForceSet },
                { "propName", mauPropName },
                { "propVal", MyAngularUi.ParseMauDataToFrontEnd(propType, propValue) }
            };

            MyAngularUi.SendRequestAsync(holder.MauId, MyAngularUi.RequestType.SetPropValue, data);
        }