/// <summary> /// Parses an entityDef into an EntityDef object /// </summary> /// <param name="entityDefText">text containing the entityDef</param> /// <param name="currentLineNumber">current line number reference in the file</param> /// <returns>an EntityDef object containing the parsed data from the entityDef</reurns> internal EntityDef ParseEntityDef(string entityDefText, ref int currentLineNumber) { EntityDef entityDef = new EntityDef(); List <EntityProperty> entityProperties = new List <EntityProperty>(); // Split the entity definition into lines string[] entityDefTextLines = entityDefText.Split('\n'); currentLineNumber -= entityDefTextLines.Length - 1; for (int i = 0; i < entityDefTextLines.Length; i++) { if (i > 0) { currentLineNumber++; } entityDefTextLines[i] = entityDefTextLines[i].Trim(); // The entityDef declaration is in the first line and contains its name if (i == 0) { string[] entityDefParts = entityDefTextLines[i].Split(' '); if (!entityDefParts[0].Equals("entityDef") && !entityDefParts[0].Equals("entityDef{")) { Errors.Add(string.Format("Line {0}: unknown type '{1}'", currentLineNumber, entityDefParts[0])); return(null); } // The bracket could be next to the entityDef name so we have to check that if (entityDefParts.Length == 1) { Errors.Add(string.Format("Line {0}: missing entityDef name", currentLineNumber)); return(null); } else if (entityDefParts.Length == 2) { if (entityDefParts[1].Equals("{")) { Errors.Add(string.Format("Line {0}: missing entityDef name", currentLineNumber)); return(null); } else if (entityDefParts[1][entityDefParts[1].Length - 1] != '{') { Errors.Add(string.Format("Line {0}: missing '{{'", currentLineNumber)); return(null); } else if (!IsValidEntityDefName(entityDefParts[1].Remove(entityDefParts[1].Length - 1, 1))) { Errors.Add(string.Format("Line {0}: invalid entityDef name '{1}'", currentLineNumber, entityDefParts[1].Remove(entityDefParts[1].Length - 1, 1))); return(null); } else { entityDef.Name = entityDefParts[1].Remove(entityDefParts[1].Length - 1, 1); } } else if (entityDefParts.Length == 3) { if (!entityDefParts[2].Equals("{")) { Errors.Add(string.Format("Line {0}: missing '{{'", currentLineNumber)); return(null); } else if (!IsValidEntityDefName(entityDefParts[1])) { Errors.Add(string.Format("Line {0}: invalid entityDef name '{1}'", currentLineNumber, entityDefParts[1])); return(null); } else { entityDef.Name = entityDefParts[1]; } } else { Errors.Add(string.Format("Line {0}: expected entityDef declaration not found", currentLineNumber, entityDefTextLines[i])); return(null); } continue; } // Everything inside the entityDef must be a property of some kind EntityProperty entityProperty = null; // We will get all the text of the property and pass it to the property parser string[] propertyText = entityDefTextLines[i].Split('='); if (propertyText.Length != 2) { if (entityDefTextLines[i].Equals("{") || entityDefTextLines[i].Equals("}")) { continue; } else { Errors.Add(string.Format("Line {0}: unexpected '{1}'", currentLineNumber, entityDefTextLines[i])); continue; } } propertyText[0] = propertyText[0].TrimEnd(); propertyText[1] = propertyText[1].Trim(); // First we need to determine which kind of property this is to get all it's text // This is probably a "single-line" property, so we can just pass the whole line to the property parser if (propertyText[1][propertyText[1].Length - 1] != '{') { try { entityProperty = ParseEntityProperty(entityDefTextLines[i], ref currentLineNumber); } catch (FormatException) { throw; } } else { // Check if the "Important" flag is present if (propertyText[1].Length > 1 && propertyText[1][0] == '!') { entityProperty.Important = true; } // This is either an object or an array, so we'll just get the whole block // to pass it to the property parser StringBuilder currentPropertyText = new StringBuilder(); int openingBracketCount = 1; int closingBracketCount = 0; currentPropertyText.Append(entityDefTextLines[i]).Append("\n"); currentLineNumber++; // Get everything until the block is closed for (int j = i + 1; j < entityDefTextLines.Length; j++, currentLineNumber++, i = j) { if (string.IsNullOrEmpty(entityDefTextLines[j])) { continue; } if (entityDefTextLines[j][entityDefTextLines[j].Length - 1] == '{') { openingBracketCount++; currentPropertyText.Append(entityDefTextLines[j]).Append("\n"); continue; } if (entityDefTextLines[j][entityDefTextLines[j].Length - 1] == '}') { closingBracketCount++; } if (openingBracketCount == closingBracketCount) { currentPropertyText.Append(entityDefTextLines[j]); break; } currentPropertyText.Append(entityDefTextLines[j]).Append("\n"); } entityProperty = ParseEntityProperty(currentPropertyText.ToString(), ref currentLineNumber); currentPropertyText.Clear(); } if (entityProperty != null) { entityProperties.Add(entityProperty); } } entityDef.Properties = entityProperties; return(entityDef); }
/// <summary> /// Parses an entity /// </summary> /// <param name="entityText">text block containing the entity</param> /// <param name="currentLineNumber">current line number reference in the file</param> /// <returns>an Entity object with the parsed data from the entity</returns> internal Entity ParseEntity(string entityText, ref int currentLineNumber) { // Split the entity definition into lines string[] entityTextLines = entityText.Split('\n'); currentLineNumber -= entityTextLines.Length - 1; Entity entity = new Entity(); EntityDef entityDef = null; for (int i = 0; i < entityTextLines.Length; i++) { entityTextLines[i] = entityTextLines[i].Trim(); if (i > 0) { currentLineNumber++; } // Parse the layers if (entityTextLines[i].Equals("layers {") || entityTextLines[i].Equals("layers{")) { i++; entity.Layers = new List <EntityPropertyStringValue>(); while (!entityTextLines[i].Trim().Equals("}")) { try { var layer = (EntityPropertyStringValue)ParseEntityPropertyValue(entityTextLines[i++].Trim(), ref currentLineNumber); if (layer != null) { entity.Layers.Add(layer); } currentLineNumber++; } catch (FormatException) { throw; } } // Closing bracket currentLineNumber++; } else if (entityTextLines[i].Contains("originalName")) { // Look for "originalName" and "instanceId" properties string[] originalNameParts = entityTextLines[i].Split('='); if (originalNameParts.Length != 2) { Errors.Add(string.Format("Line {0}: bad property declaration '{1}'", currentLineNumber, entityTextLines[i])); continue; } if (entityTextLines[i][entityTextLines[i].Length - 1] != ';') { Errors.Add(string.Format("Line {0}: missing ';'", currentLineNumber)); continue; } entity.OriginalName = (EntityPropertyStringValue)ParseEntityPropertyValue(originalNameParts[1].Remove(originalNameParts[1].Length - 1, 1).Trim(), ref currentLineNumber); } else if (entityTextLines[i].Contains("instanceId")) { string[] instanceIdParts = entityTextLines[i].Split('='); if (instanceIdParts.Length != 2) { Errors.Add(string.Format("Line {0}: bad property declaration '{1}'", currentLineNumber, entityTextLines[1])); continue; } if (entityTextLines[i][entityTextLines[i].Length - 1] != ';') { Errors.Add(string.Format("Line {0}: missing ';'", currentLineNumber)); continue; } entity.InstanceId = (EntityPropertyLongValue)ParseEntityPropertyValue(instanceIdParts[1].Remove(instanceIdParts[1].Length - 1, 1).Trim(), ref currentLineNumber); } else if (entityTextLines[i].Contains("entityDef")) { // Get the entityDef block and parse it if (entityTextLines[i][entityTextLines[i].Length - 1] != '{') { Errors.Add(string.Format("Line {0}: missing '{{'", currentLineNumber)); continue; } StringBuilder entityDefText = new StringBuilder(); int openingBracketCount = 1; int closingBracketCount = 0; // Append the first entityDef line, which opens the block entityDefText.Append(entityTextLines[i]).Append("\n"); // Get everything until the block is closed for (int j = i + 1; j < entityTextLines.Length; j++, currentLineNumber++, i = j) { if (string.IsNullOrEmpty(entityTextLines[j])) { continue; } if (entityTextLines[j][entityTextLines[j].Length - 1] == '{') { openingBracketCount++; entityDefText.Append(entityTextLines[j]).Append("\n"); continue; } if (entityTextLines[j][entityTextLines[j].Length - 1] == '}') { closingBracketCount++; } if (openingBracketCount == closingBracketCount) { entityDefText.Append(entityTextLines[j]); currentLineNumber++; break; } entityDefText.Append(entityTextLines[j]).Append("\n"); } entityDef = ParseEntityDef(entityDefText.ToString(), ref currentLineNumber); entityDefText.Clear(); } else if (!entityTextLines[i].Equals("entity{") && !entityTextLines[i].Equals("entity {") && !entityTextLines[i].Equals("{") && !entityTextLines[i].Equals("}")) { Errors.Add(string.Format("Line {0}: unexpected '{1}' inside entity definition", currentLineNumber, entityTextLines[i])); continue; } } entity.EntityDef = entityDef; return(entity); }