GetActorInterfaceTagName() public static method

public static GetActorInterfaceTagName ( Type type ) : string
type System.Type
return string
Esempio n. 1
0
        private void GeneratePayloadCode(
            Type type, CodeWriter.CodeWriter w,
            List <Tuple <MethodInfo, Tuple <string, string> > > method2PayloadTypeNames)
        {
            var tagName = Utility.GetActorInterfaceTagName(type);

            w._($"[PayloadTable(typeof({type.GetSymbolDisplay(typeless: true)}), PayloadTableKind.Request)]");
            using (w.B($"public static class {Utility.GetPayloadTableClassName(type)}{type.GetGenericParameters()}{type.GetGenericConstraintClause()}"))
            {
                // generate GetPayloadTypes method

                using (w.B("public static Type[,] GetPayloadTypes()"))
                {
                    using (w.i("return new Type[,] {", "};"))
                    {
                        foreach (var m in method2PayloadTypeNames)
                        {
                            var genericParameters = m.Item1.GetGenericParameters(typeless: true);
                            var payloadTypes      = m.Item2;
                            var returnType        = payloadTypes.Item2 != "" ? $"typeof({payloadTypes.Item2}{genericParameters})" : "null";
                            w._($"{{ typeof({payloadTypes.Item1}{genericParameters}), {returnType} }},");
                        }
                    }
                }

                // generate payload classes for all methods

                foreach (var m in method2PayloadTypeNames)
                {
                    var method             = m.Item1;
                    var payloadTypes       = m.Item2;
                    var returnType         = method.ReturnType.GenericTypeArguments.FirstOrDefault();
                    var observerParameters = method.GetParameters()
                                             .Select(p => Tuple.Create(p, Utility.GetReachableMemebers(p.ParameterType, Utility.IsObserverInterface).ToArray()))
                                             .Where(i => i.Item2.Length > 0)
                                             .ToArray();

                    // Invoke payload

                    if (Options.UseProtobuf)
                    {
                        w._("[ProtoContract, TypeAlias]");
                    }

                    var tagOverridable    = tagName != null ? ", IPayloadTagOverridable" : "";
                    var observerUpdatable = observerParameters.Any() ? ", IPayloadObserverUpdatable" : "";
                    using (w.B($"public class {payloadTypes.Item1}{method.GetGenericParameters()}",
                               $": IInterfacedPayload, IAsyncInvokable{tagOverridable}{observerUpdatable}{method.GetGenericConstraintClause()}"))
                    {
                        // Parameters

                        var parameters = method.GetParameters();
                        for (var i = 0; i < parameters.Length; i++)
                        {
                            var parameter = parameters[i];

                            var attr = "";
                            var defaultValueExpression = "";
                            if (Options.UseProtobuf)
                            {
                                var defaultValueAttr =
                                    parameter.HasNonTrivialDefaultValue()
                                        ? $", DefaultValue({parameter.DefaultValue.GetValueLiteral()})"
                                        : "";
                                attr = $"[ProtoMember({i + 1}){defaultValueAttr}] ";

                                if (parameter.HasNonTrivialDefaultValue())
                                {
                                    defaultValueExpression = " = " + parameter.DefaultValue.GetValueLiteral();
                                }
                            }

                            var typeName = parameter.ParameterType.GetSymbolDisplay(true);
                            w._($"{attr}public {typeName} {parameter.Name}{defaultValueExpression};");
                        }
                        if (parameters.Any())
                        {
                            w._();
                        }

                        // GetInterfaceType

                        using (w.B($"public Type GetInterfaceType()"))
                        {
                            w._($"return typeof({type.GetSymbolDisplay()});");
                        }

                        // InvokeAsync

                        if (Options.UseSlimClient)
                        {
                            using (w.B("public Task<IValueGetable> InvokeAsync(object __target)"))
                            {
                                w._("return null;");
                            }
                        }
                        else
                        {
                            using (w.B("public async Task<IValueGetable> InvokeAsync(object __target)"))
                            {
                                var parameterNames = string.Join(", ", method.GetParameters().Select(p => p.Name));
                                if (returnType != null)
                                {
                                    w._($"var __v = await (({type.GetSymbolDisplay()})__target).{method.Name}{method.GetGenericParameters()}({parameterNames});",
                                        $"return (IValueGetable)(new {payloadTypes.Item2}{method.GetGenericParameters()} {{ v = __v }});");
                                }
                                else
                                {
                                    w._($"await (({type.GetSymbolDisplay()})__target).{method.Name}{method.GetGenericParameters()}({parameterNames});",
                                        $"return null;");
                                }
                            }
                        }

                        // IPayloadTagOverridable.SetTag

                        if (tagName != null)
                        {
                            using (w.B($"void IPayloadTagOverridable.SetTag(object value)"))
                            {
                                var tagParameter = parameters.FirstOrDefault(pi => pi.Name == tagName);
                                if (tagParameter != null)
                                {
                                    var typeName = tagParameter.ParameterType.GetSymbolDisplay(true);
                                    w._($"{tagName} = ({typeName})value;");
                                }
                            }
                        }

                        // IPayloadObserverUpdatable.Update

                        if (observerParameters.Any())
                        {
                            using (w.B("void IPayloadObserverUpdatable.Update(Action<IInterfacedObserver> updater)"))
                            {
                                foreach (var p in observerParameters)
                                {
                                    using (w.b($"if ({p.Item1.Name} != null)"))
                                    {
                                        foreach (var o in p.Item2)
                                        {
                                            if (o == "")
                                            {
                                                w._($"updater({p.Item1.Name});");
                                            }
                                            else
                                            {
                                                w._($"if ({p.Item1.Name}.{o} != null) updater({p.Item1.Name}.{o});");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Return payload

                    if (returnType != null)
                    {
                        var actorRefs = Utility.GetReachableMemebers(returnType, Utility.IsActorInterface).ToArray();

                        if (Options.UseProtobuf)
                        {
                            w._("[ProtoContract, TypeAlias]");
                        }

                        var actorRefUpdatable = actorRefs.Any() ? ", IPayloadActorRefUpdatable" : "";
                        using (w.B($"public class {payloadTypes.Item2}{method.GetGenericParameters()}",
                                   $": IInterfacedPayload, IValueGetable{actorRefUpdatable}{method.GetGenericConstraintClause()}"))
                        {
                            var attr = (Options.UseProtobuf) ? "[ProtoMember(1)] " : "";
                            w._($"{attr}public {returnType.GetSymbolDisplay(true)} v;");
                            w._();

                            // GetInterfaceType

                            using (w.B("public Type GetInterfaceType()"))
                            {
                                w._($"return typeof({type.GetSymbolDisplay()});");
                            }

                            // IValueGetable.Value

                            using (w.B("public object Value"))
                            {
                                w._($"get {{ return v; }}");
                            }

                            // IPayloadActorRefUpdatable.Update

                            if (actorRefs.Any())
                            {
                                using (w.B("void IPayloadActorRefUpdatable.Update(Action<object> updater)"))
                                {
                                    using (w.b($"if (v != null)"))
                                    {
                                        foreach (var r in actorRefs)
                                        {
                                            if (r == "")
                                            {
                                                w._($"updater(v); ");
                                            }
                                            else
                                            {
                                                w._($"if (v.{r} != null) updater(v.{r});");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }