internal void Update() { if (null == m_SearchQuery || Mode == SearchHandlerType.sync) { return; } // The progress bar displays progress from 0 - 90% so we can visually see it reaching the end. m_SearchElement.ShowProgress(m_CurrentSearchDataIndex / (m_Count * 0.9f)); m_Stopwatch.Restart(); m_FrameBatch.Clear(); var batchSize = Math.Max(SearchDataBatchMaxSize, 1); for (;;) { if (null == m_Enumerator) { var batch = m_GetSearchDataFunc().Skip(m_CurrentSearchDataIndex).Take(batchSize); if (!batch.Any()) { // This is an empty batch. We must always call 'OnFilter' at least once regardless of results. OnFilter(m_SearchQuery, m_FrameBatch); Stop(); return; } m_Enumerator = m_SearchQuery.Apply(batch).GetEnumerator(); m_CurrentSearchDataIndex += batchSize; } while (m_Enumerator.MoveNext()) { m_FrameBatch.Add(m_Enumerator.Current); if (m_Stopwatch.ElapsedMilliseconds >= MaxFrameProcessingTimeMs) { if (m_FrameBatch.Count > 0) { m_FilterBatchCount++; OnFilter(m_SearchQuery, m_FrameBatch); } return; } } if (m_FilterBatchCount == 0) { OnFilter(m_SearchQuery, m_FrameBatch); } Stop(); return; } }
void BuildFilterResults() { m_SearchResultsFlatSystemList.Clear(); if (m_CurrentSearchQuery == null || string.IsNullOrWhiteSpace(m_CurrentSearchQuery.SearchString) || m_CurrentSearchQuery.Tokens.Count == 0 && string.IsNullOrEmpty(SearchFilter.ErrorComponentType)) { m_SearchResultsFlatSystemList.AddRange(m_AllSystemsForSearch); } else { foreach (var systemForSearch in m_AllSystemsForSearch) { systemForSearch.SystemDependencyCache = (from kvp in m_SystemDependencyMap where kvp.Value.Contains(systemForSearch.SystemName) select kvp.Key).ToArray(); } #if QUICKSEARCH_AVAILABLE m_SearchResultsFlatSystemList.AddRange(m_CurrentSearchQuery.Apply(m_AllSystemsForSearch)); #else using (var candidates = PooledHashSet <SystemForSearch> .Make()) { foreach (var system in m_AllSystemsForSearch) { if (SearchFilter.Names.All(n => system.SystemName.IndexOf(n, StringComparison.OrdinalIgnoreCase) >= 0)) { candidates.Set.Add(system); } if (candidates.Set.Contains(system) && !SearchFilter.ComponentNames.All(component => system.ComponentNamesInQuery.Any(c => c.IndexOf(component, StringComparison.OrdinalIgnoreCase) >= 0))) { candidates.Set.Remove(system); } if (candidates.Set.Contains(system) && SearchFilter.DependencySystemNames.All(dependency => system.SystemDependency.Any(c => c.IndexOf(dependency, StringComparison.OrdinalIgnoreCase) >= 0))) { m_SearchResultsFlatSystemList.Add(system); } } } #endif } }
void ISearchQueryHandler <TData> .HandleSearchQuery(ISearchQuery <TData> query) { if (null == m_GetSearchDataFunc) { return; } Stop(); if (Mode == SearchHandlerType.sync || string.IsNullOrEmpty(query.SearchString)) { OnBeginSearch(query); OnFilter(query, query.Apply(m_GetSearchDataFunc())); OnEndSearch(query); } else { m_SearchQuery = query; m_CurrentSearchDataIndex = 0; m_Count = m_GetSearchDataFunc().Count(); OnBeginSearch(query); } }
void RefreshSearchView() { if (m_SearcherCacheNeedsRebuild) { m_ItemsCache.Rebuild(m_TreeViewRootItems.OfType <EntityHierarchyItem>()); m_SearcherCacheNeedsRebuild = false; } m_ListViewFilteredItems.Clear(); var filteredData = m_CurrentQuery?.Apply(m_ItemsCache.Items) ?? m_ItemsCache.Items; EntityHierarchyItem lastSubsceneItem = null; foreach (var item in filteredData) { if (item.NodeId.Kind != NodeKind.Entity) { continue; } if (item.parent != null && IsParentedBySubScene(item, out var closestSubScene) && closestSubScene != lastSubsceneItem) { lastSubsceneItem = closestSubScene; m_ListViewFilteredItems.Add(lastSubsceneItem); } m_ListViewFilteredItems.Add(item); } if (m_ListViewFilteredItems.Count == 0 && m_QueryBuilderResult.IsValid) { m_SearchEmptyMessage.Title = NoEntitiesFoundTitle; m_SearchEmptyMessage.Message = string.Empty; m_CurrentViewMode = ViewMode.Message; } m_ListView.Refresh(); bool IsParentedBySubScene(EntityHierarchyItem item, out EntityHierarchyItem subSceneItem) { subSceneItem = null; var current = item; while (true) { if (current.parent == null) { return(false); } var currentParent = (EntityHierarchyItem)current.parent; switch (currentParent.NodeId.Kind) { case NodeKind.Root: case NodeKind.Scene: return(false); case NodeKind.Entity: current = currentParent; continue; case NodeKind.SubScene: subSceneItem = currentParent; return(true); default: throw new NotSupportedException($"{nameof(currentParent.NodeId.Kind)} is not supported in this context"); } } } }