static Relations MakeSetWithNonRequiredChildren( out SetQueryResult result, Dictionary <IMRObject, ChildMatchInfo> childrenExpectedMatchInfo, List <IMRObject> nonRequiredChildren, Exclusivity childrenExclusivity = Exclusivity.ReadOnly) { var relations = MakeBaseSet(out result, childrenExpectedMatchInfo); var childrenList = new List <IMRObject>(childrenExpectedMatchInfo.Keys); for (var i = 0; i < childrenList.Count; ++i) { var child = childrenList[i]; var args = relations.children[child]; // Half of the children will be non-required. if (i < childrenList.Count / 2) { nonRequiredChildren.Add(child); args.required = false; } args.tryBestMatchArgs.exclusivity = childrenExclusivity; relations.children[child] = args; } return(relations); }
void MarkDataUsed(SetQueryResult result, Dictionary <IMRObject, ChildMatchInfo> childrenExpectedMatchInfo) { StubRegistration(result.queryMatchId, s_SetArgs, childrenExpectedMatchInfo); var usedSet = UsedSetFromChildMatches(childrenExpectedMatchInfo); m_Db.MarkSetDataUsedForUpdates(result.queryMatchId, usedSet); }
static Relations MakeBaseSet(out SetQueryResult result, Dictionary <IMRObject, ChildMatchInfo> childrenExpectedMatchInfo) { var gameObject = new GameObject("Set"); gameObject.AddComponent <ProxyGroup>(); k_ToDestroy.Add(gameObject); // Make child MR objects and give them ordinary relations var children = new Dictionary <IMRObject, SetChildArgs>(); for (var i = 0; i < k_RelationCount + 1; ++i) { var childGameObject = new GameObject("Child" + i); k_ToDestroy.Add(childGameObject); childGameObject.transform.SetParent(gameObject.transform); var conditionsRoot = childGameObject.AddComponent <TestMRObject>(); var expectedMatchInfo = new ChildMatchInfo(); childrenExpectedMatchInfo[conditionsRoot] = expectedMatchInfo; var hasTraitCondition = childGameObject.AddComponent <SemanticTagCondition>(); hasTraitCondition.SetTraitName(k_CommonTrait); expectedMatchInfo.semanticTagTraits.Add(k_CommonTrait, true); var conditions = ProxyConditions.FromGenericIMRObject(conditionsRoot); var childArgs = new SetChildArgs(conditions); children[conditionsRoot] = childArgs; } // Make relations and store the expected trait values that will match them var childrenList = new List <IMRObject>(children.Keys); for (var i = 0; i < k_RelationCount; ++i) { var child1 = childrenList[i]; var child2 = childrenList[i + 1]; var floatRelation = gameObject.AddComponent <FloatRelation>(); floatRelation.Initialize(child1, child2, k_FloatTrait1, k_FloatTrait2); childrenExpectedMatchInfo[child1].floatTraits[floatRelation.child1TraitName] = i; childrenExpectedMatchInfo[child2].floatTraits[floatRelation.child2TraitName] = i + 1f; var vector2Relation = gameObject.AddComponent <Vector2Relation>(); vector2Relation.Initialize(child1, child2, k_Vector2Trait1, k_Vector2Trait2); childrenExpectedMatchInfo[child1].vector2Traits[vector2Relation.child1TraitName] = new Vector2(i, 0f); childrenExpectedMatchInfo[child2].vector2Traits[vector2Relation.child2TraitName] = new Vector2(i + 1f, 0f); } result = new SetQueryResult(QueryMatchID.Generate(), childrenList); var relations = new Relations(gameObject, children); s_SetArgs = new SetQueryArgs { relations = relations }; return(relations); }
public int Register(QueryMatchID id, int[] members, RelationDataPair[] pairs, SetQueryArgs args) { var index = GetInsertionIndex(); QueryMatchIds[index] = id; SetQueryArgs[index] = args; MemberIndices[index] = members; UsedByMatch[index] = Pools.DataIdHashSets.Get(); SetMatchData[index] = new SetMatchData() { dataAssignments = new Dictionary <IMRObject, int>(), exclusivities = new Dictionary <IMRObject, Exclusivity>() }; CachedTraits[index] = new RelationTraitCache(args.relations); Relations[index] = args.relations; RelationRatings[index] = Pools.RelationRatings.Get().Initialize(args.relations); RelationIndexPairs[index] = pairs; var localPairs = new RelationDataPair[pairs.Length]; MapGlobalToLocalRelationPairs(members, pairs, localPairs); LocalRelationIndexPairs[index] = localPairs; QueryResults[index] = new SetQueryResult(id); TimeOuts[index] = args.commonQueryData.timeOut; ReAcquireOnLoss[index] = args.commonQueryData.reacquireOnLoss; Priorities[index] = args.commonQueryData.priority; UpdateMatchInterval[index] = args.commonQueryData.updateMatchInterval; LastUpdateCheckTime[index] = 0f; AcquireHandlers[index] = args.onAcquire; UpdateHandlers[index] = args.onMatchUpdate; LossHandlers[index] = args.onLoss; TimeoutHandlers[index] = args.onTimeout; // SearchData will be initialized after the initial add m_Count++; MatchIdToIndex.Add(id, index); ValidIndices.Add(index); AcquiringIndices.Add(index); return(index); }
public bool TryUpdateSetQueryMatchData(SetMatchData data, Relations relations, SetQueryResult result, bool failOnNonRequiredChildren = false) { var dataAssignments = data.dataAssignments; // if data assignments are empty, this means all the group members have been unmatched, // so we return false to indicate that the update has failed if (dataAssignments.Count == 0) { return(false); } var childResults = result.childResults; var nonRequiredChildrenLost = result.nonRequiredChildrenLost; // Non-required children lost in previous updates should not have results. k_ChildrenList.Clear(); k_ChildrenList.AddRange(childResults.Keys); foreach (var child in k_ChildrenList) { if (!dataAssignments.ContainsKey(child)) { childResults.Remove(child); } } nonRequiredChildrenLost.Clear(); // First check ordinary conditions. var children = relations.children; foreach (var kvp in dataAssignments) { var child = kvp.Key; var args = children[child]; var childResult = childResults[child]; if (!TryUpdateQueryMatchData(dataAssignments[child], args.tryBestMatchArgs.conditions, args.TraitRequirements, childResult)) { if (args.required || failOnNonRequiredChildren) { return(false); } nonRequiredChildrenLost.Add(child); childResult.SetDataId((int)ReservedDataIDs.Invalid); } } if (!DataStillMatches(dataAssignments, relations, children, nonRequiredChildrenLost)) { return(false); } // Child results already contain the traits used for the ordinary relations, // now we just have to add the ones used for relations. FillRelationTraits(dataAssignments, relations, childResults); // as long as Poses need offsetting before output, they have to be special-cased if (relations.TryGetType(out IRelation <Pose>[] poseRelations) && poseRelations.Length > 0) { GetTraitProvider(out MARSTraitDataProvider <Pose> poseProvider); foreach (var relation in poseRelations) { var child1 = relation.child1; if (childResults.TryGetValue(child1, out var child1Result)) { var trait1Name = relation.child1TraitName; poseProvider.TryGetTraitValue(dataAssignments[child1], trait1Name, out var value1); child1Result.SetTrait(trait1Name, this.ApplyOffsetToPose(value1)); } var child2 = relation.child2; if (childResults.TryGetValue(child2, out var child2Result)) { var trait2Name = relation.child2TraitName; poseProvider.TryGetTraitValue(dataAssignments[child2], trait2Name, out var value2); child2Result.SetTrait(trait2Name, this.ApplyOffsetToPose(value2)); } } } return(true); }
/// <summary> /// Tries to fill out a SetQueryResult with updated data for a query that has been matched. /// This also checks if the data no longer meets the given relations. /// </summary> /// <param name="data">Specification of which data is used for each set child</param> /// <param name="relations">Bi-directional constraints that the data must continue to meet</param> /// <param name="result">Object that will contain the updated data that still matches the relations, /// as well as a list of non-required children that were lost during this update</param> /// <returns>True if the data still matches the relations, false otherwise</returns> public static bool TryUpdateSetQueryMatchData(this IUsesDatabaseQuerying obj, SetMatchData data, Relations relations, SetQueryResult result) { return(IUsesDatabaseQueryingMethods.TryUpdateSetQueryMatchData(data, relations, result)); }