/// <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(); } } }
/// <inheritdoc /> public override void Update(GameTime gameTime) { // This system should load from settings before becoming functional if (!Enabled) { return; } if (currentSceneInstance != sceneSystem?.SceneInstance) { // ReSharper disable once PossibleNullReferenceException UpdateScene(sceneSystem.SceneInstance); } if (pendingRebuild && currentSceneInstance != null) { scriptSystem.AddTask(async() => { // TODO EntityProcessors // Currently have to wait a frame for transformations to update // for example when calling Rebuild from the event that a component was added to the scene, this component will not be in the correct location yet // since the TransformProcessor runs the next frame await scriptSystem.NextFrame(); await Rebuild(); }); pendingRebuild = false; } }
public static MicroThread AddOnEventTask <T>( this ScriptSystem scriptSystem, EventReceiver <T> receiver, Func <T, Task> action, long priority = 0L) { if (scriptSystem == null) { throw new ArgumentNullException(nameof(scriptSystem)); } if (receiver == null) { throw new ArgumentNullException(nameof(receiver)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } return(scriptSystem.AddTask(DoEvent, priority)); //C# 7 Local function could also use a variable Func<Task> DoEvent = async () => { ... }; async Task DoEvent() { while (scriptSystem.Game.IsRunning) { await action(await receiver.ReceiveAsync()); } } }
public static MicroThread AddAction( this ScriptSystem scriptSystem, Action action, TimeSpan delay, long priority = 0L) { if (scriptSystem == null) { throw new ArgumentNullException(nameof(scriptSystem)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } if (delay <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(delay), "Must be greater than zero."); } return(scriptSystem.AddTask(DoTask, priority)); //C# 7 Local function could also use a variable Func<Task> DoEvent = async () => { ... }; async Task DoTask() { while (scriptSystem.Game.IsRunning && delay >= TimeSpan.Zero) { delay -= scriptSystem.Game.UpdateTime.Elapsed; await scriptSystem.NextFrame(); } action(); } }
public void Start(ScriptSystem script, string initialStateName) { exited = false; scriptSystem = script; scriptSystem.AddTask(Run); nextState = states[initialStateName]; }
public override void Update(GameTime time) { foreach (var kvp in ComponentDatas) { var component = kvp.Key; if (!component.CanExecute) { continue; } if (component.State == CharacterAttackComponent.AttackState.Primary) { if (component.PrimaryHandler != null) { scriptSystem.AddTask(async() => await component.PrimaryHandler.ExecuteAttack( component.Entity, (bool canExecute) => component.CanExecute = canExecute, Services)); } gameEventSystem.Log(new PrimaryAttackEvent(component.Entity)); } else if (component.State == CharacterAttackComponent.AttackState.Secondary) { if (component.SecondaryHandler != null) { scriptSystem.AddTask(async() => await component.SecondaryHandler.ExecuteAttack( component.Entity, (bool canExecute) => component.CanExecute = canExecute, Services)); } gameEventSystem.Log(new SecondaryAttackEvent(component.Entity)); } component.State = CharacterAttackComponent.AttackState.None; } }
/// <summary> /// Adds a micro thread function to the <paramref name="scriptSystem"/> that executes after waiting specified delay and repeats execution. /// </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="repeatEvery">The amount of time to wait for between repetition.</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"/> or <paramref name="repeatEvery"/> 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 AddAction( this ScriptSystem scriptSystem, Action action, TimeSpan delay, TimeSpan repeatEvery, long priority = 0L) { if (scriptSystem == null) { throw new ArgumentNullException(nameof(scriptSystem)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } if (delay <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(delay), "Must be greater than zero."); } if (repeatEvery <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(repeatEvery), "Must be greater than zero."); } return(scriptSystem.AddTask(DoTask, priority)); //C# 7 Local function could also use a variable Func<Task> DoEvent = async () => { ... }; async Task DoTask() { var elapsedTime = new TimeSpan(0); var scriptDelegateWatcher = new ScriptDelegateWatcher(action); while (scriptSystem.Game.IsRunning && scriptDelegateWatcher.IsActive) { elapsedTime += scriptSystem.Game.UpdateTime.Elapsed; if (elapsedTime >= delay) { elapsedTime -= delay; delay = repeatEvery; action(); } await scriptSystem.NextFrame(); } } }
/// <summary> /// Adds a micro thread function to the <paramref name="scriptSystem"/> that executes after waiting specified delay and repeats execution. /// </summary> /// <param name="scriptSystem">The <see cref="ScriptSystem"/>.</param> /// <param name="action">The micro thread function to execute. The parameter is the progress over time from 0.0f to 1.0f.</param> /// <param name="duration">The duration of the time to execute the micro thread function 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="duration"/> 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 AddOverTimeAction( this ScriptSystem scriptSystem, Action <float> action, TimeSpan duration, long priority = 0L) { if (scriptSystem == null) { throw new ArgumentNullException(nameof(scriptSystem)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } if (duration <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(duration), "Must be greater than zero."); } return(scriptSystem.AddTask(DoTask, priority)); //C# 7 Local function could also use a variable Func<Task> DoEvent = async () => { ... }; async Task DoTask() { var elapsedTime = new TimeSpan(0); var scriptDelegateWatcher = new ScriptDelegateWatcher(action); while (scriptSystem.Game.IsRunning && scriptDelegateWatcher.IsActive) { elapsedTime += scriptSystem.Game.UpdateTime.Elapsed; if (elapsedTime >= duration) { action(1.0f); break; } else { var progress = (float)(elapsedTime.TotalSeconds / duration.TotalSeconds); action(progress); } await scriptSystem.NextFrame(); } } }
/// <summary> /// Adds a micro thread function to the <paramref name="scriptSystem"/> that executes when the event is published. /// </summary> /// <typeparam name="T">The type of the event handler parameter.</typeparam> /// <param name="scriptSystem">The <see cref="ScriptSystem"/>.</param> /// <param name="receiver">The event reciever to listen to for.</param> /// <param name="action">The micro thread function to execute.</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"/>, <paramref name="receiver"/> or <paramref name="action"/> is <see langword="null"/>.</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 AddOnEventTask <T>( this ScriptSystem scriptSystem, EventReceiver <T> receiver, Func <T, Task> action, long priority = 0L) { if (scriptSystem == null) { throw new ArgumentNullException(nameof(scriptSystem)); } if (receiver == null) { throw new ArgumentNullException(nameof(receiver)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } return(scriptSystem.AddTask(DoEvent, priority)); //C# 7 Local function could also use a variable Func<Task> DoEvent = async () => { ... }; async Task DoEvent() { var scriptDelegateWatcher = new ScriptDelegateWatcher(action); while (scriptSystem.Game.IsRunning && scriptDelegateWatcher.IsActive) { if (receiver.TryReceive(out var data)) { await action(data); } await scriptSystem.NextFrame(); } } }