ICoder <IEnumerable <ModelMeta> > GenSerializeCoder(bool isClient) { // [FieldIndex(Index = 1)] // public UInt32 TowerId; var fieldDec = "[FieldIndex(Index = {0})]".Basic <FieldMeta>(meta => meta.SerializeIndex) .Satisfy(meta => meta.SerializeIndex > 0 && !isClient) .SkipLine() .Append("public {0} {1};".Basic <FieldMeta>(meta => CoderHelper.GetTypeStr(meta.Field.FieldType), meta => meta.Field.Name)) .Satisfy(meta => !meta.IsInherit); var fieldWriterWithCheck = CoderHelper.WriteWithCheckCoder <FieldMeta>() .Lift( (FieldMeta meta) => new Tuple <Type, ICoder <FieldMeta>, FieldMeta>(meta.Type, "{0}".Basic <FieldMeta>(f => f.Name), meta)); var writer = Generator.GenSelect( "public void Write(BinaryWriter bw)".Unit <ModelMeta>() .Combine(fieldWriterWithCheck.Many("\n").Brace(), meta => meta.Fields) .Satisfy(meta => !meta.IsHierarchy) , "public {0} void Write(BinaryWriter bw)".Basic <ModelMeta>(meta => Generator.GenSelect( "override".Unit <ModelMeta>().Satisfy(meta1 => !meta1.IsTopmostBase) , "virtual".Unit <ModelMeta>()).Code(meta)) .Append( "bw.Write((byte){0});".Basic <ModelMeta>(meta => meta.HierarchyCode) .Combine(fieldWriterWithCheck.Many("\n"), meta => meta.Fields) .Brace())); var fieldReaderWithCheck = CoderHelper.ReadWithCheckCoder <FieldMeta>() .Lift( (FieldMeta meta) => new Tuple <Type, ICoder <FieldMeta>, FieldMeta>(meta.Type, "{0}".Basic <FieldMeta>(f => f.Name), meta)); var reader = Generator.GenSelect( "public {0} Read(BinaryReader br)".Basic <ModelMeta>(meta => CoderHelper.GetTypeStr(meta.Type)).Satisfy(meta => !meta.IsHierarchy) , "public new {0} ReadImpl(BinaryReader br)".Basic <ModelMeta>(meta => CoderHelper.GetTypeStr(meta.Type))) .Combine(fieldReaderWithCheck.Many("\n").Append("return this;".Unit <IEnumerable <FieldMeta> >()).Brace(), meta => meta.Fields); var hierarchyReader = "public new {0} Read(BinaryReader br){{return ({0})ReadStatic(br);}}".Basic <ModelMeta>( meta => CoderHelper.GetTypeStr(meta.Type)).Satisfy(meta => meta.IsHierarchy); var topmostReaderDispatcher = "public static {0} ReadStatic(BinaryReader br)".Basic <ModelMeta>( meta => CoderHelper.GetTypeStr(meta.Type)) .Append( "byte tp = br.ReadByte();if (tp != (byte)SerializeObjectMark.IsNull){{switch (tp){{{0}{1}}}}}return null;" .Basic <ModelMeta>(meta => "case {0}: return (new {1}()).ReadImpl(br);".Basic <ModelMeta>( metac => metac.HierarchyCode, metac => CoderHelper.GetTypeStr(metac.Type)) .Many("\n") .Code(meta.Children), meta => "default: return (new {0}()).ReadImpl(br);".Basic <ModelMeta>(metai => CoderHelper.GetTypeStr(metai.Type)).Code(meta)).Brace()); var dumpAtomic = Generator.GenSelect( "{0}!=null?string.Join(\", \", Array.ConvertAll({0}, input => input.ToString())):\"null\"".Basic <FieldMeta>( meta => meta.Field.Name).Satisfy(meta => meta.Field.FieldType.IsArray) , "{0}!=null?string.Join(\", \", Array.ConvertAll({0}.ToArray(), input => input.ToString())):\"null\"".Basic <FieldMeta>( meta => meta.Field.Name).Satisfy(meta => meta.Field.FieldType.Name.Equals("List`1")) , "{0}".Basic <FieldMeta>(meta => meta.Field.Name)); var dumpHelpAtomic = "{0}={{{1}}}\\n".Basic <FieldMeta>(meta => meta.Field.Name, meta => meta.Position - 1); var dump = "public override string ToString(){{return string.Format(\"{0}:\\n{1}\", {2});}}" .Basic <ModelMeta>(meta => meta.Type.Name, meta => dumpHelpAtomic.Many("").Code(meta.Fields), meta => dumpAtomic.Many(",").Code(meta.Fields)); var serialize = "public class {0}{1}{{".Basic <ModelMeta>(meta => meta.Type.Name, meta => ":{0}".Basic <ModelMeta>(meta1 => CoderHelper.GetTypeStr(meta1.Parent.Type)).Satisfy(meta1 => meta1.Parent != null).Code(meta)) .Combine(fieldDec.Many("\n"), meta => meta.Fields) .Append(writer.SkipLine()) .Append(reader.SkipLine()) .Append(hierarchyReader.SkipLine().Satisfy(meta => meta.IsHierarchy)) .Append(topmostReaderDispatcher.SkipLine().Satisfy(meta => meta.IsTopmostBase)) .Append(dump.SkipLine()) .WithPostfix("}"); return(serialize.Many("\n")); //return "".Unit<TypeMeta>().Combine(dumpAtomic.Many(","), meta => meta.Fields).Many("\n"); }
static ICoder <IEnumerable <ServiceMeta> > GenCoder(bool client) { #region name related // DbSyncNotify/LogicClient var serviceName = Generator.GenSelect( "{0}Notify".Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Type == ServiceType.Notify) , "{0}".Basic <ServiceMeta>(meta => meta.Name)); // IDbSyncNotifyImpl var implName = "I{0}Impl".Basic <ServiceMeta>(meta => serviceName.Code(meta)); // ILogicClientInvoke var invokeName = "I{0}Invoke".Basic <ServiceMeta>(meta => serviceName.Code(meta)); // IClientLogicService var trivialServiceName = "I{0}Service".Basic <ServiceMeta>(meta => serviceName.Code(meta)); // DbSyncNotifyDelegate/LoginNotifyDelegate var delegateName = Generator.GenSelect( "{0}NotifyDelegate".Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Type == ServiceType.Notify) , "{0}ServiceDelegate".Basic <ServiceMeta>(meta => meta.Name)); // LoginNotifySerializer var serializerName = "{0}Serializer".Basic <ServiceMeta>(meta => serviceName.Code(meta)); // LoginClientDispatcher var dispatcherName = "{0}Dispatcher".Basic <ServiceMeta>(meta => serviceName.Code(meta)); // Task/Task<bool> var taskTypeName = Generator.GenSelect( "Task" .Unit <Type>() .Satisfy(meta => meta.Name.ToLower().Equals("void")), "Task<{0}>" .Basic <Type>(CoderHelper.GetTypeStr)); // InvokeOperation/InvokeOperation<bool> var invokeTypeName = Generator.GenSelect( "InvokeOperation" .Unit <Type>() .Satisfy(meta => meta.Name.ToLower().Equals("void")), "InvokeOperation<{0}>" .Basic <Type>(CoderHelper.GetTypeStr)); // InvokeOperation/InvokeOperation<bool> var invokeCallName = Generator.GenSelect( "Invoke" .Unit <Type>() .Satisfy(meta => meta.Name.ToLower().Equals("void")), "Invoke<{0}>" .Basic <Type>(CoderHelper.GetTypeStr)); var invokeTaskCallName = Generator.GenSelect( "InvokeT" .Unit <Type>() .Satisfy(meta => meta.Name.ToLower().Equals("void")), "InvokeT<{0}>" .Basic <Type>(CoderHelper.GetTypeStr)); #endregion #region function related // ulong pid var paraSig = "{0} {1}".Basic <ParameterMeta>(meta => CoderHelper.GetTypeStr(meta.Type), meta => meta.Name); // ulong pid, string newName var parasSig = Generator.GenSelect( paraSig.Many(",").Satisfy(meta => meta.Any()) , "".Unit <IEnumerable <ParameterMeta> >().Satisfy(meta => !meta.Any())); // SyncPositionMulticast(int groupId, Int32 x, Int32 y) var methodMulticast = " {0}(int groupId, {1});".Basic <MethodMeta>(meta => meta.Name, meta => parasSig.Code(meta.Parameters)); // AskChangeName(UInt64 pid, String newName); var methodWithoutReturnType = " {0}({1});".Basic <MethodMeta>(meta => meta.Name, meta => parasSig.Code(meta.Parameters)); // Task<bool> AskChangeName(ulong pid, string newName); var taskMethod = methodWithoutReturnType.CombineReverse(taskTypeName, meta => meta.ReturnType); // bool AskChangeName(ulong pid, string newName); var normalMethod = methodWithoutReturnType.CombineReverse(Generator.GenBasic <Type>(CoderHelper.GetTypeStr), meta => meta.ReturnType); // InvokeOperation<bool> AskChangeName(ulong pid, string newName); var invokeMethod = methodWithoutReturnType.CombineReverse(invokeTypeName, meta => meta.ReturnType); #endregion #region interface related // public interface ILogicClientInvoke{...} var invokeGenCoder = Generator.GenCombine(invokeName.WithPrefix("public interface "), invokeMethod.Many("\n").Brace(), meta => meta.Methods).Satisfy(meta => meta.Scope == ServiceScope.ClientToServer); // public interface ILoginNotifyImpl{...} var serverImplGenCoder = implName .WithPrefix("public interface ") .WithPostfix(": IRpcImplInstnce") .Combine(taskMethod.Many("\n").Brace(), meta => meta.Methods) .Satisfy(meta => meta.Scope != ServiceScope.ServerToClient); // public interface IClientLoginImpl{...} var clientImplGenCoder = implName .WithPrefix("public interface ") .WithPostfix(": IRpcImplInstnce") .Combine(normalMethod.Many("\n").Brace(), meta => meta.Methods) .Satisfy(meta => meta.Scope == ServiceScope.ServerToClient); #endregion #region delegate #region meta data // public const uint NotifyLogicServerWorking = 2001; var methodId = "public const uint {0} = {1};".Basic <MethodMeta>(meta => meta.Name, meta => meta.Id); // #region meta data ... #endregion var metaGenCoder = methodId.Many("\n").Brace().WithPrefix("private static class MethodId").Region("meta data"); #endregion #region constructor && forward //private readonly ServiceDelegateStub serviceDelegateStub; //public ClientLogicServiceDelegate(IDataSender dataSender) //{ // serviceDelegateStub = new ServiceDelegateStub(dataSender, ClientLogicSerializer.Instance, MetaData.GetServiceRoutingRule(AutoInit.ClientLogic)); // dataSender.RegisterDelegate(serviceDelegateStub, AutoInit.ClientLogic); //} var delegateConstructor = @"private readonly ServiceDelegateStub serviceDelegateStub; public {0}(IDataSender dataSender) {{serviceDelegateStub = new ServiceDelegateStub(dataSender, {1}.Instance, MetaData.GetServiceRoutingRule(AutoInit.{2})); dataSender.RegisterDelegate(serviceDelegateStub, AutoInit.{2});}} " .Basic <ServiceMeta>(meta => delegateName.Code(meta), meta => serializerName.Code(meta), meta => meta.Name); //private readonly string forwardKey; //private ClientLoginServiceDelegate(ServiceDelegateStub serviceDelegateStub, string forwardKey) //{ // this.forwardKey = forwardKey; // this.serviceDelegateStub = serviceDelegateStub; //} //public ClientLoginServiceDelegate Forward(byte[] sessionId) //{ // return new ClientLoginServiceDelegate(serviceDelegateStub, new Guid(sessionId).ToString()); //} var delegateForward = @"private readonly byte[] forwardKey; private {0}(ServiceDelegateStub serviceDelegateStub, byte[] forwardKey) {{this.forwardKey = forwardKey;this.serviceDelegateStub = serviceDelegateStub;}} public {0} Forward(byte[] forwardId) {{return new {0}(serviceDelegateStub, forwardId);}} " .Basic <ServiceMeta>( meta => delegateName.Code(meta)).Satisfy(meta => meta.Scope == ServiceScope.ServerToClient); var forwardKey = Generator.GenSelect( "forwardKey".Unit <ServiceMeta>().Satisfy(meta => meta.Scope == ServiceScope.ServerToClient) , "null".Unit()); #endregion // notify delegate // public void ServerMessageOk() var invokeMethodServerSig = "public {0} {1}({2})".Basic <MethodMeta>(meta => { if (meta.ReturnType == typeof(void)) { return("void"); } else { return("Task<" + CoderHelper.GetTypeStr(meta.ReturnType) + ">"); } }, meta => meta.Name, meta => parasSig.Code(meta.Parameters)); // public InvokeOperation<Boolean> AskLogin(UInt64 pid) var invokeMethodClientSig = "public {0} {1}({2})".Basic <MethodMeta>(meta => invokeTypeName.Code(meta.ReturnType), meta => meta.Name, meta => parasSig.Code(meta.Parameters)); // pid, newName var parasCall = "{0}".Basic <ParameterMeta>(meta => meta.Name).Many(","); var comma = Generator.GenSelect( ",".Unit <List <ParameterMeta> >().Satisfy(meta1 => meta1.Count > 0) , "".Unit <List <ParameterMeta> >().Satisfy(meta1 => meta1.Count == 0)); // MethodId.AskChangeName, forwardKey, pid, newName var invokeCall = "MethodId.{0}, {1}{2}{3}".Basic <MethodMeta>(meta => meta.Name, meta => forwardKey.Code(meta.ServiceMeta), meta => comma.Code(meta.Parameters), meta => parasCall.Code(meta.Parameters)); // server to client delegate && notify delegate // serviceDelegateStub.Notify(MethodId.NotifyLogicServerWorking, null, districts); var invokeNoReturnBody = Generator.GenSelect( "serviceDelegateStub.Notify{0};".Basic <MethodMeta>(meta => invokeCall.Bracket().Code(meta)).Satisfy( meta => meta.ServiceMeta.Type == ServiceType.Notify || meta.ServiceMeta.Type == ServiceType.Sync), "return serviceDelegateStub.{0}{1};".Basic <MethodMeta>(meta => invokeTaskCallName.Code(meta.ReturnType), meta => invokeCall.Bracket().Code(meta)) ); var multicastDelegate = "public void {0}Multicast(int groupId{1} {2})" .Basic <MethodMeta>(meta => meta.Name, meta => comma.Code(meta.Parameters), meta => parasSig.Code(meta.Parameters)) .Append( "serviceDelegateStub.Multicast(MethodId.{0}, groupId{1} {2});" .Basic <MethodMeta>(meta => meta.Name, meta => comma.Code(meta.Parameters), meta => parasCall.Code(meta.Parameters)).Brace()); // return serviceDelegateStub.Invoke<Boolean>(MethodId.AskAddMoney, null, pid, money); var invokeClientBody = "return serviceDelegateStub.{0}{1};".Basic <MethodMeta>(meta => invokeCallName.Code(meta.ReturnType), meta => invokeCall.Bracket().Code(meta)); //public void NotifyPlayerLoaded(UInt64 pid){this.Task(methodNotifyPlayerLoaded, pid);} var invokeNoReturnMethodGen = Generator.GenFunction(invokeMethodServerSig, invokeNoReturnBody, Generator.Id); var invokeClientMethodGen = Generator.GenFunction(invokeMethodClientSig, invokeClientBody, Generator.Id); var delegateMethod = Generator.GenSelect( invokeClientMethodGen.Satisfy( meta => meta.ServiceMeta.Scope == ServiceScope.ClientToServer && client) , invokeNoReturnMethodGen); var delegateCoder = "public class {0}".Basic <ServiceMeta>(meta => delegateName.Code(meta)) .Append(": {0}".Basic <ServiceMeta>(meta => invokeName.Code(meta)) .Satisfy(meta => meta.Scope == ServiceScope.ClientToServer && client)) .Append(delegateConstructor.Append(delegateForward) .Combine(metaGenCoder, meta => meta.Methods) .Combine(delegateMethod.Many("\n"), meta => meta.Methods) .Combine(multicastDelegate.Satisfy(meta => meta.ServiceMeta.Multicast && !client).Many("\n"), meta => meta.Methods).Brace()); #endregion // case 1001: var label = "case {0}:".Basic <MethodMeta>(meta => meta.Id); #region dispatcher // (ulong)method.Args[0] var unboxedArg = "({0})(method.Args[{1}])".Basic <ParameterMeta>(meta => CoderHelper.GetTypeStr(meta.Type), meta => meta.Position); // (UInt64)method.Args[0], (String)method.Args[1] var unboxedArgs = unboxedArg.Many(","); // AskChangeName((UInt64)method.Args[0], (String)method.Args[1]) var dispatchMethod = "{0}".Basic <MethodMeta>(meta => meta.Name).Combine(unboxedArgs.Bracket(), meta => meta.Parameters); // public static readonly ClientLogicDispatcher Instance = new ClientLogicDispatcher(); var dispatcherSingleton = "public static readonly {0} Instance = new {0}();" .Basic <ServiceMeta>(meta => dispatcherName.Code(meta)); // (IDbSyncNotifyImpl)impl var implConvert = "({0})impl".Basic <ServiceMeta>(meta => implName.Code(meta)); // ((IDbSyncNotifyImpl)impl).NotifyPlayerLoaded((UInt64)method.Args[0]) var dispatchCall = "({0}).{1}".Basic <MethodMeta>(meta => implConvert.Code(meta.ServiceMeta), meta => dispatchMethod.Code(meta)); // case 4001: // ((ILoginClientImpl)impl).AskLogin((string)method.Args[0], (byte[])method.Args[1]).ContinueWith(t => DoContinue(t, cont)); // break; // case 5001: // ((IClientLogicImpl)impl).ServerMessageOk(); // break; var dispatchSwitch = label.Append( Generator.GenSelect( "{0}.ContinueWith(t=>DoContinue(t, cont));".Basic <MethodMeta>(meta => dispatchCall.Code(meta)).Satisfy(meta => meta.ServiceMeta.Scope != ServiceScope.ServerToClient && meta.ServiceMeta.Type != ServiceType.Notify) , "{0};".Basic <MethodMeta>(meta => dispatchCall.Code(meta)))) .Append("break;".Unit <MethodMeta>()); var dispatchMethodAll = "public void Dispatch(IRpcImplInstnce impl, RpcMethod method, ServiceImplementStub.SendResult cont)" .Unit <ServiceMeta>() .Append( "switch (method.MethodId)" .Unit <ServiceMeta>() .Combine( dispatchSwitch.Many("\n").Brace(), meta => meta.Methods) .Brace()); var dispatcherCoder = "public class {0} : " .Basic <ServiceMeta>(meta => dispatcherName.Code(meta)) .Append("ServiceMethodDispatcherEx, ".Unit <ServiceMeta>().Satisfy(meta => !client)) .Append("IServiceMethodDispatcher".Unit <ServiceMeta>()) .Append( dispatcherSingleton.Append(dispatchMethodAll).Brace()); #endregion #region serializer // public static readonly ClientLogicSerializer Instance = new ClientLogicSerializer(); var serializerSingleton = "public static readonly {0} Instance = new {0}();" .Basic <ServiceMeta>(meta => serializerName.Code(meta)); var methodArgsGetter = "method.Args[{0}]".Basic <ParameterMeta>(meta => meta.Position); var argsGetter = "args[{0}]".Basic <ParameterMeta>(meta => meta.Position, meta => CoderHelper.GetTypeStr(meta.Type)); var readArgCheck = CoderHelper.ReadWithCheckCoder <ParameterMeta>() .Lift( (ParameterMeta meta) => new Tuple <Type, ICoder <ParameterMeta>, ParameterMeta>(meta.Type, methodArgsGetter, meta)); var writeArgCheck = CoderHelper.WriteWithCheckCoder <ParameterMeta>() .Lift( (ParameterMeta meta) => new Tuple <Type, ICoder <ParameterMeta>, ParameterMeta>(meta.Type, argsGetter, meta)); var readSwitch = label .Append( "method.Args = new object[{0}];".Basic <MethodMeta>(meta => meta.Parameters.Count).Satisfy(meta => meta.Parameters.Count > 0) .Combine(readArgCheck.Many("\n"), meta => meta.Parameters)) //.Append( // "method.NeedReturn = true;" // .Unit<MethodMeta>() // .Satisfy(meta => meta.ServiceMeta.Type == ServiceType.Service)) .Append( "break;".Unit <MethodMeta>()); var readDispatchGen = "public RpcMethod Read(BinaryReader br)".Unit <ServiceMeta>() .Append( "RpcMethod method = new RpcMethod();\nmethod.MethodId = br.ReadUInt32();\n".Unit <ServiceMeta>() .Append( "switch (method.MethodId)".Unit <ServiceMeta>() .Combine( readSwitch.Many("\n").Brace(), meta => meta.Methods)) .Append( "return method;".Unit <ServiceMeta>()).Brace()); var writeSwitch = label .Combine( writeArgCheck.Many("\n").WithPostfix("break;").Brace(), meta => meta.Parameters); var writeDispatchGen = "public void Write(uint methodId, object[] args, BinaryWriter bw)" .Unit <ServiceMeta>() .Append( "bw.Write(methodId);\n" .Unit <ServiceMeta>() .Append("switch (methodId)" .Unit <ServiceMeta>() .Combine( writeSwitch.Many("\n").Brace(), meta => meta.Methods)).Brace()); var readReturnWithCheck = CoderHelper.ReadWithCheckCoder <MethodMeta>() .Lift( (MethodMeta meta) => new Tuple <Type, ICoder <MethodMeta>, MethodMeta>(meta.ReturnType, "returnVal".Unit <MethodMeta>(), meta)); var readReturnSwitch = label .Append(readReturnWithCheck.WithPostfix("break;").Brace()).Satisfy(meta => meta.ReturnType != typeof(void)); var readReturnDispatch = "public object ReadReturn(uint methodId, BinaryReader br)".Unit <ServiceMeta>() .Append( ( ("var returnVal = new object();\n").Unit <ServiceMeta>() .Append( "switch (methodId)".Unit <ServiceMeta>() .Combine(readReturnSwitch.Many("\n").Brace(), meta => meta.Methods) .Satisfy(meta => meta.Methods.Any(m => m.ReturnType != typeof(void)))) .Append("return returnVal;".Unit <ServiceMeta>()) .Brace() )); var writeValueWithCheck = CoderHelper.WriteWithCheckCoder <MethodMeta>() .Lift( (MethodMeta meta) => new Tuple <Type, ICoder <MethodMeta>, MethodMeta>(meta.ReturnType, "value".Unit <MethodMeta>(), meta)); var writeReturnSwitch = label .Append(writeValueWithCheck) .Append("break;".Unit <MethodMeta>()) .Satisfy(meta => meta.ReturnType != typeof(void)); var writeReturnDispatch = "public void WriteReturn(RpcMethod method, BinaryWriter bw, object value)".Unit <ServiceMeta>() .Append(( "switch (method.MethodId)".Unit <ServiceMeta>() .Combine( writeReturnSwitch.Many("\n").Brace(), meta => meta.Methods)).Satisfy(meta => meta.Methods.Any(m => m.ReturnType != typeof(void))).Brace()); var serializerCoder = "public class {0} : IMethodSerializer".Basic <ServiceMeta>(meta => serializerName.Code(meta)) .Append( serializerSingleton .Append(readDispatchGen.SkipLine()) .Append(writeDispatchGen.SkipLine()) .Append(readReturnDispatch.SkipLine()) .Append(writeReturnDispatch.SkipLine()) .Brace()); #endregion #region serviceMeta var implMetaInit = @"MetaData.SetServiceId(typeof({0}), {1}); MetaData.SetMethodSerializer(typeof({0}), {2}.Instance); MetaData.SetServiceMethodDispatcher(typeof({0}), {3}.Instance); " .Basic <ServiceMeta>( meta => implName.Code(meta) , meta => meta.Name , meta => serializerName.Code(meta) , meta => dispatcherName.Code(meta)) .Satisfy(meta => (meta.Scope == ServiceScope.ServerToClient && client) || (meta.Scope != ServiceScope.ServerToClient && !client)); var autoInitName = "internal const string {0} = \"{0}\";".Basic <ServiceMeta>(meta => meta.Name); var implBindingKey = Generator.GenSelect( "ImplBindingKey = (districts, uuid) => \"padding.{0}.notify\",\n".Basic <ServiceMeta>( meta => meta.Name) .Satisfy(meta => meta.Type == ServiceType.Notify) , "ImplBindingKey = (districts, uuid) => string.Format(\"{{0}}/{0}/sync/{{1}}\", districts, uuid),\n" .Basic <ServiceMeta>(meta => meta.Name) .Satisfy( meta => meta.Type == ServiceType.Sync && meta.Scope == ServiceScope.ServerToClient && client) , Generator.GenSelect( "ImplBindingKey = (districts, uuid) => string.Format(\"{{0}}.{0}.invoke\", districts),\n" .Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "ImplBindingKey = (districts, uuid) => string.Format(\"padding.{0}.invoke\"),\n" .Basic <ServiceMeta>(meta => meta.Name)) .Satisfy(meta => meta.Scope == ServiceScope.ClientToServer && !client) , Generator.GenSelect( Generator.GenSelect( "ImplBindingKey = (districts, uuid) => string.Format(\"{{0}}.{0}.invoke\", districts),\n".Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "ImplBindingKey = (districts, uuid) => string.Format(\"padding.{0}.invoke\", districts),\n".Basic <ServiceMeta>(meta => meta.Name) ).Satisfy(meta => meta.Type == ServiceType.Service)) .Satisfy(meta => meta.Scope == ServiceScope.InterServer) ); var delegateRoutingKey = Generator.GenSelect( "DelegateRoutingKey = (districts, fid) => \"padding.{0}.notify\",\n".Basic <ServiceMeta>(meta => meta.Name) .Satisfy(meta => meta.Type == ServiceType.Notify) , "DelegateRoutingKey = (districts, uuid) => string.Format(\"{{0}}.{0}.sync.{{1}}\", districts, uuid),\n".Basic <ServiceMeta>(meta => meta.Name) .Satisfy(meta => meta.Type == ServiceType.Sync && meta.Scope == ServiceScope.ServerToClient && !client) , Generator.GenSelect( "DelegateRoutingKey = (districts, uuid) => string.Format(\"{{0}}/{0}/invoke\", districts),\n".Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "DelegateRoutingKey = (districts, uuid) => string.Format(\"padding/{0}/invoke\"),\n".Basic <ServiceMeta>(meta => meta.Name)) .Satisfy(meta => meta.Scope == ServiceScope.ClientToServer && client) , Generator.GenSelect( Generator.GenSelect( "DelegateRoutingKey = (districts, uuid) => string.Format(\"{{0}}.{0}.invoke\", districts),\n".Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "DelegateRoutingKey = (districts, uuid) => string.Format(\"padding.{0}.invoke\", districts),\n".Basic <ServiceMeta>(meta => meta.Name) ).Satisfy(meta => meta.Type == ServiceType.Service)) .Satisfy(meta => meta.Scope == ServiceScope.InterServer) ); var returnBindKey = Generator.GenSelect( Generator.GenSelect( "ReturnBindingKey = (districts, uuid) => string.Format(\"{{0}}/{0}/return/{{1}}\", districts, uuid),\n" .Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "ReturnBindingKey = (districts, uuid) => string.Format(\"padding/{0}/return/{{0}}\", uuid),\n" .Basic <ServiceMeta>(meta => meta.Name)) .Satisfy(meta => meta.Scope == ServiceScope.ClientToServer && client) , Generator.GenSelect( Generator.GenSelect( "ReturnBindingKey = (districts, uuid) => string.Format(\"{{0}}.{0}.return.{{1}}\", districts, uuid),\n" .Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "ReturnBindingKey = (districts, uuid) => string.Format(\"padding.{0}.return.{{1}}\", districts, uuid),\n" .Basic <ServiceMeta>(meta => meta.Name) ).Satisfy(meta => meta.Type == ServiceType.Service)) .Satisfy(meta => meta.Scope == ServiceScope.InterServer) ); var returnRoutingKey = Generator.GenSelect( Generator.GenSelect( "ReturnRoutingKey = (districts, uuid) => string.Format(\"{{0}}.{0}.return.{{1}}\", districts, uuid),\n" .Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "ReturnRoutingKey = (districts, uuid) => string.Format(\"padding.{0}.return.{{0}}\", uuid),\n" .Basic <ServiceMeta>(meta => meta.Name)) .Satisfy(meta => meta.Scope == ServiceScope.ClientToServer && !client) , Generator.GenSelect( Generator.GenSelect( "ReturnRoutingKey = (districts, uuid) => string.Format(\"{{0}}.{0}.return.{{1}}\", districts, uuid),\n" .Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "ReturnRoutingKey = (districts, uuid) => string.Format(\"padding.{0}.return.{{1}}\", districts, uuid),\n" .Basic <ServiceMeta>(meta => meta.Name) ).Satisfy(meta => meta.Type == ServiceType.Service)) .Satisfy(meta => meta.Scope == ServiceScope.InterServer)); var returnExchange = Generator.GenSelect( "ReturnExchangeName = () => \"amq.topic\",\n".Unit <ServiceMeta>() .Satisfy(meta => meta.Scope == ServiceScope.ClientToServer && !client), "ReturnExchangeName = () => \"{0}.return\",\n".Basic <ServiceMeta>(meta => meta.Name) .Satisfy(meta => meta.Scope == ServiceScope.InterServer) ).Satisfy(meta => meta.Type == ServiceType.Service); var delegateExchange = Generator.GenSelect( "DelegateExchangeName = () => \"amq.topic\",\n".Unit <ServiceMeta>() .Satisfy(meta => meta.Scope == ServiceScope.ServerToClient && !client) , "DelegateExchangeName = () => \"{0}.notify\",\n".Basic <ServiceMeta>(meta => meta.Name) .Satisfy(meta => meta.Type == ServiceType.Notify && !client) , "DelegateExchangeName = () => \"{0}.invoke\",\n".Basic <ServiceMeta>(meta => meta.Name) .Satisfy(meta => meta.Type == ServiceType.Service && meta.Scope == ServiceScope.InterServer && !client)); var implExchange = Generator.GenSelect( "ImplExchangeName = () => \"{0}.notify\",\n".Basic <ServiceMeta>(meta => meta.Name) .Satisfy(meta => meta.Type == ServiceType.Notify && !client), "ImplExchangeName = () => \"{0}.invoke\",\n".Basic <ServiceMeta>(meta => meta.Name) .Satisfy(meta => meta.Type == ServiceType.Service && !client)); var implQueueName = Generator.GenSelect( "ImplQueueName = districts=>string.Format(\"{{0}}.{0}.invoke\", districts),\n" .Basic <ServiceMeta>( meta => serviceName.Code(meta)).Satisfy(meta => meta.Divisional) , "ImplQueueName = districts => string.Format(\"padding.{0}.invoke\"),\n".Basic <ServiceMeta>( meta => serviceName.Code(meta))) .Satisfy(meta => meta.Type == ServiceType.Service && !client); var publishKey = Generator.GenSelect( "PublishKey = (districts, uuid) => string.Format(\"{{0}}/{0}/invoke\", districts),\n" .Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "PublishKey = (districts, uuid) => string.Format(\"padding/{0}/invoke\"),\n" .Basic <ServiceMeta>(meta => meta.Name)) .Satisfy(meta => meta.Scope == ServiceScope.ClientToServer && client); var subscribeKey = Generator.GenSelect( "SubscribeKey = (districts, uuid) => string.Format(\"{{0}}/{0}/sync/{{1}}\", districts, uuid),\n" .Basic <ServiceMeta>(meta => meta.Name) .Satisfy(meta => meta.Type == ServiceType.Sync && meta.Scope == ServiceScope.ServerToClient && client) , Generator.GenSelect( "SubscribeKey = (districts, uuid) => string.Format(\"{{0}}/{0}/return/{{1}}\", districts, uuid),\n" .Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "SubscribeKey = (districts, uuid) => string.Format(\"padding/{0}/return/{{0}}\", uuid),\n" .Basic <ServiceMeta>(meta => meta.Name)) .Satisfy(meta => meta.Scope == ServiceScope.ClientToServer && client)); var zkServicePath = Generator.GenSelect( "ServicePath = (districts) => string.Format(\"/{{0}}/{{1}}\", districts, {0}),\n" .Basic <ServiceMeta>(meta => meta.Name).Satisfy(meta => meta.Divisional) , "ServicePath = (districts) => string.Format(\"/global/{{1}}\", districts, {0}),\n" .Basic <ServiceMeta>(meta => meta.Name)); var gateServiceId = "ServiceId = s => {0}," .Basic <ServiceMeta>(meta => meta.Id); var amqpRule = "AmqpRule = new RoutingRule.AmqpRoutingRule()" .Unit <ServiceMeta>() .Append( implBindingKey .Append(delegateRoutingKey) .Append(returnBindKey) .Append(returnRoutingKey) .Append(returnExchange) .Append(delegateExchange) .Append(implExchange) .Append(implQueueName) .Brace()).WithPostfix(","); var mqttRule = "MqttRule = new RoutingRule.MqttRoutingRule()" .Unit <ServiceMeta>() .Append( publishKey .Append(subscribeKey) .Brace()).WithPostfix(","); var gateRule = "GateRule = new RoutingRule.GateRoutingRule()" .Unit <ServiceMeta>() .Append( gateServiceId .Brace()).WithPostfix(","); var zkRule = "ZkRule = new RoutingRule.ZkRoutingRule()" .Unit <ServiceMeta>() .Append( zkServicePath .Brace()).WithPostfix(","); var metaBuilder = "MetaData.SetServiceRoutingRule({0}, new RoutingRule()" .Basic <ServiceMeta>(meta => meta.Name) .Append( amqpRule.SkipLine().Satisfy(_ => !client) .Append(mqttRule.SkipLine().Satisfy(_ => client)) .Append(gateRule.SkipLine()) .Append(zkRule.SkipLine().Satisfy(_ => !client)) .Brace().WithPostfix(");")); var metaConstructor = implMetaInit.Many("\n").Append(metaBuilder.Many("\n")).Brace().WithPrefix("\nstatic AutoInit()"); var metaCoder = autoInitName.Many("\n") .Append(metaConstructor) .Append( "public static void Init(){}".Unit <IEnumerable <ServiceMeta> >()) .Brace().WithPrefix("\npublic static class AutoInit"); #endregion var serviceCoder = invokeGenCoder.Satisfy(_ => client) .Append(clientImplGenCoder.Satisfy(meta => client).SkipLine()) .Append(serverImplGenCoder.Satisfy(meta => !client).SkipLine()) .Append(delegateCoder.Satisfy(meta => (meta.Scope == ServiceScope.ClientToServer && client) || (meta.Scope != ServiceScope.ClientToServer && !client)).WithPostfix("\n")) .Append(dispatcherCoder.Satisfy(meta => (meta.Scope != ServiceScope.ServerToClient && !client) || (meta.Scope == ServiceScope.ServerToClient && client)).WithPostfix("\n")) .Append(serializerCoder.SkipLine()); var serviceWithRegion = "#region {0}\n{1}#endregion".Basic <ServiceMeta>(serviceName.Code, serviceCoder.Code); return (metaCoder.WithPostfix("\n") .Append(serviceWithRegion.Many("\n"))); }