Exemplo n.º 1
0
        private void GenerateRpcServiceViewCode(
            Type type,
            CodeWriter.CodeWriter w,
            List <Tuple <MethodInfo, Tuple <string, string> > > method2PayloadTypeNames,
            Tuple <Type, List <Tuple <MethodInfo, Tuple <string, string> > > >[] typeInfos)
        {
            using (w.B($"public class {Utility.GetViewRpcServiceViewClassName(type)}{type.GetGenericParameters()} : IRpcInvokable"))
            {
                using (w.B($"public async Task<bool> Invoke(object _target_, NetDataReader _reader_, NetDataWriter _writer_)"))
                {
                    w._("NetView _view_ = _target_ as NetView;");
                    w._($"var typeEnum = ({Utility.GetInterfaceEnumName(type)})_reader_.ReadInt32();");
                    using (w.B($"switch(typeEnum)"))
                    {
                        foreach (var m in typeInfos.First().Item2)
                        {
                            var method         = m.Item1;
                            var parameters     = method.GetParameters();
                            var paramStr       = string.Join(", ", parameters.Select(p => p.GetParameterDeclaration(true)));
                            var returnType     = method.ReturnType.GenericTypeArguments.FirstOrDefault();
                            var returnTaskType = (returnType != null) ? $"Task<{returnType.GetSymbolDisplay(true)}>" : "Task";

                            w._($"case {Utility.GetInterfaceEnumName(type)}.{method.Name}:");
                            using (w.i())
                            {
                                using (w.i("{", "}"))
                                {
                                    var parameterNames = string.Join(", ", method.GetParameters().Select(p => p.Name));

                                    foreach (var param in method.GetParameters())
                                    {
                                        w._($"{Utility.GetReaderMethod(param)}");
                                    }

                                    if (returnType != null)
                                    {
                                        w._($"var _result_ = await _view_.FindRpcHandler<{type.GetSymbolDisplay()}>().{method.Name}{method.GetGenericParameters()}({parameterNames});");
                                        w._($"{Utility.GetWriteMethod(returnType, "_result_")}");
                                    }
                                    else
                                    {
                                        w._($"await _view_.FindRpcHandler<{type.GetSymbolDisplay()}>().{method.Name}{method.GetGenericParameters()}({parameterNames});");
                                    }
                                }

                                w._($"break;");
                            }
                        }

                        w._($"default: return false;");
                    }
                    w._($"return true;");
                }
            }
        }
