// SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 using GLTFast.Schema; using UnityEngine; using UnityEngine.Profiling; namespace GLTFast { /// /// glTF JSON parser implemented with Unity JsonUtility /// /// class GltfJsonUtilityParser { /// public RootBase ParseJson(string json) { // JsonUtility sometimes creates non-null default instances of objects-type members // even though there are none in the original JSON. // This work-around makes sure not existent JSON nodes will be null in the result. #if MEASURE_TIMINGS var stopWatch = new Stopwatch(); stopWatch.Start(); #endif Root root; // Main JSON parsing Profiler.BeginSample("JsonUtility main"); try { root = JsonUtility.FromJson(json); if (root == null) return null; } catch (System.ArgumentException) { return null; } finally { Profiler.EndSample(); } // Detect, if a secondary null-check is necessary. if (root.JsonUtilitySecondParseRequired()) { // If we have to make an explicit check, parse the JSON again with a // different, minimal Root class, where class members are serialized to // the type string. In case the string is null, there's no JSON node. // Otherwise the string would be empty (""). Profiler.BeginSample("JsonUtility secondary"); var fakeRoot = JsonUtility.FromJson(json); root.JsonUtilityCleanupAgainstSecondParse(fakeRoot); Profiler.EndSample(); } // Further, generic checks and cleanups root.JsonUtilityCleanup(); #if MEASURE_TIMINGS stopWatch.Stop(); var elapsedSeconds = stopWatch.ElapsedMilliseconds / 1000f; var throughput = json.Length / elapsedSeconds; Debug.Log($"JSON throughput: {throughput} bytes/sec ({json.Length} bytes in {elapsedSeconds} seconds)"); #endif return root; } } }