<commit_before>﻿using AGS.API;
using System.ComponentModel;
using System.Threading.Tasks;

namespace AGS.Engine
{
	public class AGSAnimationComponent : AGSComponent, IAnimationComponent, ISpriteProvider
	{
        private IScale _scale;
        private ISpriteRenderComponent _spriteRender;

		public AGSAnimationComponent()
		{
            OnAnimationStarted = new AGSEvent();
		}		

		public IAnimation Animation { get; private set; }

        public IBlockingEvent OnAnimationStarted { get; private set; }

		public override void Init(IEntity entity)
        {
            base.Init(entity);
            entity.Bind<IScaleComponent>(c => _scale = c, c => _scale = null);
            entity.Bind<ISpriteRenderComponent>(c => _spriteRender = c, c => _spriteRender = null);
        }

        public void StartAnimation(IAnimation animation)
		{
            var scale = _scale;
            if (scale?.Width == 0f && animation.Frames.Count > 0) 
			{
                scale.BaseSize = new SizeF(animation.Frames[0].Sprite.Width, animation.Frames[0].Sprite.Height);
			}
			IAnimation currentAnimation = Animation;
            if (currentAnimation != null)
            {
                currentAnimation.State.PropertyChanged -= OnAnimationStatePropertyChanged;
                currentAnimation.State.OnAnimationCompleted.TrySetResult(new AnimationCompletedEventArgs(false));
            }

            Animation = animation;
            animation.State.PropertyChanged += OnAnimationStatePropertyChanged;
            OnAnimationStarted.Invoke();
            if (_spriteRender != null)
                _spriteRender.SpriteProvider = this;
        }

		public AnimationCompletedEventArgs Animate (IAnimation animation)
		{
			var task = Task.Run (async () => await AnimateAsync (animation));
			return task.Result;
		}

		public async Task<AnimationCompletedEventArgs> AnimateAsync (IAnimation animation)
		{
			StartAnimation (animation);
			return await animation.State.OnAnimationCompleted.Task;
		}

        public ISprite Sprite { get => Animation?.Sprite; }

        private void OnAnimationStatePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName != nameof(IAnimationState.CurrentFrame))
                return;
            // resend property changed event to notify that ISpriteProvider.Sprite has new value
            OnPropertyChanged(nameof(Sprite));
        }

    }
}<commit_msg>Hide duplicate sprite property from inspector<commit_after>﻿using AGS.API;
using System.ComponentModel;
using System.Threading.Tasks;

namespace AGS.Engine
{
	public class AGSAnimationComponent : AGSComponent, IAnimationComponent, ISpriteProvider
	{
        private IScale _scale;
        private ISpriteRenderComponent _spriteRender;

		public AGSAnimationComponent()
		{
            OnAnimationStarted = new AGSEvent();
		}		

		public IAnimation Animation { get; private set; }

        public IBlockingEvent OnAnimationStarted { get; private set; }

		public override void Init(IEntity entity)
        {
            base.Init(entity);
            entity.Bind<IScaleComponent>(c => _scale = c, c => _scale = null);
            entity.Bind<ISpriteRenderComponent>(c => _spriteRender = c, c => _spriteRender = null);
        }

        public void StartAnimation(IAnimation animation)
		{
            var scale = _scale;
            if (scale?.Width == 0f && animation.Frames.Count > 0) 
			{
                scale.BaseSize = new SizeF(animation.Frames[0].Sprite.Width, animation.Frames[0].Sprite.Height);
			}
			IAnimation currentAnimation = Animation;
            if (currentAnimation != null)
            {
                currentAnimation.State.PropertyChanged -= OnAnimationStatePropertyChanged;
                currentAnimation.State.OnAnimationCompleted.TrySetResult(new AnimationCompletedEventArgs(false));
            }

            Animation = animation;
            animation.State.PropertyChanged += OnAnimationStatePropertyChanged;
            OnAnimationStarted.Invoke();
            if (_spriteRender != null)
                _spriteRender.SpriteProvider = this;
        }

		public AnimationCompletedEventArgs Animate (IAnimation animation)
		{
			var task = Task.Run (async () => await AnimateAsync (animation));
			return task.Result;
		}

		public async Task<AnimationCompletedEventArgs> AnimateAsync (IAnimation animation)
		{
			StartAnimation (animation);
			return await animation.State.OnAnimationCompleted.Task;
		}

        [Property(Browsable = false)]
        public ISprite Sprite { get => Animation?.Sprite; }

        private void OnAnimationStatePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName != nameof(IAnimationState.CurrentFrame))
                return;
            // resend property changed event to notify that ISpriteProvider.Sprite has new value
            OnPropertyChanged(nameof(Sprite));
        }

    }
}
{'fraction_non_alphanumeric': 0.08353559870550162, 'fraction_numerical': 0.0016181229773462784, 'mean_word_length': 2.6930545182972367, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6615537', 'n_tokens_mistral': 1329, 'n_tokens_neox': 1241, 'n_words': 293}