initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
@ -0,0 +1,32 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Access to AsyncOperation (deprecated)
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Authentication")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Authentication.Editor")]
|
||||
#if UNITY_INCLUDE_TESTS
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Authentication.Tests")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Authentication.EditorTests")]
|
||||
#endif
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.TestUtils")]
|
||||
|
||||
// Required for access to Networking API
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.Networking")]
|
||||
|
||||
// Required for CoreLogger access
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.Configuration")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.Configuration.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.Registration")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.Scheduler")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.Telemetry")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.Threading")]
|
||||
|
||||
// Test assemblies
|
||||
#if UNITY_INCLUDE_TESTS
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.Tests")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.EditorTests")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.TestUtils.Tests")]
|
||||
[assembly: InternalsVisibleTo("Unity.Services.Core.TestUtils.EditorTests")]
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a7624b141c8742c78133946b1e5643d7
|
||||
timeCreated: 1622749740
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 24217193ca52348f793854bafd71c78f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,223 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation for <see cref="IAsyncOperation"/>.
|
||||
/// </summary>
|
||||
class AsyncOperation : IAsyncOperation
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool IsDone { get; protected set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public AsyncOperationStatus Status { get; protected set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<IAsyncOperation> Completed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsDone)
|
||||
value(this);
|
||||
else
|
||||
m_CompletedCallback += value;
|
||||
}
|
||||
remove => m_CompletedCallback -= value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Exception Exception { get; protected set; }
|
||||
|
||||
/// <inheritdoc cref="IAsyncOperation.Completed"/>
|
||||
protected Action<IAsyncOperation> m_CompletedCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Set this operation's status <see cref="AsyncOperationStatus.InProgress"/>.
|
||||
/// </summary>
|
||||
public void SetInProgress()
|
||||
{
|
||||
Status = AsyncOperationStatus.InProgress;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Complete this operation as a success.
|
||||
/// </summary>
|
||||
public void Succeed()
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsDone = true;
|
||||
Status = AsyncOperationStatus.Succeeded;
|
||||
m_CompletedCallback?.Invoke(this);
|
||||
m_CompletedCallback = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Complete this operation as a failure using the given <paramref name="reason"/>.
|
||||
/// </summary>
|
||||
/// <param name="reason">
|
||||
/// The exception at the source of the failure.
|
||||
/// </param>
|
||||
public void Fail(Exception reason)
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Exception = reason;
|
||||
IsDone = true;
|
||||
Status = AsyncOperationStatus.Failed;
|
||||
m_CompletedCallback?.Invoke(this);
|
||||
m_CompletedCallback = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Complete this operation as a cancellation.
|
||||
/// </summary>
|
||||
public void Cancel()
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Exception = new OperationCanceledException();
|
||||
IsDone = true;
|
||||
Status = AsyncOperationStatus.Cancelled;
|
||||
m_CompletedCallback?.Invoke(this);
|
||||
m_CompletedCallback = null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
bool IEnumerator.MoveNext() => !IsDone;
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <remarks>
|
||||
/// Left empty because we don't support operation reset.
|
||||
/// </remarks>
|
||||
void IEnumerator.Reset() {}
|
||||
|
||||
/// <inheritdoc/>
|
||||
object IEnumerator.Current => null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default implementation for <see cref="IAsyncOperation{T}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The result's type of this operation.
|
||||
/// </typeparam>
|
||||
class AsyncOperation<T> : IAsyncOperation<T>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool IsDone { get; protected set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public AsyncOperationStatus Status { get; protected set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<IAsyncOperation<T>> Completed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsDone)
|
||||
value(this);
|
||||
else
|
||||
m_CompletedCallback += value;
|
||||
}
|
||||
remove => m_CompletedCallback -= value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Exception Exception { get; protected set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public T Result { get; protected set; }
|
||||
|
||||
/// <inheritdoc cref="IAsyncOperation{T}.Completed"/>
|
||||
protected Action<IAsyncOperation<T>> m_CompletedCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Set this operation's status <see cref="AsyncOperationStatus.InProgress"/>.
|
||||
/// </summary>
|
||||
public void SetInProgress()
|
||||
{
|
||||
Status = AsyncOperationStatus.InProgress;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Complete this operation as a success and set its result.
|
||||
/// </summary>
|
||||
/// <param name="result">
|
||||
/// The result of this operation.
|
||||
/// </param>
|
||||
public void Succeed(T result)
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Result = result;
|
||||
IsDone = true;
|
||||
Status = AsyncOperationStatus.Succeeded;
|
||||
m_CompletedCallback?.Invoke(this);
|
||||
m_CompletedCallback = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Complete this operation as a failure using the given <paramref name="reason"/>.
|
||||
/// </summary>
|
||||
/// <param name="reason">
|
||||
/// The exception at the source of the failure.
|
||||
/// </param>
|
||||
public void Fail(Exception reason)
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Exception = reason;
|
||||
IsDone = true;
|
||||
Status = AsyncOperationStatus.Failed;
|
||||
m_CompletedCallback?.Invoke(this);
|
||||
m_CompletedCallback = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Complete this operation as a cancellation.
|
||||
/// </summary>
|
||||
public void Cancel()
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Exception = new OperationCanceledException();
|
||||
IsDone = true;
|
||||
Status = AsyncOperationStatus.Cancelled;
|
||||
m_CompletedCallback?.Invoke(this);
|
||||
m_CompletedCallback = null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
bool IEnumerator.MoveNext() => !IsDone;
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <remarks>
|
||||
/// Left empty because we don't support operation reset.
|
||||
/// </remarks>
|
||||
void IEnumerator.Reset() {}
|
||||
|
||||
/// <inheritdoc/>
|
||||
object IEnumerator.Current => null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1978478d5dedf4c0bbc8a8ac97566699
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation for <see cref="IAsyncOperationAwaiter"/>.
|
||||
/// </summary>
|
||||
struct AsyncOperationAwaiter : IAsyncOperationAwaiter
|
||||
{
|
||||
IAsyncOperation m_Operation;
|
||||
|
||||
/// <summary>
|
||||
/// Create an awaiter for the given <paramref name="asyncOperation"/>.
|
||||
/// </summary>
|
||||
/// <param name="asyncOperation">
|
||||
/// The operation to await.
|
||||
/// </param>
|
||||
public AsyncOperationAwaiter(IAsyncOperation asyncOperation)
|
||||
{
|
||||
m_Operation = asyncOperation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schedules the continuation action that's invoked when the instance completes.
|
||||
/// </summary>
|
||||
/// <param name="continuation">
|
||||
/// The action to invoke when the operation completes.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// Straightforward implementation of <see cref="System.Runtime.CompilerServices.ICriticalNotifyCompletion"/>.
|
||||
/// </remarks>
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
m_Operation.Completed += operation => continuation();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="OnCompleted"/>
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
m_Operation.Completed += operation => continuation();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsCompleted => m_Operation.IsDone;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void GetResult()
|
||||
{
|
||||
if (m_Operation.Status == AsyncOperationStatus.Failed
|
||||
|| m_Operation.Status == AsyncOperationStatus.Cancelled)
|
||||
{
|
||||
throw m_Operation.Exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default implementation for <see cref="IAsyncOperationAwaiter{T}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The result's type of the awaited operation.
|
||||
/// </typeparam>
|
||||
struct AsyncOperationAwaiter<T> : IAsyncOperationAwaiter<T>
|
||||
{
|
||||
IAsyncOperation<T> m_Operation;
|
||||
|
||||
/// <summary>
|
||||
/// Create an awaiter for the given <paramref name="asyncOperation"/>.
|
||||
/// </summary>
|
||||
/// <param name="asyncOperation">
|
||||
/// The operation to await.
|
||||
/// </param>
|
||||
public AsyncOperationAwaiter(IAsyncOperation<T> asyncOperation)
|
||||
{
|
||||
m_Operation = asyncOperation;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="AsyncOperationAwaiter.OnCompleted"/>
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
m_Operation.Completed += obj => continuation();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="AsyncOperationAwaiter.UnsafeOnCompleted"/>
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
m_Operation.Completed += obj => continuation();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsCompleted => m_Operation.IsDone;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public T GetResult()
|
||||
{
|
||||
if (m_Operation.Status == AsyncOperationStatus.Failed
|
||||
|| m_Operation.Status == AsyncOperationStatus.Cancelled)
|
||||
{
|
||||
throw m_Operation.Exception;
|
||||
}
|
||||
|
||||
return m_Operation.Result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c3755af4fd119427481c46ab5946719c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,206 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for asynchronous operations.
|
||||
///
|
||||
/// Implemented by: TaskAsyncOperation
|
||||
/// </summary>
|
||||
abstract class AsyncOperationBase : CustomYieldInstruction, IAsyncOperation, INotifyCompletion
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates if coroutine should be kept suspended.
|
||||
///
|
||||
/// From CustomYieldInstruction.
|
||||
/// </summary>
|
||||
public override bool keepWaiting => !IsCompleted;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this operation is completed.
|
||||
///
|
||||
/// Required to make the operation awaitable
|
||||
/// </summary>
|
||||
public abstract bool IsCompleted { get; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, this operation either succeeded, failed, or has been canceled.
|
||||
///
|
||||
/// From IAsyncOperation
|
||||
/// </summary>
|
||||
public bool IsDone => IsCompleted;
|
||||
|
||||
/// <summary>
|
||||
/// The current status of this operation.
|
||||
///
|
||||
/// From IAsyncOperation
|
||||
/// </summary>
|
||||
public abstract AsyncOperationStatus Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The exception that occured during the operation if it failed.
|
||||
///
|
||||
/// From IAsyncOperation
|
||||
/// </summary>
|
||||
public abstract Exception Exception { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Result of the operation.
|
||||
///
|
||||
/// Required to make the operation awaitable
|
||||
/// </summary>
|
||||
public abstract void GetResult();
|
||||
|
||||
/// <summary>
|
||||
/// Awaiter on the operation.
|
||||
///
|
||||
/// Required to make the operation awaitable
|
||||
/// </summary>
|
||||
public abstract AsyncOperationBase GetAwaiter();
|
||||
|
||||
Action<IAsyncOperation> m_CompletedCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when the operation succeeded or failed.
|
||||
/// The argument is the operation that raised the event.
|
||||
///
|
||||
/// From IAsyncOperation
|
||||
/// </summary>
|
||||
public event Action<IAsyncOperation> Completed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
value(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CompletedCallback += value;
|
||||
}
|
||||
}
|
||||
remove => m_CompletedCallback -= value;
|
||||
}
|
||||
|
||||
protected void DidComplete()
|
||||
{
|
||||
m_CompletedCallback?.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary>Schedules the continuation action that's invoked when the instance completes.</summary>
|
||||
/// <param name="continuation">The action to invoke when the operation completes.</param>
|
||||
///
|
||||
/// From INotifyCompletion
|
||||
public virtual void OnCompleted(Action continuation)
|
||||
{
|
||||
Completed += op => continuation?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for asynchronous operations.
|
||||
///
|
||||
/// Implemented by: TaskAsyncOperation<T>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The type of this operation's result
|
||||
/// </typeparam>
|
||||
abstract class AsyncOperationBase<T> : CustomYieldInstruction, IAsyncOperation<T>, INotifyCompletion
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates if coroutine should be kept suspended.
|
||||
///
|
||||
/// From CustomYieldInstruction.
|
||||
/// </summary>
|
||||
public override bool keepWaiting => !IsCompleted;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this operation is completed.
|
||||
///
|
||||
/// Required to make the operation awaitable
|
||||
/// </summary>
|
||||
public abstract bool IsCompleted { get; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, this operation either succeeded, failed, or has been canceled.
|
||||
///
|
||||
/// From IAsyncOperation
|
||||
/// </summary>
|
||||
public bool IsDone => IsCompleted;
|
||||
|
||||
/// <summary>
|
||||
/// The current status of this operation.
|
||||
///
|
||||
/// From IAsyncOperation
|
||||
/// </summary>
|
||||
public abstract AsyncOperationStatus Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The exception that occured during the operation if it failed.
|
||||
///
|
||||
/// From IAsyncOperation
|
||||
/// </summary>
|
||||
public abstract Exception Exception { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Result of the operation.
|
||||
///
|
||||
/// Required to make the operation awaitable
|
||||
/// </summary>
|
||||
public abstract T Result { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Awaiter on the operation.
|
||||
///
|
||||
/// Required to make the operation awaitable
|
||||
/// </summary>
|
||||
public abstract T GetResult();
|
||||
|
||||
/// <summary>
|
||||
/// Awaiter on the operation.
|
||||
///
|
||||
/// Required to make the operation awaitable
|
||||
/// </summary>
|
||||
public abstract AsyncOperationBase<T> GetAwaiter();
|
||||
|
||||
Action<IAsyncOperation<T>> m_CompletedCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when the operation succeeded or failed.
|
||||
/// The argument is the operation that raised the event.
|
||||
///
|
||||
/// From IAsyncOperation
|
||||
/// </summary>
|
||||
public event Action<IAsyncOperation<T>> Completed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsDone)
|
||||
{
|
||||
value(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CompletedCallback += value;
|
||||
}
|
||||
}
|
||||
remove => m_CompletedCallback -= value;
|
||||
}
|
||||
|
||||
protected void DidComplete()
|
||||
{
|
||||
m_CompletedCallback?.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary>Schedules the continuation action that's invoked when the instance completes.</summary>
|
||||
/// <param name="continuation">The action to invoke when the operation completes.</param>
|
||||
///
|
||||
/// From INotifyCompletion
|
||||
public virtual void OnCompleted(Action continuation)
|
||||
{
|
||||
Completed += op => continuation?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: db331124c2ee348219007881f953471b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,147 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Set of utility functions added as extensions to
|
||||
/// <see cref="IAsyncOperation"/> and <see cref="IAsyncOperation{T}"/>.
|
||||
/// </summary>
|
||||
static class AsyncOperationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a default awaiter on <paramref name="self"/>.
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The operation to create an awaiter for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return a default awaiter for <paramref name="self"/>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// This is required so we can directly use the <see langword="await"/>
|
||||
/// keyword on an <see cref="IAsyncOperation"/>.
|
||||
/// </remarks>
|
||||
public static AsyncOperationAwaiter GetAwaiter(this IAsyncOperation self)
|
||||
{
|
||||
return new AsyncOperationAwaiter(self);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a Task based on <paramref name="self"/>.
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The operation to create a Task for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return a <see cref="T:System.Threading.Tasks.Task"/>.
|
||||
/// </returns>
|
||||
public static Task AsTask(this IAsyncOperation self)
|
||||
{
|
||||
if (self.Status == AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
|
||||
void CompleteTask(IAsyncOperation operation)
|
||||
{
|
||||
switch (operation.Status)
|
||||
{
|
||||
case AsyncOperationStatus.Failed:
|
||||
taskCompletionSource.TrySetException(operation.Exception);
|
||||
break;
|
||||
case AsyncOperationStatus.Cancelled:
|
||||
taskCompletionSource.TrySetCanceled();
|
||||
break;
|
||||
case AsyncOperationStatus.Succeeded:
|
||||
taskCompletionSource.TrySetResult(null);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
if (self.IsDone)
|
||||
{
|
||||
CompleteTask(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.Completed += CompleteTask;
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a default awaiter for <paramref name="self"/>.
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The operation to create an awaiter for.
|
||||
/// </param>
|
||||
/// <typeparam name="T">
|
||||
/// The result's type of <paramref name="self"/>.
|
||||
/// </typeparam>
|
||||
/// <returns>
|
||||
/// Return a default awaiter for <paramref name="self"/>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// This is required so we can directly use the <see langword="await"/>
|
||||
/// keyword on an <see cref="IAsyncOperation{T}"/>.
|
||||
/// </remarks>
|
||||
public static AsyncOperationAwaiter<T> GetAwaiter<T>(this IAsyncOperation<T> self)
|
||||
{
|
||||
return new AsyncOperationAwaiter<T>(self);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a Task based on <paramref name="self"/>.
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The operation to create a Task for.
|
||||
/// </param>
|
||||
/// <typeparam name="T">
|
||||
/// The result's type of <paramref name="self"/>.
|
||||
/// </typeparam>
|
||||
/// <returns>
|
||||
/// Return a <see cref="T:System.Threading.Tasks.Task`1"/>
|
||||
/// </returns>
|
||||
public static Task<T> AsTask<T>(this IAsyncOperation<T> self)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<T>();
|
||||
|
||||
void CompleteTask(IAsyncOperation<T> operation)
|
||||
{
|
||||
switch (operation.Status)
|
||||
{
|
||||
case AsyncOperationStatus.Succeeded:
|
||||
taskCompletionSource.TrySetResult(operation.Result);
|
||||
break;
|
||||
case AsyncOperationStatus.Failed:
|
||||
taskCompletionSource.TrySetException(operation.Exception);
|
||||
break;
|
||||
case AsyncOperationStatus.Cancelled:
|
||||
taskCompletionSource.TrySetCanceled();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
if (self.IsDone)
|
||||
{
|
||||
CompleteTask(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.Completed += CompleteTask;
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bd3488b91e5f84fb18390042c3ebc70b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,29 @@
|
|||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// All supported status of an <see cref="IAsyncOperation"/>.
|
||||
/// </summary>
|
||||
enum AsyncOperationStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The operation status hasn't been defined yet.
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// The operation is running.
|
||||
/// </summary>
|
||||
InProgress,
|
||||
/// <summary>
|
||||
/// The operation is completed without any errors.
|
||||
/// </summary>
|
||||
Succeeded,
|
||||
/// <summary>
|
||||
/// The operation is completed with errors.
|
||||
/// </summary>
|
||||
Failed,
|
||||
/// <summary>
|
||||
/// The operation has been canceled.
|
||||
/// </summary>
|
||||
Cancelled
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2d4f47b43625b43508b700e345be22c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Contract for an asynchronous operation with no result.
|
||||
/// </summary>
|
||||
interface IAsyncOperation : IEnumerator
|
||||
{
|
||||
/// <summary>
|
||||
/// If true, this operation either succeeded, failed, or has been canceled.
|
||||
/// </summary>
|
||||
bool IsDone { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The current status of this operation.
|
||||
/// </summary>
|
||||
AsyncOperationStatus Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when the operation succeeded or failed.
|
||||
/// The argument is the operation that raised the event.
|
||||
/// </summary>
|
||||
event Action<IAsyncOperation> Completed;
|
||||
|
||||
/// <summary>
|
||||
/// The exception that occured during the operation if it failed.
|
||||
/// </summary>
|
||||
Exception Exception { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contract for an asynchronous operation returning a result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The result's type of this operation.
|
||||
/// </typeparam>
|
||||
interface IAsyncOperation<out T> : IEnumerator
|
||||
{
|
||||
/// <inheritdoc cref="IAsyncOperation.IsDone"/>
|
||||
bool IsDone { get; }
|
||||
|
||||
/// <inheritdoc cref="IAsyncOperation.Status"/>
|
||||
AsyncOperationStatus Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when the operation succeeded or failed.
|
||||
/// The argument is the operation that raised the event.
|
||||
/// </summary>
|
||||
event Action<IAsyncOperation<T>> Completed;
|
||||
|
||||
/// <inheritdoc cref="IAsyncOperation.Exception"/>
|
||||
Exception Exception { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The result of this operation.
|
||||
/// </summary>
|
||||
T Result { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fac66275348d245d490b160bcf2413c3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,51 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Contract for objects allowing to use the <see langword="await"/> keyword on an <see cref="IAsyncOperation"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For more information, see <see href="https://github.com/dotnet/roslyn/blob/master/docs/features/task-types.md"/>
|
||||
/// </remarks>
|
||||
interface IAsyncOperationAwaiter : ICriticalNotifyCompletion
|
||||
{
|
||||
/// <inheritdoc cref="IAsyncOperation.IsDone"/>
|
||||
bool IsCompleted { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the operation's current result.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// * Does nothing on success but must be declared to match the awaiter pattern.
|
||||
/// * Is expected to throw if the operation failed or has been canceled.
|
||||
/// </remarks>
|
||||
void GetResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contract for objects allowing to use the <see langword="await"/> keyword on an <see cref="IAsyncOperation{T}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The result's type of the awaited operation.
|
||||
/// </typeparam>
|
||||
/// <remarks>
|
||||
/// For more information, see <see href="https://github.com/dotnet/roslyn/blob/master/docs/features/task-types.md"/>
|
||||
/// </remarks>
|
||||
interface IAsyncOperationAwaiter<out T> : ICriticalNotifyCompletion
|
||||
{
|
||||
/// <inheritdoc cref="IAsyncOperation.IsDone"/>
|
||||
bool IsCompleted { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the operation's current result.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Return the operation's current <see cref="IAsyncOperation{T}.Result"/>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Is expected to throw if the operation failed or has been canceled.
|
||||
/// </remarks>
|
||||
T GetResult();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c6da497a894c04c6d9b6a738042ec6a0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,223 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Task-based implementation of IAsyncOperation.
|
||||
///
|
||||
/// awaitable in tasks
|
||||
/// yieldable in coroutines
|
||||
/// </summary>
|
||||
class TaskAsyncOperation : AsyncOperationBase, INotifyCompletion
|
||||
{
|
||||
/// <remarks>
|
||||
/// The scheduler is also used by the <see cref="TaskAsyncOperation{T}"/> because
|
||||
/// <see cref="RuntimeInitializeOnLoadMethodAttribute"/> can't be used in generic objects.
|
||||
/// </remarks>
|
||||
internal static TaskScheduler Scheduler;
|
||||
|
||||
Task m_Task;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsCompleted => m_Task.IsCompleted;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override AsyncOperationStatus Status
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Task == null)
|
||||
{
|
||||
return AsyncOperationStatus.None;
|
||||
}
|
||||
|
||||
if (!m_Task.IsCompleted)
|
||||
{
|
||||
return AsyncOperationStatus.InProgress;
|
||||
}
|
||||
|
||||
if (m_Task.IsCanceled)
|
||||
{
|
||||
return AsyncOperationStatus.Cancelled;
|
||||
}
|
||||
|
||||
if (m_Task.IsFaulted)
|
||||
{
|
||||
return AsyncOperationStatus.Failed;
|
||||
}
|
||||
|
||||
return AsyncOperationStatus.Succeeded;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Exception Exception => m_Task?.Exception;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void GetResult() {}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override AsyncOperationBase GetAwaiter()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new TaskAsyncOperation from a provided Task.
|
||||
/// Returns on Unity's main thread context.
|
||||
/// </summary>
|
||||
/// <param name="task">
|
||||
/// The task tracked by this TaskAsyncOperation.
|
||||
/// </param>
|
||||
public TaskAsyncOperation(Task task)
|
||||
{
|
||||
// Tests don't run `RuntimeInitializeOnLoadMethod`s?
|
||||
if (Scheduler == null)
|
||||
{
|
||||
SetScheduler();
|
||||
}
|
||||
|
||||
m_Task = task;
|
||||
|
||||
task.ContinueWith((t, state) =>
|
||||
{
|
||||
var self = (TaskAsyncOperation)state;
|
||||
self.DidComplete();
|
||||
}, this, CancellationToken.None, TaskContinuationOptions.None, Scheduler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and starts a task from the provided Action executing on the C# thread pool.
|
||||
/// Returns on Unity's main thread context.
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// The Action to execute asynchronously.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A TaskAsyncOperation tracking the execution of the provided Action.
|
||||
/// </returns>
|
||||
public static TaskAsyncOperation Run(Action action)
|
||||
{
|
||||
var task = new Task(action);
|
||||
var ret = new TaskAsyncOperation(task);
|
||||
task.Start();
|
||||
return ret;
|
||||
}
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
internal static void SetScheduler()
|
||||
{
|
||||
Scheduler = TaskScheduler.FromCurrentSynchronizationContext();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Task-based implementation of IAsyncOperation<T>.
|
||||
///
|
||||
/// awaitable in tasks
|
||||
/// yieldable in coroutines
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The return type of the operation's result.
|
||||
/// </typeparam>
|
||||
class TaskAsyncOperation<T> : AsyncOperationBase<T>
|
||||
{
|
||||
Task<T> m_Task;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsCompleted => m_Task.IsCompleted;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override T Result => m_Task.Result;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override T GetResult()
|
||||
{
|
||||
return m_Task.GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override AsyncOperationBase<T> GetAwaiter()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override AsyncOperationStatus Status
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Task == null)
|
||||
{
|
||||
return AsyncOperationStatus.None;
|
||||
}
|
||||
|
||||
if (!m_Task.IsCompleted)
|
||||
{
|
||||
return AsyncOperationStatus.InProgress;
|
||||
}
|
||||
|
||||
if (m_Task.IsCanceled)
|
||||
{
|
||||
return AsyncOperationStatus.Cancelled;
|
||||
}
|
||||
|
||||
if (m_Task.IsFaulted)
|
||||
{
|
||||
return AsyncOperationStatus.Failed;
|
||||
}
|
||||
|
||||
return AsyncOperationStatus.Succeeded;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Exception Exception => m_Task?.Exception;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new TaskAsyncOperation from a provided Task.
|
||||
/// Returns on Unity's main thread context.
|
||||
/// </summary>
|
||||
/// <param name="task">
|
||||
/// The task tracked by this TaskAsyncOperation.
|
||||
/// </param>
|
||||
public TaskAsyncOperation(Task<T> task)
|
||||
{
|
||||
// Tests don't run `RuntimeInitializeOnLoadMethod`s?
|
||||
if (TaskAsyncOperation.Scheduler == null)
|
||||
{
|
||||
TaskAsyncOperation.SetScheduler();
|
||||
}
|
||||
|
||||
m_Task = task;
|
||||
|
||||
task.ContinueWith((t, state) =>
|
||||
{
|
||||
var self = (TaskAsyncOperation<T>)state;
|
||||
self.DidComplete();
|
||||
}, this, CancellationToken.None, TaskContinuationOptions.None, TaskAsyncOperation.Scheduler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and starts a task from the provided Action executing on the C# thread pool.
|
||||
/// Returns on Unity's main thread context.
|
||||
/// </summary>
|
||||
/// <param name="func">
|
||||
/// The Action to execute asynchronously.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A TaskAsyncOperation tracking the execution of the provided Action.
|
||||
/// </returns>
|
||||
public static TaskAsyncOperation<T> Run(Func<T> func)
|
||||
{
|
||||
var task = new Task<T>(func);
|
||||
var ret = new TaskAsyncOperation<T>(task);
|
||||
task.Start();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7829c22a2e7f648629af71b9abb67494
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 99614a857646842a086184db34d8fb84
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c8f15537a1ce54d2cb26811d0da5627a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
|||
using Unity.Services.Core.Internal;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEngine.Scripting;
|
||||
#endif
|
||||
|
||||
namespace Unity.Services.Authentication.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Contract for objects providing an access token to access remote services.
|
||||
/// </summary>
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
[RequireImplementors]
|
||||
#endif
|
||||
public interface IAccessToken : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The current token to use to access remote services.
|
||||
/// </summary>
|
||||
string AccessToken { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2946cf1ab319d45a9af9d5720e7cc5f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
|||
using Unity.Services.Core.Internal;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEngine.Scripting;
|
||||
#endif
|
||||
|
||||
namespace Unity.Services.Authentication.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Component providing the Environment Id
|
||||
/// </summary>
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
[RequireImplementors]
|
||||
#endif
|
||||
public interface IEnvironmentId : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the Environment ID when a sign in succeeds, otherwise null.
|
||||
/// </summary>
|
||||
string EnvironmentId { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ac86a2bfd37d6486e831ba1e932a6f66
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using Unity.Services.Core.Internal;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEngine.Scripting;
|
||||
#endif
|
||||
|
||||
namespace Unity.Services.Authentication.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Contract for objects providing information with the player identification (PlayerID) for currently signed in player.
|
||||
/// </summary>
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
[RequireImplementors]
|
||||
#endif
|
||||
public interface IPlayerId : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the player.
|
||||
/// </summary>
|
||||
string PlayerId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when the player id changed.
|
||||
/// </summary>
|
||||
event Action<string> PlayerIdChanged;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1c760120bcec444b49d3351b04d063c0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c7fcd0b25211b4456841ec71fd8a103c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
using Unity.Services.Core.Internal;
|
||||
|
||||
namespace Unity.Services.Core.Configuration.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Component to provide cloud project ID.
|
||||
/// </summary>
|
||||
public interface ICloudProjectId : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Get cloud project ID at runtime.
|
||||
/// </summary>
|
||||
/// <returns>cloud project id</returns>
|
||||
string GetCloudProjectId();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e6a900469855a4439a8cc405993bbe57
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using Unity.Services.Core.Internal;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEngine.Scripting;
|
||||
#endif
|
||||
|
||||
namespace Unity.Services.Core.Configuration.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Component to provide external user ID, provided by a third party provider
|
||||
/// </summary>
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
[RequireImplementors]
|
||||
#endif
|
||||
public interface IExternalUserId : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the external user id
|
||||
/// </summary>
|
||||
string UserId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when the external id changed.
|
||||
/// </summary>
|
||||
event Action<string> UserIdChanged;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bd53524449ca040b9910cc0e70379457
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,73 @@
|
|||
using Unity.Services.Core.Internal;
|
||||
|
||||
namespace Unity.Services.Core.Configuration.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Component for project configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For WebGL platform, the configuration is only accessable if the application is hosted behind https. Behind http you will get an error: `Insecure connection not allowed`.
|
||||
/// </remarks>
|
||||
public interface IProjectConfiguration : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the boolean value for the project config <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// The identifier of the project config to find.
|
||||
/// </param>
|
||||
/// <param name="defaultValue">
|
||||
/// The value returned if there is no match for the given <paramref name="key"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return the boolean value for the project config for the given <paramref name="key"/> if any;
|
||||
/// return <paramref name="defaultValue"/> otherwise.
|
||||
/// </returns>
|
||||
bool GetBool(string key, bool defaultValue = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get the integer value for the project config with the given <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// The identifier of the project config to find.
|
||||
/// </param>
|
||||
/// <param name="defaultValue">
|
||||
/// The value returned if there is no match for the given <paramref name="key"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return the integer value for the project config for the given <paramref name="key"/> if any;
|
||||
/// return <paramref name="defaultValue"/> otherwise.
|
||||
/// </returns>
|
||||
int GetInt(string key, int defaultValue = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get the float value for the project config with the given <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// The identifier of the project config to find.
|
||||
/// </param>
|
||||
/// <param name="defaultValue">
|
||||
/// The value returned if there is no match for the given <paramref name="key"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return the float value for the project config for the given <paramref name="key"/> if any;
|
||||
/// return <paramref name="defaultValue"/> otherwise.
|
||||
/// </returns>
|
||||
float GetFloat(string key, float defaultValue = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get the string value for the project config with the given <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// The identifier of the project config to find.
|
||||
/// </param>
|
||||
/// <param name="defaultValue">
|
||||
/// The value returned if there is no match for the given <paramref name="key"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return the string value for the project config for the given <paramref name="key"/> if any;
|
||||
/// return <paramref name="defaultValue"/> otherwise.
|
||||
/// </returns>
|
||||
string GetString(string key, string defaultValue = default);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 83e41efdede654a89b901da7b70ff0b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d7e60a737f3cb463e9a120fbe29854e8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
using Unity.Services.Core.Internal;
|
||||
|
||||
namespace Unity.Services.Core.Device.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Component providing a Unity Installation Identifier
|
||||
/// </summary>
|
||||
public interface IInstallationId : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns Unity Installation Identifier
|
||||
/// </summary>
|
||||
/// <returns>The Installation Identifier</returns>
|
||||
string GetOrCreateIdentifier();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2ce7a4ee920834a2eb1b48958047fbd4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: add07ed3db70146bea50b6a4f554e651
|
||||
timeCreated: 1620137169
|
|
@ -0,0 +1,15 @@
|
|||
using Unity.Services.Core.Internal;
|
||||
|
||||
namespace Unity.Services.Core.Environments.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Component providing the Unity Service Environment
|
||||
/// </summary>
|
||||
public interface IEnvironments : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the name of the currently used Unity Service Environment
|
||||
/// </summary>
|
||||
string Current { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9ba8832336df045fca38ac55a6b587f0
|
||||
timeCreated: 1620137216
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2cbeea08e009b4f1d8f8b2786d63ca25
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
|||
namespace Unity.Services.Core.Networking.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Contract for objects containing all settings to customize the behaviour of a HTTP request sending.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// More options will be added based on common needs.
|
||||
/// </remarks>
|
||||
struct HttpOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Delay, in seconds, after which the request will be considered a failure.
|
||||
/// </summary>
|
||||
public int RequestTimeoutInSeconds;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the number of redirects the request can follow without failing.
|
||||
/// </summary>
|
||||
public int RedirectLimit;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 68448537185dd4d6ba109ed748b184f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,206 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.Services.Core.Networking.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Contain all data of an HTTP request.
|
||||
/// </summary>
|
||||
class HttpRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// The HTTP method to use.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// Common values are: DELETE, GET, PATCH, POST, PUT ...
|
||||
/// </example>
|
||||
public string Method;
|
||||
|
||||
/// <summary>
|
||||
/// The targeted url.
|
||||
/// </summary>
|
||||
public string Url;
|
||||
|
||||
/// <summary>
|
||||
/// The headers additional information.
|
||||
/// </summary>
|
||||
public Dictionary<string, string> Headers;
|
||||
|
||||
/// <summary>
|
||||
/// The additional data of this request serialized into bytes.
|
||||
/// </summary>
|
||||
public byte[] Body;
|
||||
|
||||
/// <summary>
|
||||
/// Settings to customize this request's behaviour.
|
||||
/// </summary>
|
||||
public HttpOptions Options;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="HttpRequest"/> class.
|
||||
/// </summary>
|
||||
public HttpRequest() {}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="HttpRequest"/> class with the given parameters.
|
||||
/// </summary>
|
||||
/// <param name="method">
|
||||
/// The HTTP method to use.
|
||||
/// Valid methods are: DELETE, GET, PATCH, POST, PUT.
|
||||
/// </param>
|
||||
/// <param name="url">
|
||||
/// The target url of the created request.
|
||||
/// </param>
|
||||
/// <param name="headers">
|
||||
/// The headers to add to the request.
|
||||
/// </param>
|
||||
/// <param name="body">
|
||||
/// The request's data serialized into bytes.
|
||||
/// </param>
|
||||
public HttpRequest(string method, string url, Dictionary<string, string> headers, byte[] body)
|
||||
{
|
||||
Method = method;
|
||||
Url = url;
|
||||
Headers = headers;
|
||||
Body = body;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="method"/> to this request.
|
||||
/// </summary>
|
||||
/// <param name="method">
|
||||
/// The HTTP method to use.
|
||||
/// Valid methods are: DELETE, GET, PATCH, POST, PUT.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public HttpRequest SetMethod(string method)
|
||||
{
|
||||
Method = method;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="url"/> to this request.
|
||||
/// </summary>
|
||||
/// <param name="url">
|
||||
/// The target url of the created request.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public HttpRequest SetUrl(string url)
|
||||
{
|
||||
Url = url;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add or update a header to this request using the given
|
||||
/// <paramref name="key"/> and <paramref name="value"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// The header's key.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// The header's value.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public HttpRequest SetHeader(string key, string value)
|
||||
{
|
||||
if (Headers is null)
|
||||
{
|
||||
Headers = new Dictionary<string, string>(1);
|
||||
}
|
||||
|
||||
Headers[key] = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="headers"/> to this request.
|
||||
/// </summary>
|
||||
/// <param name="headers">
|
||||
/// The headers to add to the request.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public HttpRequest SetHeaders(Dictionary<string, string> headers)
|
||||
{
|
||||
Headers = headers;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="body"/> to this request.
|
||||
/// </summary>
|
||||
/// <param name="body">
|
||||
/// The request's data serialized into bytes.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public HttpRequest SetBody(byte[] body)
|
||||
{
|
||||
Body = body;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="options"/> to this request.
|
||||
/// </summary>
|
||||
/// <param name="options">
|
||||
/// The settings to customize the request's behaviour.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public HttpRequest SetOptions(HttpOptions options)
|
||||
{
|
||||
Options = options;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="redirectLimit"/> to this request.
|
||||
/// </summary>
|
||||
/// <param name="redirectLimit">
|
||||
/// The number of redirects this request can follow without failing.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public HttpRequest SetRedirectLimit(int redirectLimit)
|
||||
{
|
||||
Options.RedirectLimit = redirectLimit;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="timeout"/> to this request.
|
||||
/// </summary>
|
||||
/// <param name="timeout">
|
||||
/// The delay, in seconds, after which the request will
|
||||
/// be considered a failure if it didn't have a response.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public HttpRequest SetTimeOutInSeconds(int timeout)
|
||||
{
|
||||
Options.RequestTimeoutInSeconds = timeout;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dfc2b9b5d2fe14b188e5ac23c3580d9e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,134 @@
|
|||
namespace Unity.Services.Core.Networking.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility extensions on <see cref="HttpRequest"/>.
|
||||
/// </summary>
|
||||
static class HttpRequestExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Set this method to "GET".
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The request to update the method of.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public static HttpRequest AsGet(this HttpRequest self)
|
||||
{
|
||||
return self.SetMethod("GET");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this method to "POST".
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The request to update the method of.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public static HttpRequest AsPost(this HttpRequest self)
|
||||
{
|
||||
return self.SetMethod("POST");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this method to "PUT".
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The request to update the method of.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public static HttpRequest AsPut(this HttpRequest self)
|
||||
{
|
||||
return self.SetMethod("PUT");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this method to "DELETE".
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The request to update the method of.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public static HttpRequest AsDelete(this HttpRequest self)
|
||||
{
|
||||
return self.SetMethod("DELETE");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this method to "PATCH".
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The request to update the method of.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public static HttpRequest AsPatch(this HttpRequest self)
|
||||
{
|
||||
return self.SetMethod("PATCH");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this method to "HEAD".
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The request to update the method of.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public static HttpRequest AsHead(this HttpRequest self)
|
||||
{
|
||||
return self.SetMethod("HEAD");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this method to "CONNECT".
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The request to update the method of.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public static HttpRequest AsConnect(this HttpRequest self)
|
||||
{
|
||||
return self.SetMethod("CONNECT");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this method to "OPTIONS".
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The request to update the method of.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public static HttpRequest AsOptions(this HttpRequest self)
|
||||
{
|
||||
return self.SetMethod("OPTIONS");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this method to "TRACE".
|
||||
/// </summary>
|
||||
/// <param name="self">
|
||||
/// The request to update the method of.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this request.
|
||||
/// </returns>
|
||||
public static HttpRequest AsTrace(this HttpRequest self)
|
||||
{
|
||||
return self.SetMethod("TRACE");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9f6735934f1934f448e5884d3ca69780
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,193 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.Services.Core.Networking.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Contain all data from a server response to a <see cref="HttpRequest"/>.
|
||||
/// </summary>
|
||||
class HttpResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The request at the origin of this response.
|
||||
/// </summary>
|
||||
public ReadOnlyHttpRequest Request;
|
||||
|
||||
/// <summary>
|
||||
/// The headers additional information.
|
||||
/// </summary>
|
||||
public Dictionary<string, string> Headers;
|
||||
|
||||
/// <summary>
|
||||
/// The date sent by the server serialized into bytes.
|
||||
/// </summary>
|
||||
public byte[] Data;
|
||||
|
||||
/// <summary>
|
||||
/// The status code sent by the server.
|
||||
/// </summary>
|
||||
public long StatusCode;
|
||||
|
||||
/// <summary>
|
||||
/// The error message if an error occured.
|
||||
/// </summary>
|
||||
public string ErrorMessage;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the request failed due to an HTTP error.
|
||||
/// </summary>
|
||||
public bool IsHttpError;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the request failed due to a connectivity error.
|
||||
/// </summary>
|
||||
public bool IsNetworkError;
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="request"/> to this response.
|
||||
/// </summary>
|
||||
/// <param name="request">
|
||||
/// The request at the origin of this response.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this response.
|
||||
/// </returns>
|
||||
public HttpResponse SetRequest(HttpRequest request)
|
||||
{
|
||||
Request = new ReadOnlyHttpRequest(request);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="request"/> to this response.
|
||||
/// </summary>
|
||||
/// <param name="request">
|
||||
/// A handle to the request at the origin of this response.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this response.
|
||||
/// </returns>
|
||||
public HttpResponse SetRequest(ReadOnlyHttpRequest request)
|
||||
{
|
||||
Request = request;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add or update a header to this request using the given
|
||||
/// <paramref name="key"/> and <paramref name="value"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// The header's key.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// The header's value.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this response.
|
||||
/// </returns>
|
||||
public HttpResponse SetHeader(string key, string value)
|
||||
{
|
||||
Headers[key] = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="headers"/> to this response.
|
||||
/// </summary>
|
||||
/// <param name="headers">
|
||||
/// The headers to add to the request.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this response.
|
||||
/// </returns>
|
||||
public HttpResponse SetHeaders(Dictionary<string, string> headers)
|
||||
{
|
||||
Headers = headers;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="data"/> to this response.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// The response's data serialized into bytes.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this response.
|
||||
/// </returns>
|
||||
public HttpResponse SetData(byte[] data)
|
||||
{
|
||||
Data = data;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="statusCode"/> to this response.
|
||||
/// </summary>
|
||||
/// <param name="statusCode">
|
||||
/// The status code sent by the server.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this response.
|
||||
/// </returns>
|
||||
public HttpResponse SetStatusCode(long statusCode)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="errorMessage"/> to this response.
|
||||
/// </summary>
|
||||
/// <param name="errorMessage">
|
||||
/// The error message if an error occured during the <see cref="Request"/> processing.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this response.
|
||||
/// </returns>
|
||||
public HttpResponse SetErrorMessage(string errorMessage)
|
||||
{
|
||||
ErrorMessage = errorMessage;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="isHttpError"/> to this response.
|
||||
/// </summary>
|
||||
/// <param name="isHttpError">
|
||||
/// A flag to determine if this response failed due to an HTTP error.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this response.
|
||||
/// </returns>
|
||||
public HttpResponse SetIsHttpError(bool isHttpError)
|
||||
{
|
||||
IsHttpError = isHttpError;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the given <paramref name="isNetworkError"/> to this response.
|
||||
/// </summary>
|
||||
/// <param name="isNetworkError">
|
||||
/// A flag to determine if this response failed due to a connectivity error.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return this response.
|
||||
/// </returns>
|
||||
public HttpResponse SetIsNetworkError(bool isNetworkError)
|
||||
{
|
||||
IsNetworkError = isNetworkError;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f062e98fc9ade4f4faa8759ddbf79a98
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,65 @@
|
|||
using Unity.Services.Core.Internal;
|
||||
|
||||
namespace Unity.Services.Core.Networking.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Contract for objects able to send an HTTP request.
|
||||
/// </summary>
|
||||
interface IHttpClient : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the base URL to reach the service identified by the given <paramref name="serviceId"/>.
|
||||
/// </summary>
|
||||
/// <param name="serviceId">
|
||||
/// The ID of the remote service to get the base URL for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return the base URL for the service if it exists;
|
||||
/// throw otherwise.
|
||||
/// </returns>
|
||||
string GetBaseUrlFor(string serviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Get the default options for requests targeting the service
|
||||
/// identified by the given <paramref name="serviceId"/>.
|
||||
/// </summary>
|
||||
/// <param name="serviceId">
|
||||
/// The ID of the remote service to get default options for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return the default options for requests targeting the service if it exists;
|
||||
/// throw otherwise.
|
||||
/// </returns>
|
||||
HttpOptions GetDefaultOptionsFor(string serviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="HttpRequest"/> targeting the service
|
||||
/// identified by the given <paramref name="serviceId"/>.
|
||||
/// Also set its default options.
|
||||
/// </summary>
|
||||
/// <param name="serviceId">
|
||||
/// The ID of the remote service to create a request for.
|
||||
/// </param>
|
||||
/// <param name="resourcePath">
|
||||
/// The path to the resource to act on.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return the created <see cref="HttpRequest"/> if the service exists.
|
||||
/// </returns>
|
||||
HttpRequest CreateRequestForService(string serviceId, string resourcePath);
|
||||
|
||||
/// <summary>
|
||||
/// Send the given <paramref name="request"/>.
|
||||
/// Note: The success of the returned operation only means that the request could be handled
|
||||
/// gracefully; the request in itself can still fail (HTTP error or network error).
|
||||
/// </summary>
|
||||
/// <param name="request">
|
||||
/// The request to send.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return a handle to monitor the progression of the request.
|
||||
/// The operation's result will contain the server's response if the request was sent successfully.
|
||||
/// </returns>
|
||||
IAsyncOperation<ReadOnlyHttpResponse> Send(HttpRequest request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 03a13814984de4f0b88ec94c7f6f1b58
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,35 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.Services.Core.Networking.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Read-only handle to a <see cref="HttpRequest"/>.
|
||||
/// </summary>
|
||||
struct ReadOnlyHttpRequest
|
||||
{
|
||||
HttpRequest m_Request;
|
||||
|
||||
/// <summary>
|
||||
/// Create a read-only handle to the given <paramref name="request"/>.
|
||||
/// </summary>
|
||||
/// <param name="request">
|
||||
/// The request to create the read-only handle for.
|
||||
/// </param>
|
||||
public ReadOnlyHttpRequest(HttpRequest request)
|
||||
{
|
||||
m_Request = request;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="HttpRequest.Method"/>
|
||||
public string Method => m_Request.Method;
|
||||
|
||||
/// <inheritdoc cref="HttpRequest.Url"/>
|
||||
public string Url => m_Request.Url;
|
||||
|
||||
/// <inheritdoc cref="HttpRequest.Headers"/>
|
||||
public IReadOnlyDictionary<string, string> Headers => m_Request.Headers;
|
||||
|
||||
/// <inheritdoc cref="HttpRequest.Body"/>
|
||||
public byte[] Body => m_Request.Body;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: eafba3bdb53b34d70a61f2cf40a497ec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,47 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.Services.Core.Networking.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Read-only handle to a <see cref="HttpResponse"/>.
|
||||
/// </summary>
|
||||
struct ReadOnlyHttpResponse
|
||||
{
|
||||
HttpResponse m_Response;
|
||||
|
||||
/// <summary>
|
||||
/// Create a read-only handle to the given <paramref name="response"/>.
|
||||
/// </summary>
|
||||
/// <param name="response">
|
||||
/// The response to create the read-only handle for.
|
||||
/// </param>
|
||||
public ReadOnlyHttpResponse(HttpResponse response)
|
||||
{
|
||||
m_Response = response;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="HttpResponse.Request"/>
|
||||
public ReadOnlyHttpRequest Request => m_Response.Request;
|
||||
|
||||
/// <inheritdoc cref="HttpResponse.Headers"/>
|
||||
public IReadOnlyDictionary<string, string> Headers => m_Response.Headers;
|
||||
|
||||
/// <inheritdoc cref="HttpResponse.Data"/>
|
||||
public byte[] Data => m_Response.Data;
|
||||
|
||||
/// <inheritdoc cref="HttpResponse.StatusCode"/>
|
||||
public long StatusCode => m_Response.StatusCode;
|
||||
|
||||
/// <inheritdoc cref="HttpResponse.ErrorMessage"/>
|
||||
/// <remarks>
|
||||
/// Can be filled by the server for HTTP errors or by the local request manager for network errors.
|
||||
/// </remarks>
|
||||
public string ErrorMessage => m_Response.ErrorMessage;
|
||||
|
||||
/// <inheritdoc cref="HttpResponse.IsHttpError"/>
|
||||
public bool IsHttpError => m_Response.IsHttpError;
|
||||
|
||||
/// <inheritdoc cref="HttpResponse.IsNetworkError"/>
|
||||
public bool IsNetworkError => m_Response.IsNetworkError;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 57789d1bf989e4a6da9126326213f6ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 332ad2f567fa467f945149fb7fabb67e
|
||||
timeCreated: 1646947789
|
|
@ -0,0 +1,66 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Unity.Services.Core.Internal;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEngine.Scripting;
|
||||
#endif
|
||||
|
||||
namespace Unity.Services.Qos.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface that allows access to QoS measurements. For use by other Operate packages through the Core
|
||||
/// Services SDK.
|
||||
/// </summary>
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
[RequireImplementors]
|
||||
#endif
|
||||
public interface IQosResults : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets sorted QoS measurements the specified service and regions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// `GetSortedQosResultsAsync` doesn't consider the returned regions until applying the services and regions filters.
|
||||
///
|
||||
/// If you specify regions, it only includes those regions.
|
||||
/// </remarks>
|
||||
/// <param name="service">The service to query regions for QoS. `GetSortedQosResultsAsync` only uses measures
|
||||
/// regions configured for the specified service.</param>
|
||||
/// <param name="regions">The regions to query for QoS. If not null or empty, `GetSortedQosResultsAsync` only uses
|
||||
/// regions in the intersection of the specified service and the specified regions for measurements.</param>
|
||||
/// <returns>Returns the sorted list of QoS results, ordered from best to worst.</returns>
|
||||
Task<IList<QosResult>> GetSortedQosResultsAsync(string service, IList<string> regions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the results of QoS measurements for a given region.
|
||||
/// </summary>
|
||||
public struct QosResult
|
||||
{
|
||||
/// <summary>
|
||||
/// The identifier for the service's region used in this set of QoS measurements.
|
||||
/// </summary>
|
||||
/// <value>A string containing the region name.
|
||||
/// </value>
|
||||
public string Region;
|
||||
/// <summary>
|
||||
/// Average latency of QoS measurements to the region.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The latency is determined by measuring the time between sending a packet and receiving the response for that packet,
|
||||
/// then taking the average for all responses received. Only packets for which a response was received are
|
||||
/// considered in the calculation.
|
||||
/// </remarks>
|
||||
/// <value>A positive integer, in milliseconds.</value>
|
||||
public int AverageLatencyMs;
|
||||
/// <summary>
|
||||
/// Percentage of packet loss observed in QoS measurements to the region.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Packet loss is determined by counting the number of packets for which a response was received from the QoS server,
|
||||
/// then taking the percentage based on the total number of packets sent.
|
||||
/// </remarks>
|
||||
/// <value>A positive flow value. The range is 0.0f - 1.0f (0 - 100%).</value>
|
||||
public float PacketLossPercent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cec35b4f221f4ae69973858262c86db2
|
||||
timeCreated: 1646947810
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a38057f3b0350493ca2bf521021d2c83
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using Unity.Services.Core.Internal;
|
||||
|
||||
namespace Unity.Services.Core.Scheduler.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Unity Service Scheduler to schedule actions on main thread.
|
||||
/// </summary>
|
||||
public interface IActionScheduler : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Schedules the action to be invoked on the main thead, on the first frame that occurs after the given delay in seconds
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// Action to be scheduled.
|
||||
/// </param>
|
||||
/// <param name="delaySeconds">
|
||||
/// time in seconds to delay execute action
|
||||
/// </param>
|
||||
/// <returns>unique Id for the scheduled action</returns>
|
||||
long ScheduleAction(Action action, double delaySeconds = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Removes all instances of the given action from the queue
|
||||
/// </summary>
|
||||
/// <param name="actionId">
|
||||
/// unique Id for action to be canceled.
|
||||
/// </param>
|
||||
void CancelAction(long actionId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 39aaed770c8974f1094c0cfba7b3d277
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cdc4ee70299e74aba975054ebe4d3432
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,24 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.Services.Core.Telemetry.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Object used to send diagnostic events to the backend.
|
||||
/// </summary>
|
||||
public interface IDiagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// Send a diagnostic event to the telemetry service to report unexpected behaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// Name of the event.
|
||||
/// </param>
|
||||
/// <param name="message">
|
||||
/// An error message describing what error occured.
|
||||
/// </param>
|
||||
/// <param name="tags">
|
||||
/// Event tags.
|
||||
/// </param>
|
||||
void SendDiagnostic(string name, string message, IDictionary<string, string> tags = null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f8592c5cb0e11974cb7545a8a68a55ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using System.Threading.Tasks;
|
||||
using Unity.Services.Core.Internal;
|
||||
|
||||
namespace Unity.Services.Core.Telemetry.Internal
|
||||
{
|
||||
interface IDiagnosticsComponentProvider
|
||||
{
|
||||
Task<IDiagnosticsFactory> CreateDiagnosticsComponents();
|
||||
|
||||
Task<string> GetSerializedProjectConfigurationAsync();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3b67b1e8b8e4b40a8a8c9013b40c7efd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,28 @@
|
|||
using System.Collections.Generic;
|
||||
using Unity.Services.Core.Internal;
|
||||
|
||||
namespace Unity.Services.Core.Telemetry.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Component to get or create the proper <see cref="IDiagnostics"/> for a given package.
|
||||
/// </summary>
|
||||
public interface IDiagnosticsFactory : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// All tags shared among all diagnostics events generated by <see cref="IDiagnostics"/> created by this factory.
|
||||
/// </summary>
|
||||
IReadOnlyDictionary<string, string> CommonTags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="IDiagnostics"/> setup with common tags for the given <paramref name="packageName"/>.
|
||||
/// </summary>
|
||||
/// <param name="packageName">
|
||||
/// The name of the package that will use the created <see cref="IDiagnostics"/> to send diagnostic events.
|
||||
/// Example value: "com.unity.services.core"
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return a <see cref="IDiagnostics"/> setup with common tags for the given <paramref name="packageName"/>.
|
||||
/// </returns>
|
||||
IDiagnostics Create(string packageName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ef7fcc1a349fcfd4eb60ca422145e7d2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,52 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.Services.Core.Telemetry.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Object used to send metrics events to the backend.
|
||||
/// </summary>
|
||||
public interface IMetrics
|
||||
{
|
||||
/// <summary>
|
||||
/// Send a metric that can arbitrarily go up or down to the telemetry service.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// Name of the event.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// Value of the metric.
|
||||
/// </param>
|
||||
/// <param name="tags">
|
||||
/// Event tags.
|
||||
/// </param>
|
||||
void SendGaugeMetric(string name, double value = 0, IDictionary<string, string> tags = null);
|
||||
|
||||
/// <summary>
|
||||
/// Send a metric that lasts over time to the telemetry service.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// Name of the event.
|
||||
/// </param>
|
||||
/// <param name="time">
|
||||
/// Duration of the operation the event is tracking.
|
||||
/// </param>
|
||||
/// <param name="tags">
|
||||
/// Event tags.
|
||||
/// </param>
|
||||
void SendHistogramMetric(string name, double time, IDictionary<string, string> tags = null);
|
||||
|
||||
/// <summary>
|
||||
/// Send a metric that can only be incremented to the telemetry service.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// Name of the event.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// Value of the metric.
|
||||
/// </param>
|
||||
/// <param name="tags">
|
||||
/// Event tags.
|
||||
/// </param>
|
||||
void SendSumMetric(string name, double value = 1, IDictionary<string, string> tags = null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a1ee07fd37bf943e898438344b687120
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,28 @@
|
|||
using System.Collections.Generic;
|
||||
using Unity.Services.Core.Internal;
|
||||
|
||||
namespace Unity.Services.Core.Telemetry.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Component to get or create the proper <see cref="IMetrics"/> for a given package.
|
||||
/// </summary>
|
||||
public interface IMetricsFactory : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// All tags shared among all metrics events generated by <see cref="IMetrics"/> created by this factory.
|
||||
/// </summary>
|
||||
IReadOnlyDictionary<string, string> CommonTags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="IMetrics"/> setup with common tags for the given <paramref name="packageName"/>.
|
||||
/// </summary>
|
||||
/// <param name="packageName">
|
||||
/// The name of the package that will use the created <see cref="IMetrics"/> to send metric events.
|
||||
/// Example value: "com.unity.services.core"
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return a <see cref="IMetrics"/> setup with common tags for the given <paramref name="packageName"/>.
|
||||
/// </returns>
|
||||
IMetrics Create(string packageName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f637fc8d11c022942833496d32ff8f9b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 72cfb564f8b25174e87a90f7eb44ca04
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,136 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Unity.Services.Core.Internal;
|
||||
using NotNull = JetBrains.Annotations.NotNullAttribute;
|
||||
|
||||
namespace Unity.Services.Core.Threading.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// This component is an utility to simplify working with the Unity thread.
|
||||
/// </summary>
|
||||
public interface IUnityThreadUtils : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Check if the calling thread is the Unity thread.
|
||||
/// </summary>
|
||||
bool IsRunningOnUnityThread { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a task out of the given <paramref name="action"/> that will be invoked on the Unity thread.
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// The action to invoke on the Unity thread.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return the created task.
|
||||
/// </returns>
|
||||
Task PostAsync([NotNull] Action action);
|
||||
|
||||
/// <summary>
|
||||
/// Create a task out of the given <paramref name="action"/> that will be invoked on the Unity thread.
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// The action to invoke on the Unity thread.
|
||||
/// <paramref name="state"/> will be passed as its argument.
|
||||
/// </param>
|
||||
/// <param name="state">
|
||||
/// The captured state to pass to <paramref name="action"/> when invoking it.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Return the created task.
|
||||
/// </returns>
|
||||
Task PostAsync([NotNull] Action<object> action, object state);
|
||||
|
||||
/// <summary>
|
||||
/// Create a task out of the given <paramref name="action"/> that will be invoked on the Unity thread.
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// The action to invoke on the Unity thread.
|
||||
/// </param>
|
||||
/// <typeparam name="T">
|
||||
/// The type of the return of the invoked action.
|
||||
/// Can be any type.
|
||||
/// </typeparam>
|
||||
/// <returns>
|
||||
/// Return the created task.
|
||||
/// </returns>
|
||||
Task<T> PostAsync<T>([NotNull] Func<T> action);
|
||||
|
||||
/// <summary>
|
||||
/// Create a task out of the given <paramref name="action"/> that will be invoked on the Unity thread.
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// The action to invoke on the Unity thread.
|
||||
/// <paramref name="state"/> will be passed as its argument.
|
||||
/// </param>
|
||||
/// <param name="state">
|
||||
/// The captured state to pass to <paramref name="action"/> when invoking it.
|
||||
/// </param>
|
||||
/// <typeparam name="T">
|
||||
/// The type of the return of the invoked action.
|
||||
/// Can be any type.
|
||||
/// </typeparam>
|
||||
/// <returns>
|
||||
/// Return the created task.
|
||||
/// </returns>
|
||||
Task<T> PostAsync<T>([NotNull] Func<object, T> action, object state);
|
||||
|
||||
/// <summary>
|
||||
/// Execute the given <paramref name="action"/> on the Unity thread.
|
||||
/// Wait for the execution to finish before resuming this thread.
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// The action to invoke on the Unity thread.
|
||||
/// </param>
|
||||
void Send([NotNull] Action action);
|
||||
|
||||
/// <summary>
|
||||
/// Execute the given <paramref name="action"/> on the Unity thread.
|
||||
/// Wait for the execution to finish before resuming this thread.
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// The action to invoke on the Unity thread.
|
||||
/// <paramref name="state"/> will be passed as its argument.
|
||||
/// </param>
|
||||
/// <param name="state">
|
||||
/// The captured state to pass to <paramref name="action"/> when invoking it.
|
||||
/// </param>
|
||||
void Send([NotNull] Action<object> action, object state);
|
||||
|
||||
/// <summary>
|
||||
/// Execute the given <paramref name="action"/> on the Unity thread.
|
||||
/// Wait for the execution to finish before resuming this thread.
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// The action to invoke on the Unity thread.
|
||||
/// </param>
|
||||
/// <typeparam name="T">
|
||||
/// The type of the return of the invoked action.
|
||||
/// Can be any type.
|
||||
/// </typeparam>
|
||||
/// <returns>
|
||||
/// Return what the action returned.
|
||||
/// </returns>
|
||||
T Send<T>([NotNull] Func<T> action);
|
||||
|
||||
/// <summary>
|
||||
/// Execute the given <paramref name="action"/> on the Unity thread.
|
||||
/// Wait for the execution to finish before resuming this thread.
|
||||
/// </summary>
|
||||
/// <param name="action">
|
||||
/// The action to invoke on the Unity thread.
|
||||
/// <paramref name="state"/> will be passed as its argument.
|
||||
/// </param>
|
||||
/// <param name="state">
|
||||
/// The captured state to pass to <paramref name="action"/> when invoking it.
|
||||
/// </param>
|
||||
/// <typeparam name="T">
|
||||
/// The type of the return of the invoked action.
|
||||
/// Can be any type.
|
||||
/// </typeparam>
|
||||
/// <returns>
|
||||
/// Return what the action returned.
|
||||
/// </returns>
|
||||
T Send<T>([NotNull] Func<object, T> action, object state);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6348586e6343e6e4a824e3cd597f091e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 36565a93e739cba4d8afed38abe79811
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,26 @@
|
|||
using Unity.Services.Core.Internal;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEngine.Scripting;
|
||||
#endif
|
||||
|
||||
namespace Unity.Services.Vivox.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides utilities for performing simple Vivox actions or overriding
|
||||
/// the <see cref="IVivoxTokenProviderInternal"/> with a custom implementation.
|
||||
/// </summary>
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
[RequireImplementors]
|
||||
#endif
|
||||
public interface IVivox : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers an <see cref="IVivoxTokenProviderInternal"/> that will be used as the primary
|
||||
/// token generator for all Vivox actions.
|
||||
/// </summary>
|
||||
/// <param name="tokenProvider">
|
||||
/// Token provider to register.
|
||||
/// </param>
|
||||
void RegisterTokenProvider(IVivoxTokenProviderInternal tokenProvider);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d30387cc0bff00b45b7e52fc7d794046
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Unity.Services.Vivox.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Must be implemented by the <see cref="IVivox.RegisterTokenProvider(IVivoxTokenProviderInternal)"/> caller.
|
||||
/// This object's responsibility is to provide an overridable implementation that will generate
|
||||
/// tokens for Vivox actions.
|
||||
/// </summary>
|
||||
public interface IVivoxTokenProviderInternal
|
||||
{
|
||||
/// <summary>
|
||||
/// This async method should implement the necessary steps to providing a valid Vivox token.
|
||||
/// After registration, this method will automatically be called whenever a token needs to
|
||||
/// be generated for a particular action. (e.g. login, channel join, mute).
|
||||
/// This token generation method will not be used if a developer provides their own
|
||||
/// IVivoxTokenProvider implementation to the Vivox service.
|
||||
/// If the requested action is a login to the Vivox service we will use the UAS token for
|
||||
/// that instead of this method as well.
|
||||
/// </summary>
|
||||
/// <param name="issuer">
|
||||
/// Id of a title.
|
||||
/// Provided as part of the credentials delivered upon creating a project in the Unity Dashboard
|
||||
/// and enabling Vivox.
|
||||
/// </param>
|
||||
/// <param name="expiration">
|
||||
/// When the token should expire.
|
||||
/// </param>
|
||||
/// <param name="userUri">
|
||||
/// Id of the target for actions such as muting and blocking.
|
||||
/// </param>
|
||||
/// <param name="action">
|
||||
/// The action for which a token is requested.
|
||||
/// e.g.: "login", "join", ...
|
||||
/// </param>
|
||||
/// <param name="conferenceUri">
|
||||
/// Id if the conference requesting the token.
|
||||
/// </param>
|
||||
/// <param name="fromUserUri">
|
||||
/// Id of the user requesting the token.
|
||||
/// </param>
|
||||
/// <param name="realm">
|
||||
/// Domain for which the token should be created.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A Vivox token string.
|
||||
/// </returns>
|
||||
Task<string> GetTokenAsync(string issuer = null, TimeSpan? expiration = null, string userUri = null,
|
||||
string action = null, string conferenceUri = null, string fromUserUri = null, string realm = null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 230ff0327fa25a64a84bbf9e7cf97c8b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b9bc5cd0bdb9d4676878ddd8f116adfa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
|||
namespace Unity.Services.Wire.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// This structure represents the necessary data to perform a Wire subscription to an <see cref="IChannel"/>
|
||||
/// </summary>
|
||||
public struct ChannelToken
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a string identifying a Channel on which a service publishes messages.
|
||||
/// </summary>
|
||||
public string ChannelName;
|
||||
/// <summary>
|
||||
/// This is an authorization token emitted by the service who owns the Channel for this specific UAS Id.
|
||||
/// </summary>
|
||||
public string Token;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5a367299638e0496c93ea5472d17e202
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Unity.Services.Wire.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Channel object. Use <see cref="IWire.CreateChannel(IChannelTokenProvider)"/>
|
||||
/// to construct one. This object allows the subscription to a channel.
|
||||
/// </summary>
|
||||
public interface IChannel : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Handler called each time the channel receives a message.
|
||||
/// </summary>
|
||||
event Action<string> MessageReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Handler called each time the channel receives a binary message.
|
||||
/// </summary>
|
||||
event Action<byte[]> BinaryMessageReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Handler called if the subscription gets terminated by the Wire server.
|
||||
/// </summary>
|
||||
event Action KickReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Handler called whenever the subscription reliability changes.
|
||||
/// </summary>
|
||||
event Action<SubscriptionState> NewStateReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Handler called whenever the subscription encounters an error.
|
||||
/// A description of the error is passed as an argument.
|
||||
/// </summary>
|
||||
event Action<string> ErrorReceived;
|
||||
|
||||
/// <summary>
|
||||
/// SubscribeAsync will subscribe to the channel.
|
||||
/// Possible error codes are:
|
||||
/// * 23002 -> "CommandFailed"
|
||||
/// * 23003 -> "ConnectionFailed"
|
||||
/// * 23004 -> "InvalidToken"
|
||||
/// * 23005 -> "InvalidChannelName"
|
||||
/// * 23006 -> "TokenRetrieverFailed"
|
||||
/// * 23007 -> "Unauthorized"
|
||||
/// * 23008 -> "AlreadySubscribed"
|
||||
/// </summary>
|
||||
/// <returns>An awaitable task.</returns>
|
||||
/// <exception cref="RequestFailedException"/>
|
||||
Task SubscribeAsync();
|
||||
|
||||
/// <summary>
|
||||
/// UnsubscribeAsync will stop the subscription, effective immediately.
|
||||
/// Possible error codes are:
|
||||
/// * 23002 -> "CommandFailed"
|
||||
/// * 23009 -> "AlreadyUnsubscribed"
|
||||
/// </summary>
|
||||
/// <returns>An awaitable task.</returns>
|
||||
/// <exception cref="RequestFailedException"/>
|
||||
Task UnsubscribeAsync();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: db9e13e6a104a4b3a943cdd2e3ef4851
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,19 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace Unity.Services.Wire.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Must be implemented by the <see cref="IWire.CreateChannel(IChannelTokenProvider)"/> caller.
|
||||
/// This object responsibility is to provide an async method that returns a <see cref="ChannelToken"/> structure.
|
||||
/// </summary>
|
||||
public interface IChannelTokenProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// This async method should implement whetever network transaction necessary to retrieve a token enabling a Wire subscription.
|
||||
/// This function can be called by the Wire SDK multiple times during the lifetime of the subscription.
|
||||
/// For example, whenever the token needs to be refreshed.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="ChannelToken"/> structure to be used at subscription time.</returns>
|
||||
Task<ChannelToken> GetTokenAsync();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cb20682ba56fb47f285cd16dd1291270
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using Unity.Services.Core.Internal;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEngine.Scripting;
|
||||
#endif
|
||||
|
||||
namespace Unity.Services.Wire.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// IWire allows the creation of disposable <see cref="IChannel"/> objects.
|
||||
/// </summary>
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
[RequireImplementors]
|
||||
#endif
|
||||
public interface IWire : IServiceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// CreateChannel is a <see cref="IChannel"/> factory. It will generate an object enabling the subscription to a Wire channel.
|
||||
/// </summary>
|
||||
/// <param name="tokenProvider">Will be used to obtain a subscription token whenever the user calls <see cref="IChannel.SubscribeAsync"/>
|
||||
/// or Wire might choose to use it whenever a refreshed token is needed. Make sure that this <see cref="IChannelTokenProvider"/> can never provide
|
||||
/// an outdated or bad token.</param>
|
||||
/// <returns>A <see cref="IChannel"/> object.</returns>
|
||||
IChannel CreateChannel(IChannelTokenProvider tokenProvider);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5c918066646404a9cb09f3f5b6b20f35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.Services.Wire.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// The subscription current state.
|
||||
/// </summary>
|
||||
public enum SubscriptionState
|
||||
{
|
||||
/// <summary>
|
||||
/// The subscription is inactive.
|
||||
/// </summary>
|
||||
Unsubscribed,
|
||||
/// <summary>
|
||||
/// The subscription is active and synchronized to the server. You can trust that the last message received
|
||||
/// from the subscription is up to date.
|
||||
/// </summary>
|
||||
Synced,
|
||||
/// <summary>
|
||||
/// A connectivity issue prevents Wire from receiving update on this active subscription. As soon as Wire
|
||||
/// has reconnected, the subscription will receive the missing messages.
|
||||
/// </summary>
|
||||
Unsynced,
|
||||
/// <summary>
|
||||
/// The subscription encountered an error and is not active.
|
||||
/// </summary>
|
||||
Error,
|
||||
/// <summary>
|
||||
/// Wire is getting a token then sending a request to Wire to subscribe to a channel.
|
||||
/// </summary>
|
||||
Subscribing,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4dc74701c67cd41a18b37fe1a4e42b71
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a33cebe73913d4ddf9970fdbf0965bc5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
static class CoreLogger
|
||||
{
|
||||
internal const string Tag = "[ServicesCore]";
|
||||
internal const string VerboseLoggingDefine = "ENABLE_UNITY_SERVICES_CORE_VERBOSE_LOGGING";
|
||||
const string k_TelemetryLoggingDefine = "ENABLE_UNITY_SERVICES_CORE_TELEMETRY_LOGGING";
|
||||
|
||||
public static void Log(object message) => Debug.unityLogger.Log(Tag, message);
|
||||
public static void LogWarning(object message) => Debug.unityLogger.LogWarning(Tag, message);
|
||||
public static void LogError(object message) => Debug.unityLogger.LogError(Tag, message);
|
||||
|
||||
public static void LogException(Exception exception) =>
|
||||
Debug.unityLogger.Log(LogType.Exception, Tag, exception);
|
||||
|
||||
[Conditional("UNITY_ASSERTIONS")]
|
||||
public static void LogAssertion(object message) => Debug.unityLogger.Log(LogType.Assert, Tag, message);
|
||||
|
||||
#if !ENABLE_UNITY_SERVICES_VERBOSE_LOGGING
|
||||
[Conditional(VerboseLoggingDefine)]
|
||||
#endif
|
||||
public static void LogVerbose(object message) => Debug.unityLogger.Log(Tag, message);
|
||||
|
||||
#if !ENABLE_UNITY_SERVICES_TELEMETRY_LOGGING
|
||||
[Conditional(k_TelemetryLoggingDefine)]
|
||||
#endif
|
||||
public static void LogTelemetry(object message) => Debug.unityLogger.Log(Tag, message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 64d1febe16e70491e9b6b08c14aad487
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0b86b5b95a96c4ed5bf7167992f203ef
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,23 @@
|
|||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception to use two registered <see cref="IInitializablePackage"/> depend on the other.
|
||||
/// </summary>
|
||||
public class CircularDependencyException : ServicesInitializationException
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="ServicesInitializationException" /> class.
|
||||
/// </summary>
|
||||
public CircularDependencyException() {}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="ServicesInitializationException" />
|
||||
/// class with a specified error message.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// The error message that explains the reason for the exception.
|
||||
/// </param>
|
||||
public CircularDependencyException(string message)
|
||||
: base(message) {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ae7633dffe64d4dbd8d058a0e330bdad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cb40388a6db89d3429128f7a969e3960
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NotNull = JetBrains.Annotations.NotNullAttribute;
|
||||
|
||||
namespace Unity.Services.Core.Internal
|
||||
{
|
||||
class ComponentRegistry : IComponentRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// Key: Hash code of a <see cref="IServiceComponent"/> type.
|
||||
/// Value: Component instance.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
internal Dictionary<int, IServiceComponent> ComponentTypeHashToInstance { get; }
|
||||
|
||||
public ComponentRegistry(
|
||||
[NotNull] Dictionary<int, IServiceComponent> componentTypeHashToInstance)
|
||||
{
|
||||
ComponentTypeHashToInstance = componentTypeHashToInstance;
|
||||
}
|
||||
|
||||
public void RegisterServiceComponent<TComponent>(TComponent component)
|
||||
where TComponent : IServiceComponent
|
||||
{
|
||||
var componentType = typeof(TComponent);
|
||||
|
||||
// This check is to avoid passing the component without specifying the interface type as a generic argument.
|
||||
if (component.GetType() == componentType)
|
||||
{
|
||||
throw new ArgumentException("Interface type of component not specified.");
|
||||
}
|
||||
|
||||
var componentTypeHash = componentType.GetHashCode();
|
||||
if (IsComponentTypeRegistered(componentTypeHash))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"A component with the type {componentType.FullName} has already been registered.");
|
||||
}
|
||||
|
||||
ComponentTypeHashToInstance[componentTypeHash] = component;
|
||||
}
|
||||
|
||||
public TComponent GetServiceComponent<TComponent>()
|
||||
where TComponent : IServiceComponent
|
||||
{
|
||||
var componentType = typeof(TComponent);
|
||||
if (!ComponentTypeHashToInstance.TryGetValue(componentType.GetHashCode(), out var component)
|
||||
|| component is MissingComponent)
|
||||
|
||||
{
|
||||
throw new KeyNotFoundException($"There is no component `{componentType.Name}` registered. " +
|
||||
"Are you missing a package?");
|
||||
}
|
||||
|
||||
return (TComponent)component;
|
||||
}
|
||||
|
||||
bool IsComponentTypeRegistered(int componentTypeHash)
|
||||
{
|
||||
return ComponentTypeHashToInstance.TryGetValue(componentTypeHash, out var storedComponent)
|
||||
&& !(storedComponent is null)
|
||||
&& !(storedComponent is MissingComponent);
|
||||
}
|
||||
|
||||
public void ResetProvidedComponents(IDictionary<int, IServiceComponent> componentTypeHashToInstance)
|
||||
{
|
||||
ComponentTypeHashToInstance.Clear();
|
||||
ComponentTypeHashToInstance.MergeAllowOverride(componentTypeHashToInstance);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 249ac81b0a95a25449448c6ac698e501
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue