/// <summary> /// Adds a micro thread function to the <paramref name="scriptSystem"/> that executes after waiting specified delay. /// </summary> /// <param name="scriptSystem">The <see cref="ScriptSystem"/>.</param> /// <param name="action">The micro thread function to execute.</param> /// <param name="delay">The amount of time to wait for.</param> /// <param name="priority">The priority of the micro thread action being added.</param> /// <returns>The <see cref="MicroThread"/>.</returns> /// <exception cref="ArgumentNullException"> If <paramref name="scriptSystem"/> or <paramref name="action"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="delay"/> is less than zero.</exception> /// <remarks> /// If the <paramref name="action"/> is a <see cref="ScriptComponent"/> instance method the micro thread will be automatically stopped if the <see cref="ScriptComponent"/> or <see cref="Entity"/> is removed. /// </remarks> public static MicroThread AddTask( this ScriptSystem scriptSystem, Func <Task> action, TimeSpan delay, long priority = 0L) { if (scriptSystem == null) { throw new ArgumentNullException(nameof(scriptSystem)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } return(scriptSystem.AddTask(DoTask, priority)); //C# 7 Local function could also use a variable Func<Task> DoEvent = async () => { ... }; async Task DoTask() { var scriptDelegateWatcher = new ScriptDelegateWatcher(action); await scriptSystem.WaitFor(delay, scriptDelegateWatcher); if (scriptSystem.Game.IsRunning && scriptDelegateWatcher.IsActive) { await action(); } } }