public void SwitchParser() { ClearUIData(); CurrentParser = InitializeParser(SelectNextParser(CurrentParseType)); CurrentParser.ParseJson(); StopAllCoroutines(); StartCoroutine(ProcessSchoolDataToUIWithInterval(CurrentParser.SchoolData, ProcessingTime)); // Update the name of the current parser on the UI CurrentParserText.text = "Parser type: " + CurrentParseType.ToString(); }
public static object FromKson <T>(string ksonString) { Type type = typeof(T); var instance = Activator.CreateInstance(type);//create instance of required type bool classOrStructVar = false; string varName = string.Empty, value = string.Empty; int nested = 0;//checks how many "nested" classes there are CurrentParseType currentParseType = CurrentParseType.none; for (int i = 0; i < ksonString.Length; i++)//loop through all the characters in the entered string { switch (ksonString[i]) { case '{': if (i != 0) //not the start { if (classOrStructVar) { nested++; } else { if (nested == 0) { classOrStructVar = true; nested++; } } value += '{'; } break; case '}': //not the end if (i != ksonString.Length - 1) { if (classOrStructVar) { nested--; } if (nested == 0) { classOrStructVar = false; } value += '}'; } break; case char c when c == '"': //checks wether or not a variable name is being detected, if not set varName to "" if (currentParseType == CurrentParseType.varValue || classOrStructVar) //make sure its not in a var value, if it is add it to the value string { value += c; break; } currentParseType = currentParseType == CurrentParseType.none ? CurrentParseType.varName : CurrentParseType.none; if (currentParseType == CurrentParseType.varName) { varName = string.Empty; } break; case char c when c == ':': if (currentParseType == CurrentParseType.varValue || classOrStructVar) //make sure its not in a var value, if it is add it to the value string { value += c; break; } currentParseType = CurrentParseType.varValue; break; case char c when c == ';' && !classOrStructVar && currentParseType == CurrentParseType.varValue: //a complete field with variable name + value has been found, parse the value and change it in the created instance and reset "varName" and "value". //all of this only happens if its not currently reading a class or struct variable FieldInfo field = instance.GetType().GetField(varName); if (!field.FieldType.IsValidType(true) && field.FieldType.GetCustomAttribute <Serialisable>() == null) { throw new InvalidTypeException(false); } if (value == NULL) //the value is null { field.SetValue(instance, null); } else { Type fieldType = field.FieldType; if (fieldType.GetCustomAttribute <Serialisable>() != null) //a serialsible struct or class { MethodInfo method = typeof(KsonParser).GetMethod(nameof(KsonParser.FromKson)); MethodInfo generic = method.MakeGenericMethod(fieldType); var serialisedClass = generic.Invoke(null, new[] { value }); //"creates" a new FromKson method and calls it field.SetValue(instance, serialisedClass); //sets the value of the instance } else { if (field.FieldType.IsArray) //type is array { Type listType = typeof(List <>).MakeGenericType(fieldType.GetElementType()); dynamic values = Activator.CreateInstance(listType); //create a list of elemant type of the variable being parsed string currentValue = string.Empty; for (int k = 0; k < value.Length; k++) //loop through the "value" string to find the elemants of the array { switch (value[k]) { case '[': //ignore case ' ': break; case char _charecter when _charecter.IsValidToBeDeserialised_Array(): //elemant currentValue += value[k]; break; case char _charecter when _charecter.DeterminesEndOfSerialisedArray(): //end of the elemant, add the value to the elemants list values.Add(type.GetCustomAttribute <Serialisable>().Deserialise(currentValue, fieldType.GetElementType())); //adds the deserialised value to the list currentValue = string.Empty; //reset the string values break; } field.SetValue(instance, values.ToArray()); //assign the elemants to the variable in the created instance of type T } } else { field.SetValue(instance, type.GetCustomAttribute <Serialisable>().Deserialise(value, fieldType)); //sets the value in the instance to the deserialised value } } } value = string.Empty; currentParseType = CurrentParseType.none; break; case char c: //character can be deserialised if (classOrStructVar) { value += c; } else if (!char.IsWhiteSpace(c)) //if a variable name is being read { if (currentParseType == CurrentParseType.varName) { varName += c; } else if (currentParseType == CurrentParseType.varValue) { value += c; } } break; } } return(instance); }