// Parse the next path component from a SerializedProperty.propertyPath. For simple field/property access, // this is just tokenizing on '.' and returning each field/property name. Array/list access is via // the pseudo-property "Array.data[N]", so this method parses that and returns just the array/list index N. // // Call this method repeatedly to access all path components. For example: // // string propertyPath = "quests.Array.data[0].goal"; // int i = 0; // NextPropertyPathToken(propertyPath, ref i, out var component); // => component = { propertyName = "quests" }; // NextPropertyPathToken(propertyPath, ref i, out var component) // => component = { elementIndex = 0 }; // NextPropertyPathToken(propertyPath, ref i, out var component) // => component = { propertyName = "goal" }; // NextPropertyPathToken(propertyPath, ref i, out var component) // => returns false private static bool NextPathComponent(string propertyPath, ref int index, out PropertyPathComponent component) { component = new PropertyPathComponent(); if (index >= propertyPath.Length) { return(false); } Match arrayElementMatch = ArrayElementRegex.Match(propertyPath, index); if (arrayElementMatch.Success) { index += arrayElementMatch.Length + 1; // Skip past next '.' component.elementIndex = int.Parse(arrayElementMatch.Groups[1].Value); return(true); } int dot = propertyPath.IndexOf('.', index); if (dot == -1) { component.propertyName = propertyPath.Substring(index); index = propertyPath.Length; } else { component.propertyName = propertyPath.Substring(index, dot - index); index = dot + 1; // Skip past next '.' } return(true); }
private static void SetPathComponentValue(object container, PropertyPathComponent component, object value) { if (component.propertyName == null) { ((IList)container)[component.elementIndex] = value; } else { SetMemberValue(container, component.propertyName, value); } }
private static object GetPathComponentValue(object container, PropertyPathComponent component) { if (component.propertyName == null) { return(((IList)container)[component.elementIndex]); } else { return(GetMemberValue(container, component.propertyName)); } }