private static void Configure(UIModel model, int parent, int index, UISchema schema, MemoryBinaryWriter modelWriter, TypeDecomposer decomposer, UIPropertyWriterContext context, List <Type> types, ref long totalSize) { var node = model.nodes[index]; var header = new HeaderConfig { configurationMask = node.mask, schemaIndex = schema.elements.FindIndex((element) => element.identifier == node.identifier), flags = 0, childCount = node.children.Count, parent = parent }; var sizeOffset = modelWriter.Length; var headerOffset = modelWriter.Length + sizeof(int); int size = 0; modelWriter.Write(0); modelWriter.WriteBytes(UnsafeUtility.AddressOf(ref header), UnsafeUtility.SizeOf <HeaderConfig>()); foreach (var child in node.children) { modelWriter.Write(child); } size += UnsafeUtility.SizeOf <HeaderConfig>() + (UnsafeUtility.SizeOf <int>() * node.children.Count); size += ConfigureBlocks(node, modelWriter, decomposer, ref context, types, size, out header.flags); UnsafeUtility.MemCpy((((IntPtr)modelWriter.Data) + sizeOffset).ToPointer(), UnsafeUtility.AddressOf(ref size), UnsafeUtility.SizeOf <int>()); UnsafeUtility.MemCpy((((IntPtr)modelWriter.Data) + headerOffset).ToPointer(), UnsafeUtility.AddressOf(ref header), UnsafeUtility.SizeOf <HeaderConfig>()); totalSize += UnsafeUtility.SizeOf <int>() + size; foreach (var child in node.children) { Configure(model, index, child, schema, modelWriter, decomposer, context, types, ref totalSize); } }
private static int ConfigureBlocks(UIModel.Node node, MemoryBinaryWriter writer, TypeDecomposer decomposer, ref UIPropertyWriterContext context, List <Type> types, int headerSize, out byte flags) { var configBlocks = new List <object>(); UIConfigUtility.GetTypes(node.mask, types); UIConfigUtility.CreateConfiguration(node.mask, configBlocks); var configSize = UIConfigUtility.GetLength(node.mask); using var extraBytesStream = new MemoryBinaryWriter(); IntPtr configData = (IntPtr)UnsafeUtility.Malloc(configSize, 0, Allocator.Temp); int configBlockOffset = 0; var configFields = new Dictionary <string, TypeDecomposer.FieldData>(); flags = 0; foreach (var configBlock in configBlocks) { decomposer.Decompose(configBlock.GetType(), configFields, configBlock.GetType().GetCustomAttribute <UIConfigBlockAttribute>()?.Name, configBlockOffset, '-'); Marshal.StructureToPtr(configBlock, configData + configBlockOffset, true); flags |= StandardConfigurationHandlers.PreInit(configBlock.GetType(), configData + configBlockOffset, node.mask, ref context); configBlockOffset += UnsafeUtility.SizeOf(configBlock.GetType()); } foreach (var property in node.properties) { if (configFields.TryGetValue(property.path, out TypeDecomposer.FieldData fieldData)) { StandardPropertyWriters.writers.Write(property.Value, configData, fieldData, extraBytesStream, configSize + headerSize, context); } } configBlockOffset = 0; foreach (var configBlockType in types) { flags |= StandardConfigurationHandlers.PostInit(configBlockType, configData + configBlockOffset, configData, node.mask, extraBytesStream, configSize + headerSize, context); configBlockOffset += UnsafeUtility.SizeOf(configBlockType); } int length = configSize + extraBytesStream.Length; writer.WriteBytes(configData.ToPointer(), configSize); if (extraBytesStream.Length > 0) { writer.WriteBytes(extraBytesStream.Data, extraBytesStream.Length); } UnsafeUtility.Free(configData.ToPointer(), Allocator.Temp); return(length); }
public override unsafe byte PostInit(TextConfig *value, IntPtr config, ulong mask, MemoryBinaryWriter extraBytesStream, long extraByteStreamOffset, UIPropertyWriterContext context) { TMP_FontAsset fontAsset = null; var fontConfigPtr = UIConfigUtility.GetConfig(mask, UIConfigLayoutTable.FontConfig, config); if (fontConfigPtr == IntPtr.Zero) { return(0); } FontConfig *fontConfig = ((FontConfig *)fontConfigPtr); var guid = fontConfig->asset.ToHex(); #if UNITY_EDITOR fontAsset = UnityEditor.AssetDatabase.LoadAssetAtPath <TMP_FontAsset>(UnityEditor.AssetDatabase.GUIDToAssetPath(guid)); #else //var task = Addressables.LoadAssetAsync<TMP_FontAsset>(guid); //fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(AssetDatabase.GUIDToAssetPath(guid)); #endif var index = context.group.GetAtlasIndex(guid); if (fontAsset != null && index >= 0) { value->fontInfo = new FontInfo(fontAsset); value->charInfoOffset = extraBytesStream.Length; for (int charIndex = 0; charIndex < value->text.length; charIndex++) { UnsafeUtility.CopyPtrToStructure(new IntPtr(((IntPtr)extraBytesStream.Data).ToInt64() + (value->text.offset - extraByteStreamOffset) + (charIndex * 2)).ToPointer(), out char character); var charInfo = fontAsset.characterLookupTable[character]; var charInfoValue = new CharInfo { uvs = new float4(charInfo.glyph.glyphRect.x / (float)fontAsset.atlasWidth, charInfo.glyph.glyphRect.y / (float)fontAsset.atlasHeight, charInfo.glyph.glyphRect.width / (float)fontAsset.atlasWidth, charInfo.glyph.glyphRect.height / (float)fontAsset.atlasHeight), metrics = charInfo.glyph.metrics, index = (byte)index, unicode = charInfo.unicode }; extraBytesStream.WriteBytes(UnsafeUtility.AddressOf(ref charInfoValue), UnsafeUtility.SizeOf <CharInfo>()); } value->charInfoLength = value->text.length; //value->charInfoLength = (int)((extraBytesStream.Length - value->charInfoOffset) / UnsafeUtility.SizeOf<CharInfo>()); value->charInfoOffset += extraByteStreamOffset; } return(0); }
private static bool ExportWorld(FileInfo outputFile, Project project, string scenePath, World world, bool performConversion = true) { if (performConversion) { SceneConversion.Convert(world); } // Null out any references to avoid the SerializeUtility from trying to patch asset entities. world.GetOrCreateSystem <ClearRemappedEntityReferenceSystem>().Update(); // Check for missing assembly references var unresolvedComponentTypes = GetAllUsedComponentTypes(world).Where(t => !DomainCache.IsIncludedInProject(project, t.GetManagedType())).ToArray(); if (unresolvedComponentTypes.Length > 0) { foreach (var unresolvedComponentType in unresolvedComponentTypes) { var type = unresolvedComponentType.GetManagedType(); Debug.LogError($"Could not resolve component type '{type.FullName}' while exporting {scenePath.HyperLink()}. Are you missing an assembly reference to '{type.Assembly.GetName().Name}' ?"); } return(false); } // Remove non-exported components var nonExportedComponentTypes = UnityEditor.TypeCache.GetTypesWithAttribute <NonExportedAttribute>().Select(t => new ComponentType(t)); world.EntityManager.RemoveComponent(world.EntityManager.UniversalQuery, new ComponentTypes(nonExportedComponentTypes.ToArray())); // Merges the entities and shared component streams, (optionally) compresses them, and finally serializes to disk with a small header in front using (var fileStream = new StreamBinaryWriter(outputFile.FullName)) using (var entitiesWriter = new MemoryBinaryWriter()) using (var sharedComponentWriter = new MemoryBinaryWriter()) using (var combinedDataWriter = new MemoryBinaryWriter()) { SerializeUtility.SerializeWorld(world.EntityManager, entitiesWriter, out var sharedComponentsToSerialize); if (sharedComponentsToSerialize.Length > 0) { SerializeUtility.SerializeSharedComponents(world.EntityManager, sharedComponentWriter, sharedComponentsToSerialize); } unsafe { combinedDataWriter.WriteBytes(sharedComponentWriter.Data, sharedComponentWriter.Length); combinedDataWriter.WriteBytes(entitiesWriter.Data, entitiesWriter.Length); var worldHeader = new SceneHeader(); worldHeader.SharedComponentCount = sharedComponentsToSerialize.Length; worldHeader.DecompressedSize = entitiesWriter.Length + sharedComponentWriter.Length; worldHeader.Codec = Codec.LZ4; worldHeader.SerializeHeader(fileStream); if (worldHeader.Codec != Codec.None) { int compressedSize = CodecService.Compress(worldHeader.Codec, combinedDataWriter.Data, combinedDataWriter.Length, out var compressedData); fileStream.WriteBytes(compressedData, compressedSize); } else { fileStream.WriteBytes(combinedDataWriter.Data, combinedDataWriter.Length); } } } return(true); }