95 lines
No EOL
2.6 KiB
C#
95 lines
No EOL
2.6 KiB
C#
using System;
|
|
using System.Threading;
|
|
|
|
namespace Plugin
|
|
{
|
|
/// <summary>
|
|
/// Result of a query to the engine. Allows to wait until the result is available.
|
|
/// </summary>
|
|
/// <typeparam name="T">Type of data inside the result.</typeparam>
|
|
public interface IQueryResult<T>
|
|
{
|
|
/// <summary>
|
|
/// Waits for the result, returns true if the timeout didn't expire.
|
|
/// </summary>
|
|
bool Join(out T result, int millisecondsTimeout = QueryResult<T>.DefaultTimeout);
|
|
|
|
/// <summary>
|
|
/// Triggered when the query is filled.
|
|
/// </summary>
|
|
event Action<T> Done;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Result of a query to the engine. Allows to wait until the result is available.
|
|
/// </summary>
|
|
/// <typeparam name="T">Type of data inside the result.</typeparam>
|
|
public class QueryResult<T> : IQueryResult<T>
|
|
{
|
|
public const int DefaultTimeout = 2500;
|
|
|
|
private readonly AbstractPlugin _plugin;
|
|
private readonly ManualResetEvent _waitHandle = new ManualResetEvent(false);
|
|
private T _content;
|
|
|
|
public QueryResult(AbstractPlugin plugin)
|
|
{
|
|
_plugin = plugin;
|
|
}
|
|
|
|
public T Content
|
|
{
|
|
get { return _content; }
|
|
set
|
|
{
|
|
_content = value;
|
|
_waitHandle.Set();
|
|
OnDone();
|
|
}
|
|
}
|
|
|
|
public bool Join(out T result, int millisecondsTimeout = DefaultTimeout)
|
|
{
|
|
if (_waitHandle.WaitOne(millisecondsTimeout))
|
|
{
|
|
result = _content;
|
|
return true;
|
|
}
|
|
result = _content;
|
|
_plugin.ReportTimeoutFailure();
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Separated in a backend and the interface so we can trigger the event right away if already filled.
|
|
/// </summary>
|
|
private event Action<T> DoneBackend;
|
|
|
|
/// <summary>
|
|
/// Triggered when the query is filled.
|
|
/// </summary>
|
|
public event Action<T> Done
|
|
{
|
|
add
|
|
{
|
|
DoneBackend += value;
|
|
|
|
// When already set, we trigger the event right now.
|
|
if (_waitHandle.WaitOne(0))
|
|
{
|
|
OnDone();
|
|
}
|
|
}
|
|
remove { DoneBackend -= value; }
|
|
}
|
|
|
|
protected virtual void OnDone()
|
|
{
|
|
var done = DoneBackend;
|
|
if (done != null)
|
|
{
|
|
done(Content);
|
|
}
|
|
}
|
|
}
|
|
} |