private void verifyProperties(BlockPart block) { if (block.Block == null) { block.Block = Block.ID; } else if (block.Block != Block.ID) { throw new Exception($"Block [{block.Block}] and file name [{Block.ID}] doesn't match."); } if (block.Episode == null) { block.Episode = Block.Episode.ID; } else if (block.Episode != Block.Episode.ID) { throw new Exception($"Episode [{block.Episode}] and file path [{Block.Episode.ID}] doesn't match."); } if (block.Season == null) { block.Season = Block.Episode.Season.ID; } else if (block.Season != Block.Episode.Season.ID) { throw new Exception($"Season [{block.Season}] and file path [{Block.Episode.Season.ID}] doesn't match."); } }
/// <summary> /// Construct a new String8Block to hold String8 copies. /// </summary> public String8Block() { _blocks = new List <BlockPart>(); _current = new BlockPart(); _blocks.Add(_current); }
/// <summary> /// Create a concatenation of three String8s. Used to join values /// with a delimiter in a memory efficient way. /// </summary> /// <param name="first">First Value</param> /// <returns>String8 copy which will persist</returns> public String8 Concatenate(String8 first, String8 delimiter, String8 second) { // If either string is empty, use only the other [if both empty, String8.Empty returned] if (first.IsEmpty()) { return(GetCopy(second)); } if (second.IsEmpty()) { return(GetCopy(first)); } BlockPart targetBlock = null; // If "first" is the last thing on the last block... if (_blocks.Count > 0) { targetBlock = _blocks[_blocks.Count - 1]; if (targetBlock.Block == first.Array && targetBlock.LengthUsed == first.Index + first.Length) { // If there's room to concatenate in place, do that if (targetBlock.Block.Length >= targetBlock.LengthUsed + delimiter.Length + second.Length) { targetBlock.LengthUsed += delimiter.WriteTo(targetBlock.Block, targetBlock.LengthUsed); targetBlock.LengthUsed += second.WriteTo(targetBlock.Block, targetBlock.LengthUsed); return(new String8(first.Array, first.Index, targetBlock.LengthUsed - first.Index)); } // If not, "remove" first from the block to recycle the space if (first.Index == 0) { // If first was alone, remove the whole block _blocks.RemoveAt(_blocks.Count - 1); } else { // Deduct the used space for "first" _blocks[_blocks.Count - 1].LengthUsed -= first.Length; } } } // Find new room for the concatenated value int requiredLength = first.Length + delimiter.Length + second.Length; targetBlock = GetBlockForLength((int)(1.5 * requiredLength)); // Write the parts to the chosen block and return a reference to the new copy int startPosition = targetBlock.LengthUsed; targetBlock.LengthUsed += first.WriteTo(targetBlock.Block, targetBlock.LengthUsed); targetBlock.LengthUsed += delimiter.WriteTo(targetBlock.Block, targetBlock.LengthUsed); targetBlock.LengthUsed += second.WriteTo(targetBlock.Block, targetBlock.LengthUsed); return(new String8(targetBlock.Block, startPosition, targetBlock.LengthUsed - startPosition)); }
/// <summary> /// Clear the String8Block. Clear reuses some memory, avoiding allocations /// if use between clear calls is relatively small. /// </summary> public void Clear() { // Clear length used on the first block BlockPart first = _blocks[0]; first.LengthUsed = 0; // Remove other blocks and restore only the first _blocks.Clear(); _blocks.Add(first); }
private void adjustParagraphs(BlockPart blockPart) { if (isAuthor) { addParagraphsToLimit(blockPart); } else { blockPart.Paragraphs = blockPart.Paragraphs .Where(pg => pg.HasText) .ToList(); } }
/// <summary> /// Create a copy of a String8. Use when the source of the String8s /// will change (like a reader reusing the same byte[] buffer) and /// you need to keep a copy of specific values with minimal object overhead. /// </summary> /// <param name="source">String8 to copy</param> /// <returns>String8 copy which will persist</returns> public String8 GetCopy(String8 source) { if (source.IsEmpty()) { return(String8.Empty); } BlockPart targetBlock = GetBlockForLength(source.Length); // Write the String8 to the chosen block and return a reference to the new copy int writePosition = targetBlock.LengthUsed; targetBlock.LengthUsed += source.WriteTo(targetBlock.Block, writePosition); return(new String8(targetBlock.Block, writePosition, source.Length)); }
public static BlockPart GetBlockPart(Facing facing, Rect uvRect) { var part = parts[(int)facing]; var newPart = new BlockPart(); newPart.vertices = new Vector3[part.vertices.Length]; part.vertices.CopyTo(newPart.vertices, 0); newPart.triangles = new int[part.triangles.Length]; part.triangles.CopyTo(newPart.triangles, 0); newPart.uv = BlockSideUVs(uvRect); return(newPart); }
/// <summary> /// Create a copy of a String8. Use when the source of the String8s /// will change (like a reader reusing the same byte[] buffer) and /// you need to keep a copy of specific values with minimal object overhead. /// </summary> /// <param name="source">String8 to copy</param> /// <returns>String8 copy which will persist</returns> public String8 GetCopy(string source) { if (string.IsNullOrEmpty(source)) { return(String8.Empty); } int length = String8.GetLength(source); BlockPart targetBlock = GetBlockForLength(length); // Write the String to the chosen block and return a reference to the new copy int writePosition = targetBlock.LengthUsed; targetBlock.LengthUsed += source.Length; return(String8.Convert(source, targetBlock.Block, writePosition)); }
static Geometry() { void addPart(Facing facing, Quaternion rotation) { var part = new BlockPart(); part.vertices = BlockSideVertexes(rotation); part.triangles = BlockSideTriangles(); parts[(int)facing] = part; } addPart(Facing.North, Quaternion.Euler(0, 180, 0)); addPart(Facing.East, Quaternion.Euler(0, -90, 0)); addPart(Facing.South, Quaternion.identity); addPart(Facing.West, Quaternion.Euler(0, 90, 0)); addPart(Facing.Up, Quaternion.Euler(90, 0, 0)); addPart(Facing.Down, Quaternion.Euler(-90, 0, 0)); }
private BlockPart GetBlockForLength(int length) { BlockPart targetBlock = _current; if (length >= StoreIndividuallyLengthBytes) { // If the String8 is too long, store by itself targetBlock = new BlockPart(length); _blocks.Add(targetBlock); } else if (_current.Block.Length < _current.LengthUsed + length) { // If the current block is too full, start a new one targetBlock = new BlockPart(); _blocks.Add(targetBlock); _current = targetBlock; } return(targetBlock); }
private static void addParagraphsToLimit(BlockPart blockPart) { var begin = blockPart.Paragraphs.Count; var end = MINIMUM_PARAGRAPH_COUNT; for (var p = begin; p < end; p++) { var piece = new Piece { Type = TalkStyle.Default.ToString() }; var paragraph = new Paragraph { Type = ParagraphType.Talk, Pieces = new[] { piece } }; blockPart.Paragraphs.Add(paragraph); } }
private static TextSpan GetActiveSpan(BlockSyntax node, BlockPart part) { switch (part) { case BlockPart.OpenBrace: return node.OpenBraceToken.Span; case BlockPart.CloseBrace: return node.CloseBraceToken.Span; default: throw ExceptionUtilities.UnexpectedValue(part); } }