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); }
public void AddClass(string className) { var data = new JObject { { "className", className } }; MyAngularUi.SendRequestAsync(MauId, MyAngularUi.RequestType.AddClass, data); }
public void RemoveStyle(string styleName) { var data = new JObject { { "styleName", styleName } }; MyAngularUi.SendRequestAsync(MauId, MyAngularUi.RequestType.RemoveStyle, data); }
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)); }
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); } }); } }
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); }
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)*/; } }
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); }
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); }
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(); }
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)); }
/// <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); }
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); }
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); }
public override void OnException(MethodExecutionArgs args) { MyAngularUi.RaiseException(args.Exception); }
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); }