Beispiel #1
0
 public HostOptionsAttribute(FieldAccessOption fieldAccessOption   = FieldAccessOption.Auto, PropertyAccessOption propertyAccessOption = PropertyAccessOption.Auto,
                             MethodAccessOption methodAccessOption = MethodAccessOption.Auto)
 {
     FieldAccessOption    = fieldAccessOption;
     PropertyAccessOption = propertyAccessOption;
     MethodAccessOption   = methodAccessOption;
 }
Beispiel #2
0
        public BSMLParserParams Parse(XmlNode parentNode, GameObject parent, object host = null)
        {
            BSMLParserParams parserParams = new BSMLParserParams();

            parserParams.host = host;
            FieldAccessOption    fieldAccessOptions    = FieldAccessOption.Auto;
            PropertyAccessOption propertyAccessOptions = PropertyAccessOption.Auto;
            MethodAccessOption   methodAccessOptions   = MethodAccessOption.Auto;
            HostOptionsAttribute hostOptions           = host?.GetType().GetCustomAttribute <HostOptionsAttribute>();

            if (hostOptions != null)
            {
                fieldAccessOptions    = hostOptions.FieldAccessOption;
                propertyAccessOptions = hostOptions.PropertyAccessOption;
                methodAccessOptions   = hostOptions.MethodAccessOption;
            }
            if (host != null)
            {
                foreach (MethodInfo methodInfo in host.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    UIAction uiaction     = methodInfo.GetCustomAttributes(typeof(UIAction), true).FirstOrDefault() as UIAction;
                    string   methodName   = methodInfo.Name;
                    string   uiActionName = null;
                    if (uiaction != null)
                    {
                        uiActionName = uiaction.id;
                        if (parserParams.actions.TryGetValue(uiActionName, out BSMLAction existing))
                        {
                            if (existing.FromUIAction)
                            {
                                throw new InvalidOperationException($"UIAction '{uiActionName}' is already used by member '{existing.MemberName}'.");
                            }
                            existing.methodInfo   = methodInfo;
                            existing.FromUIAction = true;
                        }
                        else
                        {
                            parserParams.actions.Add(uiActionName, new BSMLAction(host, methodInfo, true));
                        }
                        if (methodAccessOptions == MethodAccessOption.AllowBoth && methodName != uiActionName)
                        {
                            if (!parserParams.actions.ContainsKey(methodName))
                            {
                                parserParams.actions.Add(methodName, new BSMLAction(host, methodInfo, false));
                            }
                        }
                    }
                    else if (methodAccessOptions != MethodAccessOption.OptIn)
                    {
                        if (!parserParams.actions.ContainsKey(methodName))
                        {
                            parserParams.actions.Add(methodName, new BSMLAction(host, methodInfo));
                        }
                    }
                }

                foreach (FieldInfo fieldInfo in host.GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    UIValue uivalue     = fieldInfo.GetCustomAttributes(typeof(UIValue), true).FirstOrDefault() as UIValue;
                    string  fieldName   = fieldInfo.Name;
                    string  uiValueName = null;
                    if (uivalue != null)
                    {
                        uiValueName = uivalue.id;
                        if (parserParams.values.TryGetValue(uiValueName, out BSMLValue existing))
                        {
                            if (existing.FromUIValue)
                            {
                                throw new InvalidOperationException($"UIValue '{uiValueName}' is already used by member '{existing.MemberName}'.");
                            }
                            if (existing is BSMLFieldValue existingField)
                            {
                                existingField.fieldInfo   = fieldInfo;
                                existingField.FromUIValue = true;
                            }
                        }
                        else
                        {
                            parserParams.values.Add(uiValueName, new BSMLFieldValue(host, fieldInfo));
                        }
                        if (fieldAccessOptions == FieldAccessOption.AllowBoth && fieldName != uiValueName)
                        {
                            if (!parserParams.values.ContainsKey(fieldName))
                            {
                                parserParams.values.Add(fieldName, new BSMLFieldValue(host, fieldInfo, false));
                            }
                        }
                    }
                    else if (fieldAccessOptions != FieldAccessOption.OptIn)
                    {
                        if (!parserParams.values.ContainsKey(fieldName))
                        {
                            parserParams.values.Add(fieldName, new BSMLFieldValue(host, fieldInfo, false));
                        }
                    }

                    UIParams uiParams = fieldInfo.GetCustomAttributes(typeof(UIParams), true).FirstOrDefault() as UIParams;
                    if (uiParams != null)
                    {
                        fieldInfo.SetValue(host, parserParams);
                    }
                }

                foreach (PropertyInfo propertyInfo in host.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    UIValue uivalue     = Attribute.GetCustomAttributes(propertyInfo, typeof(UIValue), true).FirstOrDefault() as UIValue;
                    string  propName    = propertyInfo.Name;
                    string  uiValueName = null;
                    if (uivalue != null)
                    {
                        uiValueName = uivalue.id;
                        if (parserParams.values.TryGetValue(uiValueName, out BSMLValue existing))
                        {
                            if (existing.FromUIValue)
                            {
                                throw new InvalidOperationException($"UIValue '{uiValueName}' is already used by member '{existing.MemberName}'.");
                            }
                            if (existing is BSMLPropertyValue existingProp)
                            {
                                existingProp.propertyInfo = propertyInfo;
                                existingProp.FromUIValue  = true;
                            }
                        }
                        else
                        {
                            parserParams.values.Add(uiValueName, new BSMLPropertyValue(host, propertyInfo));
                        }
                        if (propertyAccessOptions == PropertyAccessOption.AllowBoth && propName != uiValueName)
                        {
                            if (!parserParams.values.ContainsKey(propName))
                            {
                                parserParams.values.Add(propName, new BSMLPropertyValue(host, propertyInfo, false));
                            }
                        }
                    }
                    else if (propertyAccessOptions != PropertyAccessOption.OptIn)
                    {
                        if (!parserParams.values.ContainsKey(propName))
                        {
                            parserParams.values.Add(propName, new BSMLPropertyValue(host, propertyInfo, false));
                        }
                    }
                }
            }

            IEnumerable <ComponentTypeWithData> componentInfo = Enumerable.Empty <ComponentTypeWithData>();

            foreach (XmlNode node in parentNode.ChildNodes)
            {
                HandleNode(node, parent, parserParams, out IEnumerable <ComponentTypeWithData> components);
                componentInfo = componentInfo.Concat(components);
            }

            foreach (KeyValuePair <string, BSMLAction> action in parserParams.actions.Where(x => x.Key.StartsWith(SUBSCRIVE_EVENT_ACTION_PREFIX)))
            {
                parserParams.AddEvent(action.Key.Substring(1), delegate { action.Value.Invoke(); });
            }

            foreach (ComponentTypeWithData component in componentInfo)
            {
                component.typeHandler.HandleTypeAfterParse(component, parserParams);
            }

            parserParams.EmitEvent("post-parse");

            return(parserParams);
        }