/// <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();
                }
            }
        }
예제 #2
0
        /// <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;
            }
        }
예제 #3
0
        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());
                }
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
 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();
                }
            }
        }