using System.Threading;
using System.Threading.Tasks;
using Dalamud.Interface.Internal.Windows.Data.Widgets;
namespace Dalamud.Plugin.Services;
///
/// This class represents the Framework of the native game client and grants access to various subsystems.
///
///
/// Choosing between RunOnFrameworkThread and Run
///
/// - If you do need to do use await and have your task keep executing on the main thread after waiting is
/// done, use Run.
/// - If you need to call or , use
/// RunOnFrameworkThread. It also skips the task scheduler if invoked already from the framework thread.
///
/// The game is likely to completely lock up if you call above synchronous function and getter, because starting
/// a new task by default runs on , which would make the task run on the framework
/// thread if invoked via Run. This includes Task.Factory.StartNew and
/// Task.ContinueWith. Use Task.Run if you need to start a new task from the callback specified to
/// Run, as it will force your task to be run in the default thread pool.
/// See to see the difference in behaviors, and how would a misuse of these
/// functions result in a deadlock.
///
public interface IFramework
{
///
/// A delegate type used with the event.
///
/// The Framework instance.
public delegate void OnUpdateDelegate(IFramework framework);
///
/// Event that gets fired every time the game framework updates.
///
public event OnUpdateDelegate Update;
///
/// Gets the last time that the Framework Update event was triggered.
///
public DateTime LastUpdate { get; }
///
/// Gets the last time in UTC that the Framework Update event was triggered.
///
public DateTime LastUpdateUTC { get; }
///
/// Gets the delta between the last Framework Update and the currently executing one.
///
public TimeSpan UpdateDelta { get; }
///
/// Gets a value indicating whether currently executing code is running in the game's framework update thread.
///
public bool IsInFrameworkUpdateThread { get; }
///
/// Gets a value indicating whether game Framework is unloading.
///
public bool IsFrameworkUnloading { get; }
/// Gets a that runs tasks during Framework Update event.
/// The task factory.
public TaskFactory GetTaskFactory();
///
/// Returns a task that completes after the given number of ticks.
///
/// Number of ticks to delay.
/// The cancellation token.
/// A new that gets resolved after specified number of ticks happen.
/// The continuation will run on the framework thread by default.
public Task DelayTicks(long numTicks, CancellationToken cancellationToken = default);
///
/// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call.
///
/// Function to call.
/// The cancellation token.
/// Task representing the pending or already completed function.
///
/// Starting new tasks and waiting on them synchronously from this callback will completely lock up
/// the game. Use await if you need to wait on something from an async callback.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task Run(Action action, CancellationToken cancellationToken = default);
///
/// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call.
///
/// Return type.
/// Function to call.
/// The cancellation token.
/// Task representing the pending or already completed function.
///
/// Starting new tasks and waiting on them synchronously from this callback will completely lock up
/// the game. Use await if you need to wait on something from an async callback.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task Run(Func action, CancellationToken cancellationToken = default);
///
/// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call.
///
/// Function to call.
/// The cancellation token.
/// Task representing the pending or already completed function.
///
/// Starting new tasks and waiting on them synchronously from this callback will completely lock up
/// the game. Use await if you need to wait on something from an async callback.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task Run(Func action, CancellationToken cancellationToken = default);
///
/// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call.
///
/// Return type.
/// Function to call.
/// The cancellation token.
/// Task representing the pending or already completed function.
///
/// Starting new tasks and waiting on them synchronously from this callback will completely lock up
/// the game. Use await if you need to wait on something from an async callback.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task Run(Func> action, CancellationToken cancellationToken = default);
///
/// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call.
///
/// Return type.
/// Function to call.
/// Task representing the pending or already completed function.
///
/// await, Task.Factory.StartNew or alike will continue off the framework thread.
/// Awaiting on the returned from RunOnFrameworkThread,
/// Run, or RunOnTick right away inside the callback specified to this
/// function has a chance of locking up the game. Do not do await framework.RunOnFrameworkThread(...);
/// directly or indirectly from the delegate passed to this function.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task RunOnFrameworkThread(Func func);
///
/// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call.
///
/// Function to call.
/// Task representing the pending or already completed function.
///
/// await, Task.Factory.StartNew or alike will continue off the framework thread.
/// Awaiting on the returned from RunOnFrameworkThread,
/// Run, or RunOnTick right away inside the callback specified to this
/// function has a chance of locking up the game. Do not do await framework.RunOnFrameworkThread(...);
/// directly or indirectly from the delegate passed to this function.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task RunOnFrameworkThread(Action action);
///
/// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call.
///
/// Return type.
/// Function to call.
/// Task representing the pending or already completed function.
///
/// await, Task.Factory.StartNew or alike will continue off the framework thread.
/// Awaiting on the returned from RunOnFrameworkThread,
/// Run, or RunOnTick right away inside the callback specified to this
/// function has a chance of locking up the game. Do not do await framework.RunOnFrameworkThread(...);
/// directly or indirectly from the delegate passed to this function.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
[Obsolete($"Use {nameof(RunOnTick)} instead.")]
public Task RunOnFrameworkThread(Func> func);
///
/// Run given function right away if this function has been called from game's Framework.Update thread, or otherwise run on next Framework.Update call.
///
/// Function to call.
/// Task representing the pending or already completed function.
///
/// await, Task.Factory.StartNew or alike will continue off the framework thread.
/// Awaiting on the returned from RunOnFrameworkThread,
/// Run, or RunOnTick right away inside the callback specified to this
/// function has a chance of locking up the game. Do not do await framework.RunOnFrameworkThread(...);
/// directly or indirectly from the delegate passed to this function.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
[Obsolete($"Use {nameof(RunOnTick)} instead.")]
public Task RunOnFrameworkThread(Func func);
///
/// Run given function in upcoming Framework.Tick call.
///
/// Return type.
/// Function to call.
/// Wait for given timespan before calling this function.
/// Count given number of Framework.Tick calls before calling this function. This takes precedence over delay parameter.
/// Cancellation token which will prevent the execution of this function if wait conditions are not met.
/// Task representing the pending function.
///
/// await, Task.Factory.StartNew or alike will continue off the framework thread.
/// Awaiting on the returned from RunOnFrameworkThread,
/// Run, or RunOnTick right away inside the callback specified to this
/// function has a chance of locking up the game. Do not do await framework.RunOnFrameworkThread(...);
/// directly or indirectly from the delegate passed to this function.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task RunOnTick(Func func, TimeSpan delay = default, int delayTicks = default, CancellationToken cancellationToken = default);
///
/// Run given function in upcoming Framework.Tick call.
///
/// Function to call.
/// Wait for given timespan before calling this function.
/// Count given number of Framework.Tick calls before calling this function. This takes precedence over delay parameter.
/// Cancellation token which will prevent the execution of this function if wait conditions are not met.
/// Task representing the pending function.
///
/// await, Task.Factory.StartNew or alike will continue off the framework thread.
/// Awaiting on the returned from RunOnFrameworkThread,
/// Run, or RunOnTick right away inside the callback specified to this
/// function has a chance of locking up the game. Do not do await framework.RunOnFrameworkThread(...);
/// directly or indirectly from the delegate passed to this function.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task RunOnTick(Action action, TimeSpan delay = default, int delayTicks = default, CancellationToken cancellationToken = default);
///
/// Run given function in upcoming Framework.Tick call.
///
/// Return type.
/// Function to call.
/// Wait for given timespan before calling this function.
/// Count given number of Framework.Tick calls before calling this function. This takes precedence over delay parameter.
/// Cancellation token which will prevent the execution of this function if wait conditions are not met.
/// Task representing the pending function.
///
/// await, Task.Factory.StartNew or alike will continue off the framework thread.
/// Awaiting on the returned from RunOnFrameworkThread,
/// Run, or RunOnTick right away inside the callback specified to this
/// function has a chance of locking up the game. Do not do await framework.RunOnFrameworkThread(...);
/// directly or indirectly from the delegate passed to this function.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task RunOnTick(Func> func, TimeSpan delay = default, int delayTicks = default, CancellationToken cancellationToken = default);
///
/// Run given function in upcoming Framework.Tick call.
///
/// Function to call.
/// Wait for given timespan before calling this function.
/// Count given number of Framework.Tick calls before calling this function. This takes precedence over delay parameter.
/// Cancellation token which will prevent the execution of this function if wait conditions are not met.
/// Task representing the pending function.
///
/// await, Task.Factory.StartNew or alike will continue off the framework thread.
/// Awaiting on the returned from RunOnFrameworkThread,
/// Run, or RunOnTick right away inside the callback specified to this
/// function has a chance of locking up the game. Do not do await framework.RunOnFrameworkThread(...);
/// directly or indirectly from the delegate passed to this function.
/// See the remarks on if you need to choose which one to use, between
/// Run and RunOnFrameworkThread. Note that RunOnTick is a fancy
/// version of RunOnFrameworkThread.
///
public Task RunOnTick(Func func, TimeSpan delay = default, int delayTicks = default, CancellationToken cancellationToken = default);
}