Пример #1
0
        // Raises the GameProperty.Changed and GameObject.PropertyChanged events.
        internal void OnChanged(GameProperty <T> property, T oldValue, T newValue)
        {
            var handler    = Changed;
            var gameObject = property.Owner;

            if (handler != null || gameObject.NeedToCallPropertyChanged)
            {
                // GameProperty.Changed or GameOwner.PropertyChanged must be called because event handlers
                // are registered.

                // Get args from resource pool
                var args = GamePropertyEventArgs <T> .Create(property, oldValue, newValue);

                // Call GameProperty.Changed event handlers.
                if (handler != null)
                {
                    handler(gameObject, args);
                }

                // Call the virtual OnPropertyChanged method of the GameObject.
                gameObject.OnPropertyChanged(property, oldValue, newValue);

                // Call GameObject to raise GameObject.PropertyChanged event.
                gameObject.OnPropertyChanged(args);
                gameObject.OnPropertyChanged(property.Metadata.PropertyChangedEventArgs);

                args.Recycle();
            }
            else
            {
                // Call the virtual OnPropertyChanged method of the GameObject.
                // (Derived classes can override this method.)
                gameObject.OnPropertyChanged(property, oldValue, newValue);
            }
        }
Пример #2
0
 /// <summary>
 /// Is called after a game object property was changed.
 /// </summary>
 /// <typeparam name="T">The type of the property value.</typeparam>
 /// <param name="gameProperty">The game object property.</param>
 /// <param name="oldValue">The old value.</param>
 /// <param name="newValue">The new value.</param>
 protected internal virtual void OnPropertyChanged <T>(GameProperty <T> gameProperty, T oldValue, T newValue)
 {
     // This method does not use GamePropertyEventArgs<T> to avoid creation/recycling of this
     // data structure when it is not really needed. OnPropertyChanged<T> should be called for
     // all property changes. But the creation of GamePropertyEventArgs<T> is only needed if
     // someone has attached to the PropertyChanged events.
 }
Пример #3
0
        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// <see langword="true"/> if the current object is equal to the <paramref name="other"/>
        /// parameter; otherwise, <see langword="false"/>.
        /// </returns>
        public bool Equals(GameProperty <T> other)
        {
            if (_owner != other._owner)
            {
                return(false);
            }

            return(_metadata == other._metadata);
        }
Пример #4
0
        // Raises the Changing event.
        internal void OnChanging(GameProperty <T> property, T oldValue, ref T newValue)
        {
            var handler = Changing;

            if (handler != null)
            {
                // Get args from resource pool.
                var args = GamePropertyEventArgs <T> .Create(property, oldValue, newValue);

                // Call event handlers.
                handler(property.Owner, args);

                // Changing event handlers can coerce the value. Return coerced value to caller.
                newValue = args.CoercedValue;

                args.Recycle();
            }
        }
Пример #5
0
        /// <inheritdoc/>
        public void Reset()
        {
            // Get local data.
            IGamePropertyData untypedData = Owner.PropertyData.Get(_metadata.Id);

            // Nothing to do if we have no local data.
            if (untypedData == null)
            {
                return;
            }

            // Nothing to do if the local data uses the default value.
            if (!untypedData.HasLocalValue)
            {
                return;
            }

            // Assert: We have a local value and must remove it.

            var data = ((GamePropertyData <T>)untypedData);

            // If the value is animated, changing the BaseValue does not cause events.
            var animatableData = untypedData as AnimatableGamePropertyData <T>;

            // Remember current value.
            T    oldValue;
            bool isAnimated;

            if (animatableData != null)
            {
                oldValue   = animatableData.BaseValue;
                isAnimated = animatableData.IsAnimated;
            }
            else
            {
                oldValue   = data.Value;
                isAnimated = false;
            }

            // Get the target default value from template or metadata.
            T defaultValue;

            if (Owner.Template != null)
            {
                defaultValue = new GameProperty <T>(Owner.Template, _metadata).Value;
            }
            else
            {
                defaultValue = _metadata.DefaultValue;
            }

            if (isAnimated || EqualityComparer <T> .Default.Equals(oldValue, defaultValue))
            {
                // oldValue and defaultValue are the same. We only have to reset the flag.
                data.HasLocalValue = false;
                data.Value         = default(T);
                return;
            }

            var newValue = defaultValue;

            // Raise Changing event.
            data.OnChanging(this, oldValue, ref newValue);

            if (EqualityComparer <T> .Default.Equals(defaultValue, newValue))
            {
                // After coercion in Changing, the target value is still the default value.

                // Value has been reset.
                data.HasLocalValue = false;
                data.Value         = default(T);

                // Raise Changed event if oldValue is different from the newValue.
                if (!EqualityComparer <T> .Default.Equals(oldValue, defaultValue))
                {
                    data.OnChanged(this, oldValue, defaultValue);
                }
            }
            else
            {
                // Value was overwritten by Changing event handler! - We still have a local value!
                // Raise Changed event if oldValue is different from the newValue.
                if (!EqualityComparer <T> .Default.Equals(oldValue, newValue))
                {
                    data.Value = newValue;
                    data.OnChanged(this, oldValue, newValue);
                }
            }
        }
Пример #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GamePropertyChangeHandler{T}"/> class.
 /// </summary>
 /// <param name="gameProperty">The game property.</param>
 public GamePropertyChangeHandler(GameProperty <T> gameProperty)
 {
     _gameProperty = gameProperty;
 }