public BufferedAction(bool isAdd, QueryMatchID id, QueryArgs args) : this(isAdd ? ActionKind.AddSingle : ActionKind.RemoveSingle) { QueryId = id; SingleArgs = args; }
static void ModifySetQueryNoop(QueryMatchID queryMatchID, SetQueryArgs queryArgs) { }
public BufferedAction(ActionKind kind, QueryMatchID id) : this(kind) { QueryId = id; }
void RegisterSetQuery(QueryMatchID queryMatchID, SetQueryArgs queryArgs) { EnqueueUpdate(new BufferedAction(true, queryMatchID, queryArgs)); }
// This dummy function is used to prevent errors from happening if a query tries to unregister after unload static bool UnregisterQueryNoop(QueryMatchID queryMatchID, bool allMatches) { return(false); }
public BufferedAction(QueryMatchID id, SetQueryArgs args) : this(ActionKind.ModifyGroup) { QueryId = id; GroupArgs = args; }
internal void Modify(QueryMatchID id, SetQueryArgs args) { if (!Data.MatchIdToIndex.TryGetValue(id, out var groupIndex)) { return; } Assert.IsTrue(Data.QueryMatchIds[groupIndex].Equals(id), $"Mismatch between QueryMatchId {id} and group index {groupIndex}"); k_SetMemberIndices.Clear(); k_KnownMembers.Clear(); var hasMembers = MemberData.MatchIdToIndex.TryGetValue(id, out var memberIndices); if (hasMembers) { // collect data on known members to facilitate remove / update for (var orderIndex = 0; orderIndex < memberIndices.Count; orderIndex++) { var memberIndex = memberIndices[orderIndex]; var mrObject = MemberData.ObjectReferences[memberIndex]; k_KnownMembers.Add(new KnownMember(mrObject, memberIndex)); } var children = args.relations.children; // remove members that are gone for (var i = k_KnownMembers.Count - 1; i >= 0; i--) { var knownMember = k_KnownMembers[i]; if (children.ContainsKey(knownMember.Reference)) { continue; } MemberData.Remove(id, knownMember.DataIndex); // Data child removal will happen with Data.Modify // as that will reconstruct all data buffers / structures // and re-associate with the current set of relations k_KnownMembers.RemoveAt(i); } // add or update foreach (var kvp in children) { var knownIndex = -1; for (var i = 0; i < k_KnownMembers.Count; i++) { var knownMember = k_KnownMembers[i]; if (!ReferenceEquals(knownMember.Reference, kvp.Key)) { continue; } knownIndex = i; break; } if (knownIndex >= 0) { // update var knownMember = k_KnownMembers[knownIndex]; MemberData.Modify(id, knownMember.DataIndex, kvp.Value); k_KnownMembers.RemoveAt(knownIndex); } else { // register MemberData.Register(id, kvp.Key, kvp.Value); } } k_KnownMembers.Clear(); } else { RegisterRelationChildren(id, args); MemberData.MatchIdToIndex.TryGetValue(id, out memberIndices); } GetIndexPairs(id, args); // the index arrays for group & relation members are so small that we create new ones // on registration, instead of using pooled Lists var memberIndicesArray = memberIndices.ToArray(); var relationIndexPairs = k_RelationIndexPairs.ToArray(); Data.Modify(groupIndex, memberIndicesArray, relationIndexPairs, args); k_TempChildResults.Clear(); foreach (var i in memberIndices) { k_TempChildResults.Add(MemberData.ObjectReferences[i], MemberData.QueryResults[i]); } Data.QueryResults[groupIndex].SetChildren(k_TempChildResults); // for each group member, store a representation of which relations it belongs to. Data.GetRelationMemberships(groupIndex, k_RelationMemberships); foreach (var kvp in k_RelationMemberships) { var memberIndex = kvp.Key; MemberData.RelationMemberships[memberIndex] = kvp.Value; } // calculate the solve order weighting for this group var weights = QueryPipelineConfiguration.instance.SolveOrderWeighting; var order = GetGroupOrderWeight(memberIndicesArray, relationIndexPairs.Length, MemberData.Exclusivities, weights); Data.OrderWeights[groupIndex] = order; Data.InitializeSearchData(groupIndex, MemberData.ReducedConditionRatings); }
void RegisterQuery(QueryMatchID queryMatchID, QueryArgs queryArgs) { AddQuery(queryMatchID, queryArgs); }
void AddQuery(QueryMatchID queryMatchID, QueryArgs args) { EnqueueUpdate(new BufferedAction(true, queryMatchID, args)); }
void Filter(Dictionary <int, HashSet <int> > dataUsedByQueries, Dictionary <int, QueryMatchID> reservedData, Dictionary <int, int> sharedDataUsers, HashSet <int> dataIDs, QueryMatchID matchId, Exclusivity exclusivity) { if (s_IDsToRemove.Length < dataIDs.Count) { Array.Resize(ref s_IDsToRemove, dataIDs.Count + MARSMemoryOptions.ResizeHeadroom); } var removeCounter = 0; var queryId = matchId.queryID; // Data should not be used again if this query is already using it if (dataUsedByQueries.TryGetValue(queryId, out var dataUsedByQuery)) { dataIDs.ExceptWithNonAlloc(dataUsedByQuery); } var isReadOnly = exclusivity == Exclusivity.ReadOnly; // read only matches are valid if not already used by the query, so we're done with this one if (!isReadOnly) { var isShared = exclusivity == Exclusivity.Shared; foreach (var dataID in dataIDs) { var idIsPreviouslyReserved = reservedData.ContainsKey(dataID); // if it's previously reserved, neither shared nor reserved can use it if (idIsPreviouslyReserved) { s_IDsToRemove[removeCounter] = dataID; removeCounter++; continue; } // if this query is reserved & something has previously used it as shared, can't use it if (!isShared && sharedDataUsers.ContainsKey(dataID)) { s_IDsToRemove[removeCounter] = dataID; removeCounter++; } } } #if UNITY_EDITOR if (removeCounter > 0) { // collect information about what, if anything, got filtered, for editor debug purposes var filteredList = Pools.IntLists.Get(); for (var j = 0; j < removeCounter; j++) { filteredList.Add(s_IDsToRemove[j]); } DebugFilteredResults.Add(matchId, filteredList); } #endif for (int i = 0; i < removeCounter; i++) { dataIDs.Remove(s_IDsToRemove[i]); } }
bool TryAssignStandaloneMatch(QueryMatchID queryMatchId, int newDataId, bool matchConditions = true) { var data = m_PipelinesModule.StandalonePipeline.Data; if (!data.MatchIdToIndex.TryGetValue(queryMatchId, out var index)) { throw new ArgumentException($"{queryMatchId} is not registered, so cannot have a match assigned"); } // the bare minimum requirement for a new data match to be valid is that it has every trait required by the Proxy var traitRequirements = data.TraitRequirements[index]; if (!DataHasAllTraitRequirements(newDataId, traitRequirements)) { throw new ArgumentException($"Data ID \"{newDataId}\" does not have all traits required by {queryMatchId}"); } if (matchConditions) { if (!m_Database.DataPassesAllConditions(data.Conditions[index], newDataId)) { throw new ArgumentException($"Data ID \"{newDataId}\" did not pass every Condition for {queryMatchId}"); } } var exclusivity = data.Exclusivities[index]; // manual matches must still obey data availability if (!m_Database.DataAvailableForUse(newDataId, queryMatchId.queryID, exclusivity)) { throw new ArgumentException($"Data ID \"{newDataId}\" is not available for use by {queryMatchId}"); } // all validity checks have passed, so unmatch the previous data if any var previouslyAssignedDataId = data.BestMatchDataIds[index]; var hasExistingMatch = previouslyAssignedDataId != (int)ReservedDataIDs.Invalid; if (hasExistingMatch) { UnsetStandaloneMatch(queryMatchId, false, false); } else { data.UpdatingIndices.Add(index); data.AcquiringIndices.Remove(index); } UnsetStandaloneMatchIndices.Remove(index); // claim the new data id for this proxy m_Database.MarkDataUsedForUpdates(newDataId, queryMatchId, exclusivity); data.BestMatchDataIds[index] = newDataId; // fill the proxy's result with the new data var result = data.QueryResults[index]; result.Clear(); result.SetDataId(newDataId); m_Database.FillQueryResultRequirements(newDataId, traitRequirements, result); // if this query had previously acquired, treat setting a new match as an update rather than acquire if (hasExistingMatch) { data.UpdateHandlers[index]?.Invoke(result); } else { data.AcquireHandlers[index].Invoke(result); } return(true); }
public SetQueryResult(QueryMatchID id) { queryMatchId = id; }
public SetQueryResult(QueryMatchID id, IEnumerable <IMRObject> children) { queryMatchId = id; SetChildren(children); }
public void Reset() { queryMatchId = QueryMatchID.NullQuery; Clear(); }
public BufferedAction(bool isAdd, QueryMatchID id, SetQueryArgs args) : this(isAdd ? ActionKind.AddGroup : ActionKind.RemoveGroup) { QueryId = id; GroupArgs = args; }
void RemoveQuery(QueryMatchID queryMatchID) { EnqueueUpdate(new BufferedAction(BufferedAction.ActionKind.RemoveSingle, queryMatchID)); }
public BufferedAction(QueryMatchID id, QueryArgs args) : this(ActionKind.ModifySingle) { QueryId = id; SingleArgs = args; }
internal void ModifySetQuery(QueryMatchID id, SetQueryArgs args) { EnqueueUpdate(new BufferedAction(id, args)); }
internal bool UnsetStandaloneMatchPublic(QueryMatchID queryMatchId, bool seekNewMatch) { return(UnsetStandaloneMatch(queryMatchId, seekNewMatch)); }
// ReSharper disable once UnusedMember.Local void FillQueryResultInternal(int dataId, object conditions, object traits, QueryMatchID matchId, QueryResult result) { }