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();
    }
Exemple #2
0
        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);
        }