How do queries work ?
The relation engine knows all types, objects and relations that are registered to it. Queries are a way to extract data from the relation engine (which is actually the whole point of the relation engine). There are two types of queries :
- Object queries are used to find one or multiple objects that contain specific types (i.e. all objects that are grabbable and screwers)
- Realization queries are used to know which realization (meaning, actions or relation implementation) match given sets of objects and available relations.
Queries can be launched either directly or asynchronously. In the later case, the query is launched in a separate thread and the provided callback method is called when the result is available.
Note
You can check the RelationEngineQueries
sample project
Create and launch an object query
The first step is to create an ObjectQueryParameters either from scratch or through a prefilled method like GetQueryAllObjects(IEngine)
The second step is to tweak the query parameters content by adding/removing objects that the query will look into and adding/removing types that the resulting objects must have.
When the query parameters are all set, the query can be launched using the relation engine. In unity this is done by calling one of the GetObjects(ObjectQueryParameters, Action<List<IObject>>, bool) methods. You can launch multiple queries at once and specify a callback Action if you want the query to run asynchronously
using System.Collections.Generic;
using UnityEngine;
using Xareus.Relations;
using Xareus.Relations.Unity;
namespace Xareus.Samples.RelationEngineQueries
{
/// <summary>
/// This class shows examples of how to query the Relation Engine for objects
/// </summary>
public class ObjectQueryExample : MonoBehaviour
{
#region Fields
public List<XUObject> ObjectsTheQueryWillLookInto;
#endregion
#region Methods
/// <summary>
/// This method will be called at the next Unity Update step when the query is done
/// </summary>
public static void ResultCallback(IEnumerable<IObject> objects)
{
string resultString = string.Join(", ", objects);
Debug.Log("Async Query Result: " + resultString);
}
/// <summary>
/// Query the Relation Engine for all possible realizations and call the callback when the query is done
/// </summary>
private void AsyncrhonousQuery()
{
ObjectQueryParameters directQueryParameters = ObjectQueryParameters.GetQueryAllObjects(RelationEngine.Instance.Engine);
// Create a type search and assign its parameters
TypeSearch typeSearch = new()
{
Type = new Type(typeof(SampleType)),
// Every object that holds the type TestType exactly once
MinOccurs = 1,
MaxOccurs = 1
};
directQueryParameters.TypesToHave.Add(typeSearch);
RelationEngine.Instance.GetObjects(directQueryParameters, ResultCallback);
}
private void Start()
{
DirectQuery();
AsyncrhonousQuery();
}
/// <summary>
/// Query the Relation Engine for all possible realizations (blocking the main thread)
/// </summary>
private void DirectQuery()
{
ObjectQueryParameters directQueryParameters = new();
foreach (XUObject xuObject in ObjectsTheQueryWillLookInto)
directQueryParameters.ObjectsToLookInto.Add(xuObject);
// Create a type search and assign its parameters
TypeSearch typeSearch = new()
{
Type = new Type(typeof(SampleType)),
// Every object that holds the type TestType once or twice will be returned
MinOccurs = 1,
MaxOccurs = 2
};
directQueryParameters.TypesToHave.Add(typeSearch);
List<IObject> directResult = RelationEngine.Instance.GetObjects(directQueryParameters);
string resultString = string.Join(", ", directResult);
Debug.Log("Direct Query Result: " + resultString);
}
#endregion
}
}
Create and launch a realization query
The first step is to create a RealizationQueryParameters either from scratch or through a prefilled methods like GetQueryAllOptionalAllRelation(IEngine), GetQueryAllOptional(IEngine) or GetQueryAllRelation(IEngine)
The second step is to tweak the query parameters content by adding/removing mandatory and optional objects or object types that the query will look into and adding/removing relations that will be considered.
When the query parameters are all set, the query can be launched using the relation engine. In unity this is done by calling one of the GetRealizations(RealizationQueryParameters, Action<List<XURealization>>, bool) methods. You can launch multiple queries at once and specify a callback Action if you want the query to run asynchronously to prevent blocking unity's main thread for example.
using System.Collections.Generic;
using UnityEngine;
using Xareus.Relations;
using Xareus.Relations.Unity;
namespace Xareus.Samples.RelationEngineQueries
{
/// <summary>
/// This class shows examples of how to query the Relation Engine for realizations
/// </summary>
public class RealizationQueryExample : MonoBehaviour
{
#region Fields
public List<XUObject> MandatoryObjects;
public List<XUObject> OptionalObjects;
public List<XURelation> Relations;
#endregion
#region Methods
/// <summary>
/// This method will be called at the next Unity Update step when the query is done
/// </summary>
public static void ResultCallback(IEnumerable<XURealization> realizations)
{
string resultString = string.Join(", ", realizations);
Debug.Log("Async Query Result: " + resultString);
}
/// <summary>
/// Query the Relation Engine for all possible realizations and call the callback when the query is done
/// </summary>
private static void AsyncrhonousQuery()
{
// This will query all possible realization in the scene
RealizationQueryParameters directQueryParameters = RealizationQueryParameters.GetQueryAllOptionalAllRelation(RelationEngine.Instance.Engine);
RelationEngine.Instance.GetRealizations(directQueryParameters, ResultCallback);
}
private void Start()
{
DirectQuery();
AsyncrhonousQuery();
}
/// <summary>
/// Query the Relation Engine for all possible realizations (blocking the main thread)
/// </summary>
private void DirectQuery()
{
RealizationQueryParameters directQueryParameters = new();
// The mandatory objects must be present in the result
foreach (XUObject xuObject in MandatoryObjects)
directQueryParameters.MandatoryObjects.Add(xuObject);
// The optional objects may be present in the result
foreach (XUObject xuObject in OptionalObjects)
directQueryParameters.OptionalObjects.Add(xuObject);
foreach (XURelation relation in Relations)
directQueryParameters.RelationsToUse.Add(relation);
List<XURealization> directResult = RelationEngine.Instance.GetRealizations(directQueryParameters);
string resultString = string.Join(", ", directResult);
Debug.Log("Direct Query Result: " + resultString);
}
#endregion
}
}