ICoder <IEnumerable <ModelMeta> > GenDataAccessCoder() { Func <FieldMeta, bool> isKey = meta => meta.ModelMeta.Key == meta; var loadFieldMethodName = "Load{0}At{1}Async".Basic <FieldMeta>(meta => meta.Name, meta => meta.ModelMeta.Name); var updateFieldMethodName = "Update{0}At{1}".Basic <FieldMeta>(meta => meta.Name, meta => meta.ModelMeta.Name); var fieldPara = "{0} {1}".Basic <FieldMeta>(meta => CoderHelper.GetTypeStr(meta.Type), meta => meta.Name.ToLower()); var modelFieldPara = "{0} {1}".Basic <ModelMeta>(meta => CoderHelper.GetTypeStr(meta.Type), meta => meta.Name.ToLower()); // Task<uint> LoadUidAtPlayerInfoAsync() var loadField = "{0} {1}()".Basic <FieldMeta>(meta => CoderHelper.TaskTypeCoder().Code(meta.Type), loadFieldMethodName.Code); // void UpdateUidAtPlayerInfo(uint uid) var updateField = "void {0}({1})".Basic <FieldMeta>(updateFieldMethodName.Code, meta => fieldPara.Code(meta)); // Task<PlayerInfo> LoadPlayerInfoAsync(ulong pid) var loadModel = "{0} Load{1}Async()".Basic <FieldMeta>(meta => CoderHelper.TaskTypeCoder().Code(meta.ModelMeta.Type), meta => meta.ModelMeta.Name); // void UpdatePlayerInfo(PlayerInfo info) var updateModel = "void Update{0}({1})".Basic <FieldMeta>(meta => meta.ModelMeta.Name, meta => modelFieldPara.Code(meta.ModelMeta)); // ISessionReader var readInterfaceName = "I{0}Reader".Basic <ModelMeta>(meta => meta.Name); // ISessionAccesser var accessInterfaceName = "I{0}Accesser".Basic <ModelMeta>(meta => meta.Name); // public interface ISessionReader : IDisposable{...} var readInterface = "public interface {0}: IDisposable" .Basic <ModelMeta>(meta => readInterfaceName.Code(meta)) .Combine( Generator.GenSelect(loadModel.Satisfy(isKey), loadField) .Statement() .Many("\n") .Brace() , meta => meta.Fields); // public interface ISessionAccesser : ISessionReader, ISubmitChangable{...} var accessInterface = "public interface {0}: {1}, ISubmitChangable" .Basic <ModelMeta>(meta => accessInterfaceName.Code(meta), meta => readInterfaceName.Code(meta)) .Combine( Generator.GenSelect(updateModel.Satisfy(isKey), updateField) .Statement() .Many("\n") .Brace() , meta => meta.Fields); var modelAllFields = "#region {0}".Basic <ModelMeta>(meta => meta.Name) .SkipLine() .Combine( Generator.GenSelect(loadModel.Satisfy(isKey), loadField) .Statement() .Many("\n") , meta => meta.Fields) .Combine( Generator.GenSelect(updateModel.Satisfy(isKey), updateField) .Statement() .Many("\n") , meta => meta.Fields) .SkipLine() .WithPostfix("#endregion\n"); // var val = new PlayerInfo(); // var val = default(UInt); var val = Generator.GenSelect( "var val = default({0});".Basic <Type>(CoderHelper.GetTypeStr).Satisfy(meta => meta.IsPrimitive || meta == typeof(string) || meta.IsArray) //, "byte[] val = null;".Unit<Type>().Satisfy(meta=>meta == typeof(byte[])) , "var val = new {0}();".Basic <Type>(CoderHelper.GetTypeStr)); // default(T) / null var failVal = Generator.GenSelect( "default({0})".Basic <Type>(CoderHelper.GetTypeStr).Satisfy(meta => meta.IsPrimitive || meta == typeof(string) || meta.IsEnum) , "null".Unit <Type>()); // reader.ReadField<UInt64>("Pid");/(TowerState)reader.ReadField<Int32>("Test"); var readField = Generator.GenSelect( "({0})reader.ReadField<Int32>(\"{1}\");".Basic <FieldMeta>(meta => CoderHelper.GetTypeStr(meta.Type), meta => meta.Name).Satisfy(meta => meta.Type.IsEnum) , "reader.ReadField<{0}>(\"{1}\");".Basic <FieldMeta>(meta => CoderHelper.GetTypeStr(meta.Type), meta => meta.Name)); // val = reader.ReadField<UInt64>("Pid"); var fieldReadField = "val = {0}".Basic <FieldMeta>(readField.Code); // val.Pid = reader.ReadField<UInt64>("Pid"); var modelReadField = "val.{0} = {1}".Basic <FieldMeta>(meta => meta.Name, readField.Code); // val.Pid = (ulong)key; var modelReadKeyField = "val.{0} = ({1})key;".Basic <FieldMeta>(meta => meta.Name, meta => CoderHelper.GetTypeStr(meta.Type)); var fieldReader = Generator.GenSelect( "".Unit <FieldMeta>() .Combine(Generator.GenSelect(modelReadKeyField.Satisfy(isKey), modelReadField).Many("\n"), meta => meta.ModelMeta.Fields) .Satisfy(isKey) , fieldReadField); var fieldModelGetter = "(Int32)".Unit <FieldMeta>().Satisfy(meta => meta.Type.IsEnum) .Append("{1}.{0}".Basic <FieldMeta>(meta => meta.Name, meta => meta.ModelMeta.Name.ToLower())); var fieldGetter = "(Int32)".Unit <FieldMeta>().Satisfy(meta => meta.Type.IsEnum) .Append("{0}".Basic <FieldMeta>(meta => meta.Name.ToLower())); // .WriteField("InfoSkill", infoskill) var writeField = ".WriteField(\"{0}\", {1})".Basic <FieldMeta>(meta => meta.Name, fieldGetter.Code); // .WriteField("{0}", ({1})key) var writeKey = ".WriteField(\"{0}\", ({1})key)".Basic <FieldMeta>(meta => meta.Name, meta => CoderHelper.GetTypeStr(meta.Type)); // .WriteField("Pid", playerinfo.Pid) var writeFieldModel = ".WriteField(\"{0}\", {1})".Basic <FieldMeta>(meta => meta.Name, fieldModelGetter.Code); Func <bool, ICoder <FieldMeta> > writer = isRedis => { return("var ctx = adaptor.Update(dataId);\n\nctx".Unit <FieldMeta>() .SkipLine() .Append(Generator.GenSelect( "".Unit <FieldMeta>().Combine(Generator.GenSelect( writeFieldModel.Satisfy(isKey), writeFieldModel).Many("\n"), meta => meta.ModelMeta.Fields).Satisfy(isKey) , "{0}".Basic <FieldMeta>(meta => writeKey.Code(meta.ModelMeta.Key)) .SkipLine().Satisfy(meta => !isRedis) .Append(writeField))) .SkipLine() .Append( ";\nupdateQueue.Add(ctx);".Unit <FieldMeta>())); }; var updateSig = Generator.GenSelect(updateModel.Satisfy(isKey), updateField).WithPrefix("public "); var loadSig = Generator.GenSelect(loadModel.Satisfy(isKey), loadField).WithPrefix("public async "); #region redis // var dataId = string.Format("player:{0}", id); var key = "var dataId = string.Format(\"{0}:{{0}}\", {1});".Basic <FieldMeta>( meta => meta.ModelMeta.RedisCacheName, meta => meta.ModelMeta.Key.Name.ToLower()); var redisReader = Generator.GenSelect( "var reader = await adaptor.QueryAll(dataId);if (reader == null){{return {0};}}".Basic <FieldMeta>(meta => failVal.Code(meta.ModelMeta.Type)) .Satisfy(isKey) , "var reader = await adaptor.Query(dataId, \"{0}\");if (reader == null){{return {1};}}" .Basic <FieldMeta>(meta => meta.Name, meta => failVal.Code(meta.Type))); var redisUpdateLast = "return await adaptor.UpdateWork({0});".Basic <FieldMeta>(meta => meta.ModelMeta.Key.Name.ToLower()); var redisUpdate = updateSig.Append( writer(true) /*.Append(redisUpdateLast)*/.Brace()); var redisLoad = loadSig.Append( Generator.GenSelect( "{0}".Basic <FieldMeta>(meta => val.Code(meta.ModelMeta.Type)).Satisfy(isKey) , "".Unit <FieldMeta>().Combine(val, meta => meta.Type)).Append(redisReader).Append(fieldReader).WithPostfix("return val;").Brace()); var interfaceInherit = accessInterfaceName.Many(","); var delegateInnerRedisSpecial = @"public async Task<bool> SubmitChanges() { await adaptor.SubmitChanges( new[] { dataId } , new[] { contextLockId } , new [] {updateQueue}); return true; } public async Task<bool> SubmitChangesWith(params object[] others) { await adaptor.SubmitChanges( new[] { dataId } .Concat(others.Select(d => ((DelegateBase)d).dataId)).ToArray(), new[] { contextLockId } .Concat(others.Select(d => ((DelegateBase)d).contextLockId)).ToArray(), new[] { updateQueue } .Concat(others.Select(d => ((DelegateBase)d).updateQueue)).ToArray()); return true; } public void Dispose() { } ".Unit(); var redisDelegateInner = @"class Delegate<TKey> : DelegateBase, {0} {{ public Delegate(RedisAdaptor adaptor, long contextLockId, TKey key, string dataId) {{ this.adaptor = adaptor; this.contextLockId = contextLockId; this.key = key; this.dataId = dataId; }} {2} private readonly RedisAdaptor adaptor; private readonly object key; {1} }}" .Basic <IEnumerable <ModelMeta> >( interfaceInherit.Code, "#region {0}\n{1}\n#endregion\n".Basic <ModelMeta>(meta => meta.Name, meta => redisUpdate.Many("\n").SkipLine().Append(redisLoad.Many("\n")).Code(meta.Fields)).Many("\n").Code, delegateInnerRedisSpecial.Code); var modelReaderGetter = "public async Task<I{0}Reader> Get{0}Reader({1} {2}){{var dataId = string.Format(\"{3}:{{0}}\", {2});var lockId = 0;return new Delegate<{1}>(adaptor, lockId, {2}, dataId);}}" .Basic <ModelMeta>( meta => meta.Name , meta => CoderHelper.GetTypeStr(meta.Key.Type) , meta => meta.Key.Name.ToLower() , meta => meta.Name.ToLower()); var modelAccesserGetter = "public async Task<I{0}Accesser> Get{0}Accesser({1} {2}){{var dataId = string.Format(\"{3}:{{0}}\", {2});var lockId = await adaptor.LockKey(dataId);return new Delegate<{1}>(adaptor, lockId, {2}, dataId);}}" .Basic <ModelMeta>( meta => meta.Name , meta => CoderHelper.GetTypeStr(meta.Key.Type) , meta => meta.Key.Name.ToLower() , meta => meta.Name.ToLower()); var redisDelegate = "public class RedisDataServiceDelegate {{\n{0}\n{1}\n\nprivate readonly RedisAdaptor adaptor;public RedisDataServiceDelegate(RedisAdaptor adaptor){{this.adaptor = adaptor;}}\n }}" .Basic <IEnumerable <ModelMeta> >( redisDelegateInner.Code , modelReaderGetter.SkipLine().Append(modelAccesserGetter).Many("\n").Code); #endregion #region mysql // `Pid`, `Uid`, `Name`, `Level`, `InfoSkill` ,`InfoItem` var fields = Generator.GenSelect( "".Unit <FieldMeta>() .Combine("`{0}`".Basic <FieldMeta>(meta => meta.Name).Many(","), meta => meta.ModelMeta.Fields) .Satisfy(meta => meta.ModelMeta.Key == meta) , "`{0}`".Basic <FieldMeta>(meta => meta.Name)); // const string sql = "SELECT `Pid`, `Uid`, `Name`, `Level`, `InfoSkill` ,`InfoItem` FROM `mem_player` WHERE `Pid` = ?1"; var querySql = "const string sql = \"SELECT {0} FROM `{1}` WHERE `{2}` = ?1\";" .Basic <FieldMeta>(fields.Code, meta => meta.ModelMeta.MysqlTableName, meta => meta.ModelMeta.Key.Name); var mysqlReader = Generator.GenSelect( "var reader = await adaptor.Query(sql, ({0})key);if (reader == null){{return {1};}}" .Basic <FieldMeta>(meta => CoderHelper.GetTypeStr(meta.ModelMeta.Key.Type), meta => failVal.Code(meta.ModelMeta.Type)) .Satisfy(isKey) , "var reader = await adaptor.Query(sql, ({0})key);if (reader == null){{return {1};}}" .Basic <FieldMeta>(meta => CoderHelper.GetTypeStr(meta.ModelMeta.Key.Type), meta => failVal.Code(meta.Type))); var updateSqlKeyString = "INSERT INTO `{0}`({1}) VALUES({2}) ON DUPLICATE KEY UPDATE {3}".Basic <FieldMeta>( meta => meta.ModelMeta.MysqlTableName , "".Unit <FieldMeta>() .Combine("`{0}`".Basic <FieldMeta>(meta => meta.Name).Many(","), meta => meta.ModelMeta.Fields) .Code , "".Unit <FieldMeta>() .Combine("?{0}".Basic <FieldMeta>(meta => meta.Position).Many(","), meta => meta.ModelMeta.Fields) .Code , "".Unit <FieldMeta>() .Combine( "`{0}`=?{1}".Basic <FieldMeta>(meta => meta.Name, meta => meta.Position) .Many(",", meta => !isKey(meta)), meta => meta.ModelMeta.Fields) .Code); var updateSqlFieldString = "UPDATE `{0}` SET `{1}`=?2 WHERE `{2}`=?1".Basic <FieldMeta>( meta => meta.ModelMeta.MysqlTableName, meta => meta.Name, meta => meta.ModelMeta.Key.Name); var updateSql = "const string dataId = \"{0}\"; ".Basic <FieldMeta>(Generator.GenSelect( updateSqlKeyString.Satisfy(isKey), updateSqlFieldString).Code); var mysqlUpdate = updateSig.Append( Generator.GenSelect( updateSql.Append(writer(false)).Satisfy(meta => meta.ModelMeta.MysqlTableName != null) , "throw new Exception();".Unit <FieldMeta>()) .Brace()); var mysqlLoad = loadSig.Append( Generator.GenSelect( querySql.Append(Generator.GenSelect( "{0}".Basic <FieldMeta>(meta => val.Code(meta.ModelMeta.Type)).Satisfy(isKey) , "".Unit <FieldMeta>().Combine(val, meta => meta.Type))).Append(mysqlReader).Append(fieldReader).WithPostfix("reader.Dispose();\nreturn val;").Satisfy(meta => meta.ModelMeta.MysqlTableName != null) , "throw new Exception();".Unit <FieldMeta>()) .Brace()); var delegateInnerMysqlSpecial = @" public Task<bool> SubmitChanges() { throw new NotImplementedException(); } public Task<bool> SubmitChangesWith(params object[] others) { throw new NotImplementedException(); } public void Dispose() { } ".Unit(); var mysqlDelegateInner = @"class Delegate<TKey> : {0} {{ public Delegate(MysqlAdaptor adaptor, TKey key) {{ this.adaptor = adaptor; this.key = key; }} {2} private readonly MysqlAdaptor adaptor; private readonly object key; private readonly List<IUpdateDataContext> updateQueue = new List<IUpdateDataContext>(); {1} }}" .Basic <IEnumerable <ModelMeta> >( accessInterfaceName.Many(",", m => m.MysqlTableName != null).Code, "#region {0}\n{1}\n#endregion\n".Basic <ModelMeta>(meta => meta.Name, meta => mysqlUpdate.Many("\n").SkipLine().Append(mysqlLoad.Many("\n")).Code(meta.Fields)).Many("\n", m => m.MysqlTableName != null).Code, delegateInnerMysqlSpecial.Code); Func <string, ICoder <ModelMeta> > mysqlModelGetter = interfaceType => { return(string.Format("public async Task<I{{0}}{0}> Get{{0}}{0}({{1}} {{2}}){{{{return new Delegate<{{1}}>(adaptor, {{2}});}}}}" , interfaceType) .Basic <ModelMeta>( meta => meta.Name , meta => CoderHelper.GetTypeStr(meta.Key.Type) , meta => meta.Key.Name.ToLower() , meta => meta.Name.ToLower())); }; var mysqlModelReaderGetter = mysqlModelGetter("Reader"); var mysqlModelAccesserGetter = mysqlModelGetter("Accesser"); var mysqlDelegate = "public class MysqlDataServiceDelegate {{{0}\n{1}\n\nprivate readonly MysqlAdaptor adaptor;public MysqlDataServiceDelegate(MysqlAdaptor adaptor){{this.adaptor = adaptor;}}\n }}" .Basic <IEnumerable <ModelMeta> >( mysqlDelegateInner.Code , mysqlModelReaderGetter.SkipLine().Append(mysqlModelAccesserGetter).Many("\n", m => m.MysqlTableName != null).Code); #endregion var genCoder = readInterface.SkipLine().Append(accessInterface).Many("\n") .SkipLine(2) .Append(redisDelegate) .SkipLine(2) .Append(mysqlDelegate); return(genCoder); }
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"))); }