public override async Task <CmodData> Read() { using var reader = new BufferedReader(_stream); var materials = new List <Material>(); var meshes = new List <Mesh>(); while (true) { var token = await reader.TryReadToken().ConfigureAwait(false); if (!token.HasValue) { break; } switch (token.Value) { case Token.Material: materials.Add(await ReadMaterial(reader).ConfigureAwait(false)); break; case Token.Mesh: meshes.Add(await ReadMesh(reader, materials.Count).ConfigureAwait(false)); break; default: throw new CmodException("Unexpected token in cmod file"); } } if (materials.Count == 0) { throw new CmodException("No materials found"); } if (meshes.Count == 0) { throw new CmodException("No meshes found"); } return(new CmodData(materials, meshes)); }
private static async Task <IReadOnlyList <VertexAttribute> > ReadVertexDescription(BufferedReader reader) { if (await reader.ReadToken().ConfigureAwait(false) != Token.VertexDesc) { throw new CmodException("Expected vertex description"); } var attributes = new List <VertexAttribute>(); while (true) { var token = await reader.ReadInt16().ConfigureAwait(false); if (token == (short)Token.EndVertexDesc) { return(attributes); } var attribute = (AttributeType)token; if (!Enum.IsDefined(attribute)) { throw new CmodException("Unknown vertex attribute"); } if (attributes.Any(a => a.AttributeType == attribute)) { throw new CmodException("Duplicate vertex attribute"); } var format = await reader.ReadAttributeFormat().ConfigureAwait(false); if (!Enum.IsDefined(format)) { throw new CmodException("Invalid attribute format"); } attributes.Add(VertexAttribute.Create(attribute, format)); } }