Game.Routes.SearchSystem
Assembly: Assembly-CSharp (game binary)
Namespace: Game.Routes
Type: class
Base: GameSystemBase, IPreDeserialize
Summary:
SearchSystem maintains a spatial search index (NativeQuadTree
Fields
-
private EntityQuery m_UpdatedRoutesQuery
Holds an EntityQuery that selects route entities that have been updated/created/deleted (or path elements/segments/events that indicate changes). Used in OnUpdate to find which entities need tree updates. -
private EntityQuery m_AllRoutesQuery
Holds an EntityQuery that selects all non-temp route entities (used when the system is in a "loaded" state to rebuild the entire tree). -
private NativeQuadTree<RouteSearchItem, QuadTreeBoundsXZ> m_SearchTree
The primary spatial index storing route search items and their bounds. Allocated with Allocator.Persistent in OnCreate and disposed in OnDestroy. -
private NativeParallelHashMap<Entity, int> m_ElementCount
Maps an entity to the count of curve/segment elements indexed for that entity. Used to track how many element entries exist for removal/update logic. -
private JobHandle m_ReadDependencies
Aggregates job handles of jobs that read the search tree. Used to coordinate safe concurrent access. -
private JobHandle m_WriteDependencies
Holds the job handle of the job that last wrote to the search tree. Used together with m_ReadDependencies to determine when the tree is safe to read or write. -
private bool m_Loaded
Flag set during PreDeserialize to indicate the next OnUpdate should treat the query as a full reload (rebuild/search-tree population). -
private TypeHandle __TypeHandle
Internal container for EntityTypeHandle / ComponentTypeHandle / BufferTypeHandle / ComponentLookup / BufferLookup instances used by the UpdateSearchTreeJob. Assigned on system creation for fast access.
Properties
- This class does not expose public properties.
Constructors
public SearchSystem()
Default constructor (preserved). The real initialization occurs in the OnCreate override where queries and native collections are created.
Methods
-
protected override void OnCreate()
Initializes entity queries used for incremental and full updates, creates the NativeQuadTree (m_SearchTree) and NativeParallelHashMap (m_ElementCount). Queries include criteria for Waypoint/Position, Segment/PathElement and events/path-updated components. Called by the ECS bootstrap. -
protected override void OnDestroy()
Disposes m_SearchTree and m_ElementCount and calls base.OnDestroy(). Ensures native containers are released when the system is destroyed. -
private bool GetLoaded()
Internal helper used in OnUpdate. If m_Loaded is true, it clears the flag and returns true (indicating that the next update should treat queries as a full load). Otherwise returns false. -
protected override void OnUpdate()
Main update loop. Chooses either the incremental (m_UpdatedRoutesQuery) or full (m_AllRoutesQuery) query depending on GetLoaded(). If the chosen query isn't empty, it constructs an UpdateSearchTreeJob with all required handles and lookups, retrieves the search tree via GetSearchTree(readOnly: false, out dependencies), schedules the job over the query (JobChunk schedule) and records the write dependency via AddSearchTreeWriter. The job updates, adds or removes entries in the quad-tree depending on entity state (created/updated/deleted/path-updated). -
public NativeQuadTree<RouteSearchItem, QuadTreeBoundsXZ> GetSearchTree(bool readOnly, out JobHandle dependencies)
Returns the internal quad-tree. Also outputs current combined JobHandle dependencies: - If readOnly is true, dependencies = m_WriteDependencies (so readers wait for writers).
-
If readOnly is false, dependencies = JobHandle.CombineDependencies(m_ReadDependencies, m_WriteDependencies) (writers must wait for prior readers/writers). This method is how other systems/jobs obtain a reference to the search tree and the dependencies they must respect.
-
public void AddSearchTreeReader(JobHandle jobHandle)
Registers a job that reads the search tree by combining jobHandle into m_ReadDependencies. This prevents a writer from proceeding until all readers complete. -
public void AddSearchTreeWriter(JobHandle jobHandle)
Registers a writer job by setting m_WriteDependencies to jobHandle. Writers will be combined appropriately by GetSearchTree when needed. -
public void PreDeserialize(Context context)
Called before deserialization (implements IPreDeserialize). Completes any outstanding dependencies for writing the tree, clears the search tree, and sets m_Loaded = true so the next update rebuilds the tree from all route entities. -
private void __AssignQueries(ref SystemState state)
Internal/compiled helper (used by OnCreateForCompiler). Present as part of codegen; in this file it only creates/cleans an EntityQueryBuilder placeholder but should not be used directly. -
protected override void OnCreateForCompiler()
Compiler helper which calls __AssignQueries and assigns the component type handles via __TypeHandle.__AssignHandles. Used in compiled environment to satisfy generated code expectations.
Nested types / Jobs
-
private struct TypeHandle
Contains precomputed EntityTypeHandle, ComponentTypeHandle(read-only), BufferTypeHandle , ComponentLookup , and BufferLookup . Has a method __AssignHandles(ref SystemState state) to populate all handles for the current SystemState. -
public struct UpdateSearchTreeJob : IJobChunk
(BurstCompile)
This is the job that performs the heavy work of adding/updating/removing entries in the native quad-tree. Important behaviors: - Fields: various ReadOnly type handles (EntityTypeHandle, ComponentTypeHandle
, Created, Deleted, PrefabRef, PathUpdated, BufferTypeHandle ) and ComponentLookup/BufferLookup instances, plus m_Loaded flag, m_SearchTree (NativeQuadTree) and m_ElementCount (NativeParallelHashMap ). - Execute(in ArchetypeChunk chunk, ...) inspects chunk component state:
- If chunk has PathUpdated: iterates PathUpdated elements and selectively updates segments in the tree if segment present and not temp/updated/deleted.
- Else if m_Loaded or chunk has Created: adds entries for waypoint positions and curve elements to the tree (calculates Bounds3 via RouteUtils.CalculateBounds using RouteData).
- Else if chunk has Deleted: removes waypoint entry and all element entries for that entity (uses m_ElementCount to know how many to remove).
- Else (normal update): updates bounds for entity's waypoint and its curve elements; uses UpdateSegment helper to add/update/remove per-element entries and maintain m_ElementCount.
- UpdateSegment(Entity, PrefabRef, DynamicBuffer
) helper updates per-element quad-tree entries for a segment; it reconciles the new element count with previous count (m_ElementCount) and adds/updates/removes entries accordingly. - The IJobChunk.Execute wrapper calls the typed Execute to satisfy the interface.
Notes about thread-safety and usage: - The job writes to m_SearchTree and m_ElementCount so callers must obtain the tree via GetSearchTree(readOnly:false, out deps) prior to scheduling jobs that will use it, and must register writers/readers via AddSearchTreeWriter/AddSearchTreeReader so the system can coordinate dependencies. - The UpdateSearchTreeJob is Burst-compiled and uses ComponentTypeHandle/BufferTypeHandle/ComponentLookup/BufferLookup for efficient chunk iteration. - Route bounds are computed via RouteUtils.CalculateBounds using RouteData looked up from a PrefabRef.
Usage Example
// Example: read the search tree safely from another system or job
var searchSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystem<SearchSystem>();
if (searchSystem != null)
{
JobHandle deps;
var tree = searchSystem.GetSearchTree(readOnly: true, out deps);
// If you need immediate (synchronous) access:
deps.Complete();
// Now 'tree' can be queried on the main thread (or used to build job data).
// If you schedule a job that reads the tree, register it:
// searchSystem.AddSearchTreeReader(myReaderJobHandle);
}
If you need to force a full rebuild after loading/deserialization, SearchSystem.PreDeserialize is invoked by the runtime to clear the tree and mark a full reload on the next update.