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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
 /// <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));
 }