void OnEditorChangeEvents(ref ObjectChangeEventStream stream)
        {
            for (int i = 0; i < stream.length; i++)
            {
                var type = stream.GetEventType(i);
                switch (type)
                {
                case ObjectChangeKind.None:
                    break;

                case ObjectChangeKind.ChangeScene:
                {
                    stream.GetChangeSceneEvent(i, out var evt);
                    if (evt.scene.IsValid())
                    {
                        GetLiveLink(evt.scene)?.RequestCleanConversion();
                    }
                    break;
                }

                case ObjectChangeKind.CreateGameObjectHierarchy:
                {
                    stream.GetCreateGameObjectHierarchyEvent(i, out var evt);
                    GetLiveLink(evt.scene)?.ChangeTracker.MarkReconvertHierarchy(evt.instanceId);
                    break;
                }

                case ObjectChangeKind.ChangeGameObjectStructureHierarchy:
                {
                    stream.GetChangeGameObjectStructureHierarchyEvent(i, out var evt);
                    GetLiveLink(evt.scene)?.ChangeTracker.MarkReconvertHierarchy(evt.instanceId);
                    break;
                }

                case ObjectChangeKind.ChangeGameObjectStructure:
                {
                    stream.GetChangeGameObjectStructureEvent(i, out var evt);
                    GetLiveLink(evt.scene)?.ChangeTracker.MarkChanged(evt.instanceId);
                    break;
                }

                case ObjectChangeKind.ChangeGameObjectParent:
                {
                    stream.GetChangeGameObjectParentEvent(i, out var evt);
                    if (evt.newScene != evt.previousScene)
                    {
                        GetLiveLink(evt.newScene)?.ChangeTracker.MarkReconvertHierarchy(evt.instanceId);
                        GetLiveLink(evt.previousScene)?.ChangeTracker.MarkRemoved(evt.instanceId);
                    }
                    else
                    {
                        GetLiveLink(evt.newScene)?.ChangeTracker.MarkParentChanged(evt.instanceId, evt.newParentInstanceId);
                    }
                    break;
                }

                case ObjectChangeKind.ChangeGameObjectOrComponentProperties:
                {
                    stream.GetChangeGameObjectOrComponentPropertiesEvent(i, out var evt);
                    var target = EditorUtility.InstanceIDToObject(evt.instanceId);
                    if (target is Component c)
                    {
                        GetLiveLink(evt.scene)?.ChangeTracker.MarkComponentChanged(c);
                    }
                    else
                    {
                        GetLiveLink(evt.scene)?.ChangeTracker.MarkChanged(evt.instanceId);
                    }
                    break;
                }

                case ObjectChangeKind.DestroyGameObjectHierarchy:
                {
                    stream.GetDestroyGameObjectHierarchyEvent(i, out var evt);
                    GetLiveLink(evt.scene)?.ChangeTracker.MarkRemoved(evt.instanceId);
                    break;
                }

                case ObjectChangeKind.CreateAssetObject:
                {
                    stream.GetCreateAssetObjectEvent(i, out var evt);
                    MarkAssetChanged(evt.instanceId, evt.scene);
                    break;
                }

                case ObjectChangeKind.DestroyAssetObject:
                {
                    stream.GetDestroyAssetObjectEvent(i, out var evt);
                    MarkAssetChanged(evt.instanceId, evt.scene);
                    break;
                }

                case ObjectChangeKind.ChangeAssetObjectProperties:
                {
                    stream.GetChangeAssetObjectPropertiesEvent(i, out var evt);
                    MarkAssetChanged(evt.instanceId, evt.scene);
                    break;
                }

                case ObjectChangeKind.UpdatePrefabInstances:
                {
                    stream.GetUpdatePrefabInstancesEvent(i, out var evt);
                    var diffGenerator = GetLiveLink(evt.scene);
                    if (diffGenerator != null)
                    {
                        for (int k = 0; k < evt.instanceIds.Length; k++)
                        {
                            diffGenerator.ChangeTracker.MarkReconvertHierarchy(evt.instanceIds[k]);
                        }
                    }
                    break;
                }

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            EditorUpdateUtility.EditModeQueuePlayerLoopUpdate();
        }