private void GenerateCommandCode() { #region collect var clearPath = Path.Combine(Application.dataPath, OutputPath, "Command"); if (Directory.Exists(clearPath)) { Directory.Delete(clearPath, true); } ushort serverCounter = 0; ushort clientCounter = 0; var compressors = new List <Tuple <string, float, float, float> >(); var serverCommands = new List <Tuple <string, ushort, string[], string[], bool[], bool[]> >(); var clientCommands = new List <Tuple <string, ushort, string[], string[], bool[], bool[]> >(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var type in assembly.GetTypes()) { var serverAttribute = type.GetCustomAttributes(typeof(CommandToServerAttribute), false); if (serverAttribute != null && serverAttribute.Length > 0) { var name = type.Name.Replace("Scheme", ""); var fields = type.GetFields(); var fieldTypes = new List <string>(); var fieldNames = new List <string>(); var isEnums = new List <bool>(); var isCompressed = new List <bool>(); foreach (var field in fields) { var compressed = false; switch (field.FieldType.ToString()) { case "System.Single": { var compressor = field.GetCustomAttribute <BoundedFloatAttribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"Client{name.Replace("Component", "")}{field.Name}", compressor.Min, compressor.Max, compressor.Precision)); compressed = true; } } break; case "UnityEngine.Vector2": { var compressor = field.GetCustomAttribute <BoundedVector2Attribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"Client{name.Replace("Component", "")}{field.Name}X", compressor.XMin, compressor.XMax, compressor.XPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"Client{name.Replace("Component", "")}{field.Name}Y", compressor.YMin, compressor.YMax, compressor.YPrecision)); compressed = true; } } break; case "UnityEngine.Vector3": { var compressor = field.GetCustomAttribute <BoundedVector3Attribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"Client{name.Replace("Component", "")}{field.Name}X", compressor.XMin, compressor.XMax, compressor.XPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"Client{name.Replace("Component", "")}{field.Name}Y", compressor.YMin, compressor.YMax, compressor.YPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"Client{name.Replace("Component", "")}{field.Name}Z", compressor.ZMin, compressor.ZMax, compressor.ZPrecision)); compressed = true; } } break; } isEnums.Add(field.FieldType.IsEnum); fieldTypes.Add(field.FieldType.ToString()); fieldNames.Add(field.Name); isCompressed.Add(compressed); } clientCommands.Add(new Tuple <string, ushort, string[], string[], bool[], bool[]>(name, clientCounter, fieldTypes.ToArray(), fieldNames.ToArray(), isEnums.ToArray(), isCompressed.ToArray())); clientCounter++; } var clientAttribute = type.GetCustomAttributes(typeof(CommandToClientAttribute), false); if (clientAttribute != null && clientAttribute.Length > 0) { var name = type.Name.Replace("Scheme", ""); var fields = type.GetFields(); var fieldTypes = new List <string>(); var fieldNames = new List <string>(); var isEnums = new List <bool>(); var isCompressed = new List <bool>(); foreach (var field in fields) { var compressed = false; switch (field.FieldType.ToString()) { case "System.Single": { var compressor = field.GetCustomAttribute <BoundedFloatAttribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"Server{name}{field.Name}", compressor.Min, compressor.Max, compressor.Precision)); compressed = true; } } break; case "UnityEngine.Vector2": { var compressor = field.GetCustomAttribute <BoundedVector2Attribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"Server{name}{field.Name}X", compressor.XMin, compressor.XMax, compressor.XPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"Server{name}{field.Name}Y", compressor.YMin, compressor.YMax, compressor.YPrecision)); compressed = true; } } break; case "UnityEngine.Vector3": { var compressor = field.GetCustomAttribute <BoundedVector3Attribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"Server{name}{field.Name}X", compressor.XMin, compressor.XMax, compressor.XPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"Server{name}{field.Name}Y", compressor.YMin, compressor.YMax, compressor.YPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"Server{name}{field.Name}Z", compressor.ZMin, compressor.ZMax, compressor.ZPrecision)); compressed = true; } } break; } isEnums.Add(field.FieldType.IsEnum); fieldTypes.Add(field.FieldType.ToString()); fieldNames.Add(field.Name); isCompressed.Add(compressed); } serverCommands.Add(new Tuple <string, ushort, string[], string[], bool[], bool[]>(name, serverCounter, fieldTypes.ToArray(), fieldNames.ToArray(), isEnums.ToArray(), isCompressed.ToArray())); serverCounter++; } } } #endregion #region execution interfaces var serverSystem = new SchemeCommandExecutorInterfaceGenerator(); var d = new Dictionary <string, object> { { "Using", "Client" }, { "Type", "Server" }, { "SchemeNames", clientCommands.Select(x => x.Item1).ToArray() } }; serverSystem.Session = d; serverSystem.Initialize(); var output = serverSystem.TransformText(); SaveFile("Command/Execution/", "IServerHandler.cs", output); var clientSystem = new SchemeCommandExecutorInterfaceGenerator(); d = new Dictionary <string, object> { { "Using", "Server" }, { "Type", "Client" }, { "SchemeNames", serverCommands.Select(x => x.Item1).ToArray() } }; clientSystem.Session = d; clientSystem.Initialize(); output = clientSystem.TransformText(); SaveFile("Command/Execution/", "IClientHandler.cs", output); #endregion #region executors var serverExecutor = new SchemeCommandExecutorGenerator(); d = new Dictionary <string, object> { { "Using", "Client" }, { "Type", "Server" }, { "SchemeNames", clientCommands.Select(x => x.Item1).ToArray() }, { "SchemeIds", clientCommands.Select(x => x.Item2).ToArray() } }; serverExecutor.Session = d; serverExecutor.Initialize(); output = serverExecutor.TransformText(); SaveFile("Command/Execution/", "ServerCommandExecutor.cs", output); var clientExecutor = new SchemeCommandExecutorGenerator(); d = new Dictionary <string, object> { { "Using", "Server" }, { "Type", "Client" }, { "SchemeNames", serverCommands.Select(x => x.Item1).ToArray() }, { "SchemeIds", serverCommands.Select(x => x.Item2).ToArray() } }; clientExecutor.Session = d; clientExecutor.Initialize(); output = clientExecutor.TransformText(); SaveFile("Command/Execution/", "ClientCommandExecutor.cs", output); #endregion #region commands foreach (var tuple in serverCommands) { var componentTemplate = new SchemeCommandGenerator(); d = new Dictionary <string, object> { { "Namespace", "Server" }, { "CommandName", tuple.Item1 }, { "CommandId", tuple.Item2 }, { "FieldTypes", tuple.Item3 }, { "FieldNames", tuple.Item4 }, { "IsEnums", tuple.Item5 }, { "IsCompressed", tuple.Item6 } }; componentTemplate.Session = d; componentTemplate.Initialize(); output = componentTemplate.TransformText(); SaveFile("Command/Server/", $"{tuple.Item1}Command.cs", output); } foreach (var tuple in clientCommands) { var componentTemplate = new SchemeCommandGenerator(); d = new Dictionary <string, object> { { "Namespace", "Client" }, { "CommandName", tuple.Item1 }, { "CommandId", tuple.Item2 }, { "FieldTypes", tuple.Item3 }, { "FieldNames", tuple.Item4 }, { "IsEnums", tuple.Item5 }, { "IsCompressed", tuple.Item6 } }; componentTemplate.Session = d; componentTemplate.Initialize(); output = componentTemplate.TransformText(); SaveFile("Command/Client/", $"{tuple.Item1}Command.cs", output); } #endregion #region compressors { var template = new CompressorsGenerator(); d = new Dictionary <string, object> { { "Prefix", "Command" }, { "CompressorNames", compressors.Select(x => x.Item1).ToArray() }, { "Mins", compressors.Select(x => x.Item2).ToArray() }, { "Maxs", compressors.Select(x => x.Item3).ToArray() }, { "Precisions", compressors.Select(x => x.Item4).ToArray() } }; template.Session = d; template.Initialize(); output = template.TransformText(); SaveFile("Command/Compressors/", "SyncCompressors.cs", output); } #endregion AssetDatabase.Refresh(); }
private void GenerateSyncCode() { #region collect var clearPath = Path.Combine(Application.dataPath, OutputPath, "Sync"); if (Directory.Exists(clearPath)) { Directory.Delete(clearPath, true); } ushort counter = 0; var compressors = new List <Tuple <string, float, float, float> >(); var components = new List <Tuple <string, ushort, string[], string[], bool[], bool[]> >(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var type in assembly.GetTypes()) { var syncAttributes = type.GetCustomAttributes(typeof(SyncAttribute), false); if (syncAttributes != null && syncAttributes.Length > 0) { var componentName = type.Name; var fields = type.GetFields(); var fieldTypes = new List <string>(); var fieldNames = new List <string>(); var isEnums = new List <bool>(); var isCompressed = new List <bool>(); foreach (var field in fields) { var compressed = false; switch (field.FieldType.ToString()) { case "System.Single": { var compressor = field.GetCustomAttribute <BoundedFloatAttribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}", compressor.Min, compressor.Max, compressor.Precision)); compressed = true; } } break; case "UnityEngine.Vector2": { var compressor = field.GetCustomAttribute <BoundedVector2Attribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}X", compressor.XMin, compressor.XMax, compressor.XPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}Y", compressor.YMin, compressor.YMax, compressor.YPrecision)); compressed = true; } } break; case "UnityEngine.Vector3": { var compressor = field.GetCustomAttribute <BoundedVector3Attribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}X", compressor.XMin, compressor.XMax, compressor.XPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}Y", compressor.YMin, compressor.YMax, compressor.YPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}Z", compressor.ZMin, compressor.ZMax, compressor.ZPrecision)); compressed = true; } } break; } isEnums.Add(field.FieldType.IsEnum); fieldTypes.Add(field.FieldType.ToString()); fieldNames.Add(field.Name); isCompressed.Add(compressed); } components.Add(new Tuple <string, ushort, string[], string[], bool[], bool[]>(componentName, counter, fieldTypes.ToArray(), fieldNames.ToArray(), isEnums.ToArray(), isCompressed.ToArray())); counter++; } else { var serializeAttributes = type.GetCustomAttributes(typeof(SerializeAttribute), false); if (serializeAttributes != null && serializeAttributes.Length > 0) { var componentName = type.Name; var fields = type.GetFields(); var fieldTypes = new List <string>(); var fieldNames = new List <string>(); var isEnums = new List <bool>(); var isCompressed = new List <bool>(); foreach (var field in fields) { var compressed = false; switch (field.FieldType.ToString()) { case "System.Single": { var compressor = field.GetCustomAttribute <BoundedFloatAttribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}", compressor.Min, compressor.Max, compressor.Precision)); compressed = true; } } break; case "UnityEngine.Vector2": { var compressor = field.GetCustomAttribute <BoundedVector2Attribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}X", compressor.XMin, compressor.XMax, compressor.XPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}Y", compressor.YMin, compressor.YMax, compressor.YPrecision)); compressed = true; } } break; case "UnityEngine.Vector3": { var compressor = field.GetCustomAttribute <BoundedVector3Attribute>(); if (compressor != null) { compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}X", compressor.XMin, compressor.XMax, compressor.XPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}Y", compressor.YMin, compressor.YMax, compressor.YPrecision)); compressors.Add(new Tuple <string, float, float, float>( $"{componentName.Replace("Component", "")}{field.Name}Z", compressor.ZMin, compressor.ZMax, compressor.ZPrecision)); compressed = true; } } break; } isEnums.Add(field.FieldType.IsEnum); fieldTypes.Add(field.FieldType.ToString()); fieldNames.Add(field.Name); isCompressed.Add(compressed); } var componentTemplate = new SyncComponentGenerator(); var d = new Dictionary <string, object> { { "ComponentName", componentName }, { "ComponentId", counter }, { "FieldTypes", fieldTypes.ToArray() }, { "FieldNames", fieldNames.ToArray() }, { "IsEnums", isEnums.ToArray() }, { "IsCompressed", isCompressed.ToArray() } }; componentTemplate.Session = d; componentTemplate.Initialize(); var output = componentTemplate.TransformText(); SaveFile("Sync/Components/", $"{componentName}.cs", output); counter++; } } } } #endregion #region components foreach (var tuple in components) { var componentTemplate = new SyncComponentGenerator(); var d = new Dictionary <string, object> { { "ComponentName", tuple.Item1 }, { "ComponentId", tuple.Item2 }, { "FieldTypes", tuple.Item3 }, { "FieldNames", tuple.Item4 }, { "IsEnums", tuple.Item5 }, { "IsCompressed", tuple.Item6 } }; componentTemplate.Session = d; componentTemplate.Initialize(); var output = componentTemplate.TransformText(); SaveFile("Sync/Components/", $"{tuple.Item1}.cs", output); } #endregion #region capture removed components foreach (var tuple in components) { var componentTemplate = new SyncRemovedComponentSystemGenerator(); var d = new Dictionary <string, object> { { "ComponentName", tuple.Item1.Replace("Component", "") }, { "ComponentId", tuple.Item2 }, { "IsTag", tuple.Item3.Length == 0 } }; componentTemplate.Session = d; componentTemplate.Initialize(); var output = componentTemplate.TransformText(); SaveFile("Sync/Capture/", $"ServerCaptureRemoved{tuple.Item1.Replace("Component", "")}System.cs", output); } #endregion #region capture changed/added components foreach (var tuple in components) { var componentTemplate = new SyncChangedComponentSystemGenerator(); var d = new Dictionary <string, object> { { "ComponentName", tuple.Item1.Replace("Component", "") }, { "ComponentId", tuple.Item2 }, { "IsTag", tuple.Item3.Length == 0 } }; componentTemplate.Session = d; componentTemplate.Initialize(); var output = componentTemplate.TransformText(); SaveFile("Sync/Capture/", $"ServerCaptureChanged{tuple.Item1.Replace("Component", "")}System.cs", output); } #endregion #region pack entity utility { var packUtilityTemplate = new PackEntityUtilityGenerator(); var d = new Dictionary <string, object> { { "ComponentNames", components.Select(x => x.Item1).ToArray() }, { "ComponentIds", components.Select(x => x.Item2).ToArray() }, { "IsTags", components.Select(x => x.Item3.Length == 0).ToArray() } }; packUtilityTemplate.Session = d; packUtilityTemplate.Initialize(); var output = packUtilityTemplate.TransformText(); SaveFile("Sync/Utility/", "PackEntityUtility.cs", output); } #endregion #region unpack entity utility { var template = new UnpackEntityUtilityGenerator(); var d = new Dictionary <string, object> { { "ComponentNames", components.Select(x => x.Item1).ToArray() }, { "ComponentIds", components.Select(x => x.Item2).ToArray() }, { "IsTags", components.Select(x => x.Item3.Length == 0).ToArray() } }; template.Session = d; template.Initialize(); var output = template.TransformText(); SaveFile("Sync/Utility/", "UnpackEntityUtility.cs", output); } #endregion #region feature { var template = new SyncFeatureGenerator(); var d = new Dictionary <string, object> { { "ComponentNames", components.Select(x => x.Item1.Replace("Component", "")).ToArray() } }; template.Session = d; template.Initialize(); var output = template.TransformText(); SaveFile("Sync/Feature/", "ServerStateCaptureFeature.cs", output); } #endregion #region compressors { var template = new CompressorsGenerator(); var d = new Dictionary <string, object> { { "Prefix", "Sync" }, { "CompressorNames", compressors.Select(x => x.Item1).ToArray() }, { "Mins", compressors.Select(x => x.Item2).ToArray() }, { "Maxs", compressors.Select(x => x.Item3).ToArray() }, { "Precisions", compressors.Select(x => x.Item4).ToArray() } }; template.Session = d; template.Initialize(); var output = template.TransformText(); SaveFile("Sync/Compressors/", "SyncCompressors.cs", output); } #endregion AssetDatabase.Refresh(); }