private void WriteStruct()

in utils/SkiaSharpGenerator/Generate/Generator.cs [174:309]


		private void WriteStruct(TextWriter writer, CppClass klass)
		{
			var cppClassName = klass.GetDisplayName();

			if (excludedTypes.Contains(cppClassName) == true)
			{
				Log?.LogVerbose($"    Skipping struct '{cppClassName}' because it was in the exclude list.");
				return;
			}

			Log?.LogVerbose($"    {cppClassName}");

			typeMappings.TryGetValue(cppClassName, out var map);
			var name = map?.CsType ?? CleanName(cppClassName);

			writer.WriteLine();
			writer.WriteLine($"\t// {cppClassName}");
			writer.WriteLine($"\t[StructLayout (LayoutKind.Sequential)]");
			var visibility = map?.IsInternal == true ? "internal" : "public";
			var isReadonly = map?.IsReadOnly == true ? " readonly" : "";
			var equatable = map?.GenerateEquality == true ? $" : IEquatable<{name}>" : "";
			writer.WriteLine($"\t{visibility}{isReadonly} unsafe partial struct {name}{equatable} {{");

			var allFields = new List<string>();
			foreach (var field in klass.Fields)
			{
				var type = GetType(field.Type);
				var cppT = GetCppType(field.Type);

				writer.WriteLine($"\t\t// {field}");

				var fieldName = field.Name;
				var isPrivate = fieldName.StartsWith("_private_", StringComparison.OrdinalIgnoreCase);
				if (isPrivate)
					fieldName = fieldName[9..];
				isPrivate |= fieldName.StartsWith("reserved", StringComparison.OrdinalIgnoreCase);

				allFields.Add(fieldName);

				var vis = map?.IsInternal == true ? "public" : "private";
				var ro = map?.IsReadOnly == true ? " readonly" : "";
				writer.WriteLine($"\t\t{vis}{ro} {type} {fieldName};");

				if (!isPrivate && (map == null || (map.GenerateProperties && !map.IsInternal)))
				{
					var propertyName = fieldName;
					if (map != null && map.Members.TryGetValue(propertyName, out var fieldMap))
					{
						if (string.IsNullOrEmpty(fieldMap))
							isPrivate = true;
						propertyName = fieldMap;
					}
					else
					{
						propertyName = CleanName(propertyName);
					}

					if (!isPrivate)
					{
						if (fieldName == "value")
							fieldName = "this." + fieldName;

						if (cppT == "bool")
						{
							if (map?.IsReadOnly == true)
							{
								writer.WriteLine($"\t\tpublic readonly bool {propertyName} => {fieldName} > 0;");
							}
							else
							{
								writer.WriteLine($"\t\tpublic bool {propertyName} {{");
								writer.WriteLine($"\t\t\treadonly get => {fieldName} > 0;");
								writer.WriteLine($"\t\t\tset => {fieldName} = value ? (byte)1 : (byte)0;");
								writer.WriteLine($"\t\t}}");
							}
						}
						else
						{
							if (map?.IsReadOnly == true)
							{
								writer.WriteLine($"\t\tpublic readonly {type} {propertyName} => {fieldName};");
							}
							else
							{
								writer.WriteLine($"\t\tpublic {type} {propertyName} {{");
								writer.WriteLine($"\t\t\treadonly get => {fieldName};");
								writer.WriteLine($"\t\t\tset => {fieldName} = value;");
								writer.WriteLine($"\t\t}}");
							}
						}
					}
				}

				writer.WriteLine();
			}

			if (map?.GenerateEquality == true)
			{
				// IEquatable
				var equalityFields = new List<string>();
				foreach (var f in allFields)
				{
					equalityFields.Add($"{f} == obj.{f}");
				}
				writer.WriteLine($"\t\tpublic readonly bool Equals ({name} obj) =>");
				writer.WriteLine($"\t\t\t{string.Join(" && ", equalityFields)};");
				writer.WriteLine();

				// Equals
				writer.WriteLine($"\t\tpublic readonly override bool Equals (object obj) =>");
				writer.WriteLine($"\t\t\tobj is {name} f && Equals (f);");
				writer.WriteLine();

				// equality operators
				writer.WriteLine($"\t\tpublic static bool operator == ({name} left, {name} right) =>");
				writer.WriteLine($"\t\t\tleft.Equals (right);");
				writer.WriteLine();
				writer.WriteLine($"\t\tpublic static bool operator != ({name} left, {name} right) =>");
				writer.WriteLine($"\t\t\t!left.Equals (right);");
				writer.WriteLine();

				// GetHashCode
				writer.WriteLine($"\t\tpublic readonly override int GetHashCode ()");
				writer.WriteLine($"\t\t{{");
				writer.WriteLine($"\t\t\tvar hash = new HashCode ();");
				foreach (var f in allFields)
				{
					writer.WriteLine($"\t\t\thash.Add ({f});");
				}
				writer.WriteLine($"\t\t\treturn hash.ToHashCode ();");
				writer.WriteLine($"\t\t}}");
				writer.WriteLine();
			}

			writer.WriteLine($"\t}}");
		}