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_);"); } } } } } }