public void StopTracking(List <VisualElement> elements)
        {
            // Some panels like the main Toolbar don't have any tracking set up
            if (panel.contextType == ContextType.Editor && m_EditorVisualTreeAssetTracker == null)
            {
                return;
            }

            VisualTreeAsset currentAsset = null;
            ILiveReloadAssetTracker <VisualTreeAsset> tracker = null;

            foreach (var ve in elements)
            {
                if (ve.visualTreeAssetSource != null)
                {
                    if (ve.visualTreeAssetSource != currentAsset)
                    {
                        currentAsset = ve.visualTreeAssetSource;
                        tracker      = FindTracker(ve);
                    }
                    StopVisualTreeAssetTracking(tracker, ve.visualTreeAssetSource);
                }

                if (ve.styleSheetList?.Count > 0)
                {
                    foreach (var styleSheet in ve.styleSheetList)
                    {
                        m_LiveReloadStyleSheetAssetTracker.StopTrackingAsset(styleSheet);
                    }
                }
            }
        }
        internal void StopVisualTreeAssetTracking(VisualElement visualElementUsingAsset)
        {
            ILiveReloadAssetTracker <VisualTreeAsset> foundTracker = null;

            foreach (var trackerMapEntry in m_TrackerToVisualElementMap)
            {
                var tracker = trackerMapEntry.Key;

                if (!tracker.IsTrackingAsset(visualElementUsingAsset.m_VisualTreeAssetSource))
                {
                    continue;
                }

                var visualElements = trackerMapEntry.Value;

                foreach (var visualElement in visualElements)
                {
                    if (visualElement == visualElementUsingAsset)
                    {
                        foundTracker = tracker;
                        break;
                    }
                }

                if (foundTracker != null)
                {
                    visualElements.Remove(visualElementUsingAsset);
                    break;
                }
            }

            foundTracker?.StopTrackingAsset(visualElementUsingAsset.m_VisualTreeAssetSource);
        }
        private void StartVisualTreeAssetTracking(ILiveReloadAssetTracker <VisualTreeAsset> tracker, VisualTreeAsset asset)
        {
            int dirtyCount = tracker.StartTrackingAsset(asset);

            if (!m_AssetToTrackerMap.TryGetValue(asset, out var trackers))
            {
                trackers = new VisualTreeAssetToTrackMappingEntry()
                {
                    m_LastDirtyCount = dirtyCount,
                    m_Trackers       = new HashSet <ILiveReloadAssetTracker <VisualTreeAsset> >()
                };
                m_AssetToTrackerMap[asset] = trackers;
            }
            trackers.m_Trackers.Add(tracker);
        }
        internal void StartVisualTreeAssetTracking(ILiveReloadAssetTracker <VisualTreeAsset> tracker,
                                                   VisualElement visualElementUsingAsset)
        {
            tracker.StartTrackingAsset(visualElementUsingAsset.m_VisualTreeAssetSource);

            if (m_TrackerToVisualElementMap.TryGetValue(tracker, out var visualElements))
            {
                visualElements.Add(visualElementUsingAsset);
            }
            else
            {
                visualElements = new HashSet <VisualElement>();
                m_TrackerToVisualElementMap[tracker] = visualElements;
                m_LiveReloadVisualTreeAssetTrackers.Add(tracker);
            }
        }
        private void StopVisualTreeAssetTracking(ILiveReloadAssetTracker <VisualTreeAsset> tracker, VisualTreeAsset asset)
        {
            if (tracker == null)
            {
                return;
            }

            tracker.StopTrackingAsset(asset);

            if (m_AssetToTrackerMap.TryGetValue(asset, out var trackers))
            {
                trackers.m_Trackers.Remove(tracker);
                if (trackers.m_Trackers.Count == 0)
                {
                    m_AssetToTrackerMap.Remove(asset);
                }
            }
        }
        private void StartVisualTreeAssetTracking(ILiveReloadAssetTracker <VisualTreeAsset> tracker, VisualTreeAsset asset)
        {
            int dirtyCount = tracker.StartTrackingAsset(asset);

            if (!m_AssetToTrackerMap.TryGetValue(asset, out var trackers))
            {
                trackers = new VisualTreeAssetToTrackMappingEntry()
                {
                    m_LastDirtyCount                    = dirtyCount,
                    m_LastElementCount                  = asset.visualElementAssets.Count,
                    m_LastInlinePropertiesCount         = asset.inlineSheet.rules.Sum(r => r.properties.Length),
                    m_LastAttributePropertiesDirtyCount = asset.GetAttributePropertiesDirtyCount(),
                    m_Trackers = new HashSet <ILiveReloadAssetTracker <VisualTreeAsset> >()
                };
                m_AssetToTrackerMap[asset] = trackers;
            }
            trackers.m_Trackers.Add(tracker);
        }
        public void RegisterVisualTreeAssetTracker(ILiveReloadAssetTracker <VisualTreeAsset> tracker, VisualElement rootElement)
        {
            if (panel.contextType == ContextType.Editor)
            {
                m_EditorVisualTreeAssetTracker = tracker;
            }
            else
            {
                m_RuntimeVisualTreeAssetTrackers[rootElement] = tracker;

                // Add template container to be able to track newly created uxml assets
                if (rootElement is TemplateContainer container && container.templateSource != null)
                {
                    StartVisualTreeAssetTracking(tracker, container.templateSource);
                }

                // The enablement of Live Reload for panels of type ContextType.Player depends on the preference set
                // for the Game View itself.
                enable = DefaultEditorWindowBackend.IsGameViewWindowLiveReloadOn();
            }
        }