Exemplo n.º 2
0
        private void GenerateRpcCode(
            Type type, CodeWriter.CodeWriter w, Type[] baseTypes,
            Tuple <Type, List <Tuple <MethodInfo, Tuple <string, string> > > >[] typeInfos,
            Dictionary <int, string> rpcEnumMap)
        {
            // NoReply Interface

            var baseNoReplys        = baseTypes.Select(t => Utility.GetNoReplyInterfaceName(t));
            var baseNoReplysInherit = baseNoReplys.Any() ? " : " + string.Join(", ", baseNoReplys) : "";

            using (w.B($"public interface {Utility.GetNoReplyInterfaceName(type)}{type.GetGenericParameters()}{baseNoReplysInherit}{type.GetGenericConstraintClause()}"))
            {
                foreach (var m in typeInfos.First().Item2)
                {
                    var method     = m.Item1;
                    var parameters = method.GetParameters();
                    var paramStr   = string.Join(", ", parameters.Select(p => p.GetParameterDeclaration(true)));
                    w._($"void {method.Name}{method.GetGenericParameters()}({paramStr}){method.GetGenericConstraintClause()};");
                }
            }

            // Rpc Enum
            using (w.B($"public enum {Utility.GetInterfaceEnumName(type)} : int"))
            {
                foreach (var m in typeInfos.First().Item2)
                {
                    var method = m.Item1;

                    /*var parameters = method.GetParameters();
                     * var paramStr = string.Join(", ", parameters.Select(p => p.GetParameterDeclaration(true)));
                     * var returnType = method.ReturnType.GenericTypeArguments.FirstOrDefault();
                     * var returnTaskType = (returnType != null) ? $"Task<{returnType.GetSymbolDisplay(true)}>" : "Task";*/
                    var methodHash = Utility.GetMethodHashCode(Utility.GetInterfaceEnumName(type) + "." + method.Name);

                    w._($"{method.Name} = {methodHash},");

                    rpcEnumMap.Add(methodHash, $"{type.GetPureName()}.{method.Name}");
                }
            }

            // Rpc
            var rpcClassName                = Utility.GetRpcClassName(type);
            var rpcClassGenericName         = rpcClassName + type.GetGenericParameters();
            var noReplyInterfaceName        = Utility.GetNoReplyInterfaceName(type);
            var noReplyInterfaceGenericName = noReplyInterfaceName + type.GetGenericParameters();

            using (w.B($"public class {rpcClassName}{type.GetGenericParameters()} : RpcRequester, {type.GetSymbolDisplay()}, {noReplyInterfaceName}{type.GetGenericParameters()}{type.GetGenericConstraintClause()}"))
            {
                // InterfaceType property

                w._($"public override Type InterfaceType => typeof({type.GetSymbolDisplay()});");
                w._();

                // Constructors

                using (w.B($"public {rpcClassName}(NetView view, TimeSpan? timeout = null)",
                           "\t: base(NetClientGlobal.Instance.Client, new NetViewRequestWaiter(view), timeout)"))
                {
                    w._("DeliveryMethod = DeliveryMethod.Unreliable;");
                    w._("DeliveryTarget = DeliveryTarget.Others;");
                }

                using (w.B($"public {rpcClassName}(ISession target, IRequestWaiter requestWaiter, TimeSpan? timeout = null) : base(target, requestWaiter, timeout)"))
                {
                    w._("DeliveryMethod = DeliveryMethod.Unreliable;");
                    w._("DeliveryTarget = DeliveryTarget.Others;");
                }

                // With Helpers

                using (w.B($"public {rpcClassGenericName} ToTarget(DeliveryMethod deliveryMethod, ushort sessionId)"))
                {
                    w._("DeliveryMethod = deliveryMethod;");
                    w._("DeliveryTarget = DeliveryTarget.Target;");
                    w._("Extra = sessionId;");
                    w._("return this;");
                }

                using (w.B($"public {rpcClassGenericName} ToMaster(DeliveryMethod deliveryMethod)"))
                {
                    w._("DeliveryMethod = deliveryMethod;");
                    w._("DeliveryTarget = DeliveryTarget.Master;");
                    w._("return this;");
                }

                using (w.B($"public {noReplyInterfaceGenericName} ToOthers(DeliveryMethod deliveryMethod)"))
                {
                    w._("DeliveryMethod = deliveryMethod;");
                    w._("DeliveryTarget = DeliveryTarget.Others;");
                    w._("return this;");
                }

                using (w.B($"public {noReplyInterfaceGenericName} ToAll(DeliveryMethod deliveryMethod)"))
                {
                    w._("DeliveryMethod = deliveryMethod;");
                    w._("DeliveryTarget = DeliveryTarget.All;");
                    w._("return this;");
                }

                using (w.B($"public {noReplyInterfaceGenericName} WithNoReply()"))
                {
                    w._("return this;");
                }

                using (w.B($"public {rpcClassGenericName} WithRequestWaiter(IRequestWaiter requestWaiter)"))
                {
                    w._($"return new {rpcClassGenericName}(Target, requestWaiter, Timeout);");
                }

                using (w.B($"public {rpcClassGenericName} WithTimeout(TimeSpan? timeout)"))
                {
                    w._($"return new {rpcClassGenericName}(Target, RequestWaiter, timeout);");
                }

                // IInterface message methods

                foreach (var t in typeInfos)
                {
                    var payloadTableClassName = Utility.GetRpcServiceClassName(t.Item1) + type.GetGenericParameters();

                    foreach (var m in t.Item2)
                    {
                        var method       = m.Item1;
                        var payloadTypes = m.Item2;
                        var parameters   = method.GetParameters();

                        var parameterTypeNames = string.Join(", ", parameters.Select(p => p.GetParameterDeclaration(true)));
                        var parameterInits     = string.Join(", ", parameters.Select(Utility.GetParameterAssignment));
                        var returnType         = method.ReturnType.GenericTypeArguments.FirstOrDefault();

                        // Request Methods

                        var returnTaskType = (returnType != null) ? $"Task<{returnType.GetSymbolDisplay(true)}>" : "Task";
                        var prototype      = $"public async {returnTaskType} {method.Name}{method.GetGenericParameters()}({parameterTypeNames}){method.GetGenericConstraintClause()}";
                        using (w.B(prototype))
                        {
                            w._("var _writer_ = NetPool.DataWriterPool.Alloc();");
                            w._("try");
                            using (w.i("{", "}"))
                            {
                                w._($"_writer_.Write((int){Utility.GetInterfaceEnumName(type)}.{method.Name});");

                                foreach (var param in parameters)
                                {
                                    w._($"{Utility.GetWriteMethod(param)}");
                                }

                                if (returnType != null)
                                {
                                    using (w.B($"using(var _reader_ = await SendRequestAndReceive(_writer_))"))
                                    {
                                        w._($"return {Utility.GetReaderMethod(returnType)}");
                                    }
                                }
                                else
                                {
                                    w._($"await SendRequestAndWait(_writer_);");
                                }
                            }
                            w._("finally");
                            using (w.i("{", "}"))
                            {
                                w._($"NetPool.DataWriterPool.Free(_writer_);");
                            }
                        }
                    }
                }

                // IInterface_NoReply message methods

                foreach (var t in typeInfos)
                {
                    var interfaceName        = Utility.GetNoReplyInterfaceName(t.Item1);
                    var interfaceGenericName = interfaceName + t.Item1.GetGenericParameters();

                    var payloadTableClassName = Utility.GetRpcServiceClassName(t.Item1) + type.GetGenericParameters();

                    foreach (var m in t.Item2)
                    {
                        var method       = m.Item1;
                        var payloadTypes = m.Item2;
                        var parameters   = method.GetParameters();

                        var parameterTypeNames = string.Join(", ", parameters.Select(p => p.GetParameterDeclaration(false)));
                        var parameterInits     = string.Join(", ", parameters.Select(Utility.GetParameterAssignment));

                        // Request Methods

                        using (w.B($"void {interfaceGenericName}.{method.Name}{method.GetGenericParameters()}({parameterTypeNames})"))
                        {
                            w._("var _writer_ = NetPool.DataWriterPool.Alloc();");
                            w._("try");
                            using (w.i("{", "}"))
                            {
                                w._($"_writer_.Write((int){Utility.GetInterfaceEnumName(type)}.{method.Name});");

                                foreach (var param in parameters)
                                {
                                    w._($"{Utility.GetWriteMethod(param)}");
                                }

                                w._("SendRequest(_writer_);");
                            }
                            w._("finally");
                            using (w.i("{", "}"))
                            {
                                w._($"NetPool.DataWriterPool.Free(_writer_);");
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        private void GenerateFormatterCode(Type type, Dictionary <string, string> formatterMap, CodeWriter.CodeWriter w)
        {
            bool allowPrivate = false;
            Dictionary <int, SerializeMember> members = new Dictionary <int, SerializeMember>();

            foreach (PropertyInfo item in GetAllProperties(type))
            {
                if (item.GetCustomAttribute <IgnoreMemberAttribute>(true) != null)
                {
                    continue;
                }

                if (item.IsIndexer())
                {
                    continue;
                }

                MethodInfo getMethod = item.GetGetMethod(true);
                MethodInfo setMethod = item.GetSetMethod(true);

                int key = Utility.GetMethodHashCode(item.Name);

                var member = new SerializeMember
                {
                    PropertyInfo = item,
                    Key          = key,
                    IsReadable   = (getMethod != null) && (allowPrivate || getMethod.IsPublic) && !getMethod.IsStatic,
                    IsWritable   = (setMethod != null) && (allowPrivate || setMethod.IsPublic) && !setMethod.IsStatic,
                };

                if (!member.IsReadable || !member.IsWritable)
                {
                    continue;
                }

                if (members.ContainsKey(key))
                {
                    throw new Exception("key is duplicated, all members key must be unique." + " type: " + type.FullName + " member:" + item.Name);
                }

                members.Add(key, member);
            }

            foreach (FieldInfo item in GetAllFields(type))
            {
                if (item.GetCustomAttribute <IgnoreMemberAttribute>(true) != null)
                {
                    continue;
                }

                if (item.GetCustomAttribute <System.Runtime.CompilerServices.CompilerGeneratedAttribute>(true) != null)
                {
                    continue;
                }

                if (item.IsStatic)
                {
                    continue;
                }

                int key = Utility.GetMethodHashCode(item.Name);

                var member = new SerializeMember
                {
                    FieldInfo  = item,
                    Key        = key,
                    IsReadable = allowPrivate || item.IsPublic,
                    IsWritable = allowPrivate || (item.IsPublic && !item.IsInitOnly),
                };

                if (!member.IsReadable || !member.IsWritable)
                {
                    continue;
                }

                if (members.ContainsKey(key))
                {
                    throw new Exception("key is duplicated, all members key must be unique." + " type: " + type.FullName + " member:" + item.Name);
                }

                members.Add(key, member);
            }

            var memberArray = members.Values.OrderBy(x => x.Key).ToArray();

            var formatterClassName        = Utility.GetFormatterClassName(type);
            var formatterClassGenericName = formatterClassName + type.GetGenericParameters();
            var className        = type.GetPureName();
            var classGenericName = className + type.GetGenericParameters();

            using (w.B($"public sealed class {formatterClassGenericName} : INetDataFormatter<{classGenericName}>"))
            {
                if (type.IsGenericType == false)
                {
                    w._($"public static readonly {formatterClassGenericName} Instance = new {formatterClassGenericName}();");
                    w._();
                }

                // Constructor

                /*
                 * using (w.B($"private {formatterClassName}()"))
                 * {
                 * }
                 */

                // Serializer

                using (w.B($"public void Serialize(NetDataWriter _writer_, {classGenericName} _value_, NetDataSerializerOptions options)"))
                {
                    foreach (var member in memberArray)
                    {
                        w._(Utility.GetWriteMethod(member.Type, $"_value_.{member.Name}"));
                    }
                }

                using (w.B($"public {classGenericName} Deserialize(NetDataReader _reader_, NetDataSerializerOptions options)"))
                {
                    foreach (var member in memberArray)
                    {
                        w._($"var __{member.Name} = {Utility.GetReaderMethod(member.Type)}");
                    }
                    w._();

                    using (w.i($"return new {classGenericName}() {{", "};"))
                    {
                        foreach (var member in memberArray)
                        {
                            w._($"{member.Name} = __{member.Name},");
                        }
                    }
                }
            }

            var ns = type.Namespace;

            if (ns != null)
            {
                ns += ".";
            }
            else
            {
                ns = string.Empty;
            }

            var fullFormatterClassName = ns + formatterClassName;

            if (type.IsGenericType)
            {
                formatterMap.Add($"typeof({type.GetSymbolDisplay(true, true)})", $"typeof({fullFormatterClassName + type.GetGenericParameters(true)})");
            }
            else
            {
                formatterMap.Add($"typeof({type.GetSymbolDisplay(true, true)})", $"{fullFormatterClassName}.Instance");
            }
        }