public Expression GetValue(ComponentBuilderContext context) => Expression.MemberInit( Expression.New(typeof(MarginPadding)), Expression.Bind(_top, Expression.Constant(_value.Top)), Expression.Bind(_right, Expression.Constant(_value.Right)), Expression.Bind(_bottom, Expression.Constant(_value.Bottom)), Expression.Bind(_left, Expression.Constant(_value.Left)));
public bool Handle(ComponentBuilderContext context, string name, YamlNode node) { if (name != "import") { return(false); } var assemblies = new List <Assembly>(); foreach (var item in node.ToSequence()) { try { assemblies.Add(Assembly.LoadFrom(item.ToScalar().Value)); } catch (Exception e) { context.OnException(e); } } // append as element resolver with new assemblies var builder = (IYamlComponentBuilder)context.Builder; builder.ElementResolver = new CompositeElementResolver(assemblies.Select(a => new AssemblyElementResolver(a)).Append(builder.ElementResolver)); return(true); }
public Expression GetValue(ComponentBuilderContext context) => Expression.MemberInit( Expression.New(typeof(ColourInfo)), Expression.Bind(_topLeft, new SrgbProvider(_color.TopLeft).GetValue(context)), Expression.Bind(_topRight, new SrgbProvider(_color.TopRight).GetValue(context)), Expression.Bind(_bottomRight, new SrgbProvider(_color.BottomRight).GetValue(context)), Expression.Bind(_bottomLeft, new SrgbProvider(_color.BottomLeft).GetValue(context)));
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (!CollectionPropProvider.IsCollection(prop.Type, out _, out var itemType)) { return(null); } IEnumerable <YamlNode> items; switch (node) { case YamlSequenceNode n: items = n; break; case YamlScalarNode n when string.IsNullOrEmpty(n.Value): items = Enumerable.Empty <YamlNode>(); break; default: items = new[] { node }; break; } return(new CollectionPropProvider(prop.Type, items.Select(n => ((IYamlComponentBuilder)context.Builder).PropResolver.Resolve(context, element, itemType, n)))); }
public Expression GetValue(ComponentBuilderContext context) => Expression.New(_ctor, Expression.Constant(_font.Family, typeof(string)), Expression.Constant(_font.Size, typeof(float)), Expression.Constant(_font.Weight, typeof(string)), Expression.Constant(_font.Italics, typeof(bool)), Expression.Constant(_font.FixedWidth, typeof(bool)));
protected override ElementBuilder Render(ComponentBuilderContext context) { var render = null as YamlNode; foreach (var(keyNode, valueNode) in _mapping) { try { var key = keyNode.ToScalar().Value; if (key == "render") { render = valueNode; continue; } if (!PartHandler.Handle(context, key, valueNode)) { throw new YamlComponentException($"Invalid component part '{key}'.", keyNode); } } catch (Exception e) { context.OnException(e); } } if (render == null) { return(null); } return(BuildElement(context, render)); }
// resolving a style delegate parameter public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (!IsStyleDelegate(prop.Type)) { return(null); } var provider = new Provider(prop.Type); foreach (var(key, value) in node.ToMapping()) { try { // find member by name var memberName = key.ToScalar().Value; var member = provider.FindMember(memberName); // resolve member using prop provider var memberProvider = member == null ? null : ((IYamlComponentBuilder)context.Builder).PropResolver.Resolve(context, null, member, value); if (memberProvider == null) { throw new YamlComponentException($"Cannot resolve property or field '{memberName}' in element {provider.DrawableType}.", key); } provider.Properties[member] = memberProvider; } catch (Exception e) { context.OnException(e); } } return(provider); }
static Provider ResolveInternal(ComponentBuilderContext context, ElementBuilder element, YamlNode node) { if (element == null) { return(null); } var value = node.ToScalar().Value; // declare a variable for this element if (!context.TryDeclareVariable(element.Type, value, null, out var variable)) { throw new YamlComponentException($"Variable '{value}' is already declared.", node); } // assign to this variable when element is constructed if (element.Assignee != null) { throw new YamlComponentException("Cannot specify multiple keys for an element.", node); } element.Assignee = variable; return(new Provider(value)); }
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (prop.Type != typeof(MarginPadding)) { return(null); } switch (node) { case YamlScalarNode scalar: return(new Provider(new MarginPadding(scalar.ToSingle()))); case YamlSequenceNode sequence when sequence.Children.Count == 1: return(new Provider(new MarginPadding(sequence[0].ToSingle()))); case YamlSequenceNode sequence when sequence.Children.Count == 4: return(new Provider(new MarginPadding { Top = sequence[0].ToSingle(), Right = sequence[1].ToSingle(), Bottom = sequence[2].ToSingle(), Left = sequence[3].ToSingle() })); case YamlMappingNode mapping: var value = new MarginPadding(); foreach (var(keyNode, valueNode) in mapping) { var key = keyNode.ToScalar().Value; switch (key) { case "top": value.Top = valueNode.ToSingle(); break; case "right": value.Right = valueNode.ToSingle(); break; case "bottom": value.Bottom = valueNode.ToSingle(); break; case "left": value.Left = valueNode.ToSingle(); break; default: throw new YamlComponentException($"Invalid margin/padding property '{key}'.", keyNode); } } return(new Provider(value)); default: throw new YamlComponentException("Must be a sequence containing 4 components or a mapping that specifies top-left-bottom-right margin/padding respectively.", node); } }
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (prop.Type != typeof(LocalisedString)) { return(null); } return(new Provider(node.ToScalar().Value)); }
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (prop.Type != typeof(ElementKey)) { return(null); } return(ResolveInternal(context, element, node)); }
public bool Resolve(ComponentBuilderContext context, ElementBuilder element, string prop, YamlNode node) { if (prop != "key") { return(false); } return(ResolveInternal(context, element, node) != null); }
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (!typeof(ofElement).IsAssignableFrom(prop.Type)) { return(null); } return(((IYamlComponentBuilder)context.Builder).BuildElement(context, node)); }
public bool Handle(ComponentBuilderContext context, string name, YamlNode node) { if (name != "name") { return(false); } context.Name = node.ToScalar().Value; return(true); }
// resolving some prop that could be a property of drawable // the assignment gets appended to the style delegate public bool Resolve(ComponentBuilderContext context, ElementBuilder element, string prop, YamlNode node) { if (element == null) { return(false); } // find style delegate parameter var styleProps = element.Parameters.Where(p => IsStyleDelegate(p.ParameterType)).ToArray(); if (styleProps.Length == 0) { return(false); } if (styleProps.Length != 1) { throw new YamlComponentException($"Ambiguous element style prop reference: {string.Join<ParameterInfo>(", ", styleProps)}", node); } var styleProp = styleProps[0]; // add or create style delegate prop provider Provider provider; if (element.Props.TryGetValue(styleProp.Name, out var p) && p is Provider pp) { provider = pp; } else { element.Props[styleProp.Name] = provider = new Provider(styleProp.ParameterType); } // find member by name var member = provider.FindMember(prop); if (member == null) { return(false); } // resolve member using prop provider var memberProvider = ((IYamlComponentBuilder)context.Builder).PropResolver.Resolve(context, element, member, node); if (memberProvider == null) { throw new YamlComponentException($"Cannot resolve property or field '{prop}' in element {provider.DrawableType}.", node); } provider.Properties[member] = memberProvider; return(true); }
public Expression GetValue(ComponentBuilderContext context) { var drawable = Expression.Parameter(DrawableType, "drawable"); return(Expression.Lambda( DelegateType, Expression.Block(Properties.Select(x => Expression.Assign( Expression.MakeMemberAccess(drawable, x.Key), x.Value.GetValue(context)))), drawable)); }
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { var underlying = Nullable.GetUnderlyingType(prop.Type); if (underlying == null) { return(null); } // rerun prop resolution using unwrapped nullable type return(new Provider(prop.Type, ((IYamlComponentBuilder)context.Builder).PropResolver.Resolve(context, element, underlying, node))); }
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (!prop.Type.IsEnum) { return(null); } var value = node.ToScalar().Value; if (Enum.TryParse(prop.Type, value, IgnoreEnumCase, out var parsed)) { return(new Provider(parsed, prop.Type)); } throw new YamlComponentException($"Cannot convert '{value}' to enum {prop.Type}.", node); }
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (!prop.Type.IsPrimitive && prop.Type != typeof(string)) { return(null); } var value = node.ToScalar().Value; try { return(new Provider(Convert.ChangeType(value, prop.Type, CultureInfo.InvariantCulture))); } catch (Exception e) { throw new YamlComponentException($"Cannot convert '{value}' to type {prop.Type}.", node, e); } }
public ElementBuilder BuildElement(ComponentBuilderContext context, YamlNode node) { try { switch (node) { // element case YamlMappingNode mapping: if (mapping.Children.Count == 0) { return(new ElementBuilder.Empty()); } if (mapping.Children.Count != 1) { throw new YamlComponentException("Mapping must have one key that indicates element type.", mapping); } var(keyNode, valueNode) = mapping.Children.First(); var key = keyNode.ToScalar().Value; // resolve type var type = ElementResolver.Resolve(context, key) ?? throw new YamlComponentException($"Cannot resolve element '{key}'.", keyNode); // build prop dictionary var props = valueNode.ToMapping().ToDictionary(x => x.Key.ToScalar().Value, x => new YamlProp(x.Key, x.Value)); return(BuildElementWithProps(context, type, keyNode, props)); // fragment case YamlSequenceNode sequence: var elements = sequence.Select(n => BuildElement(context, n)).Where(e => !(e is ElementBuilder.Empty)).ToArray(); return(elements.Length switch { 0 => new ElementBuilder.Empty(), 1 => elements[0], _ => new FragmentBuilder(elements) }); case YamlScalarNode scalar when string.IsNullOrEmpty(scalar.Value): return(new ElementBuilder.Empty());
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (prop.Type == typeof(Vector2)) { return(new Provider2(ParseVector(node, 2))); } if (prop.Type == typeof(Vector3)) { return(new Provider3(ParseVector(node, 3))); } if (prop.Type == typeof(Vector4)) { return(new Provider4(ParseVector(node, 4))); } return(null); }
public Expression GetValue(ComponentBuilderContext context) => Expression.Convert(Expression.Constant(_value), typeof(ElementKey));
public Type Resolve(ComponentBuilderContext context, string name) => _types.GetValueOrDefault(name);
public Type Resolve(ComponentBuilderContext context, string name) => _resolver?.Resolve(context, AddPrefix(name)) ?? _resolver?.Resolve(context, RemovePrefix(name));
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) { if (prop.Type != typeof(FontUsage)) { return(null); } switch (node) { case YamlScalarNode scalar: var parts = scalar.Value.Split(','); switch (parts.Length) { case 1: return(new Provider(FontUsage.Default.With(family: parts[0]))); case 2: return(new Provider(FontUsage.Default.With(family: parts[0], size: node.ToSingle(parts[1])))); default: throw new YamlComponentException("Must be a scalar that indicates the font family name and an optional font size.", node); } case YamlMappingNode mapping: var usage = FontUsage.Default; foreach (var(keyNode, valueNode) in mapping) { var key = keyNode.ToScalar().Value; switch (key) { case "family": usage = usage.With(family: valueNode.ToScalar().Value); break; case "weight": usage = usage.With(weight: valueNode.ToScalar().Value); break; case "italics": usage = usage.With(italics: valueNode.ToBoolean()); break; case "size": usage = usage.With(size: valueNode.ToSingle()); break; case "fixed": usage = usage.With(fixedWidth: valueNode.ToBoolean()); break; default: throw new YamlComponentException($"Invalid font property '{key}'.", keyNode); } } return(new Provider(usage)); default: throw new YamlComponentException("Must be a scalar or sequence.", node); } }
public bool Handle(ComponentBuilderContext context, string name, YamlNode node) => _handlers.Any(h => h.Handle(context, name, node));
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) => prop.GetAttributes() .OfType <IPropResolver>() .Select(r => r.Resolve(context, element, prop, node)) .FirstOrDefault(p => p != null);
public bool Resolve(ComponentBuilderContext context, ElementBuilder element, string prop, YamlNode node) => _resolvers.Any(r => r.Resolve(context, element, prop, node));
public Expression GetValue(ComponentBuilderContext context) => Expression.New(_ctor, Expression.Constant(_v[0]), Expression.Constant(_v[1]));
public IPropProvider Resolve(ComponentBuilderContext context, ElementBuilder element, PropTypeInfo prop, YamlNode node) => _resolvers.Select(r => r.Resolve(context, element, prop, node)).FirstOrDefault(p => p != null);