xmake.repo/packages/n/noesis/latest/Include/NsGui/Freezable.h

160 lines
6.3 KiB
C
Raw Normal View History

2024-12-22 19:15:02 +08:00
////////////////////////////////////////////////////////////////////////////////////////////////////
// NoesisGUI - http://www.noesisengine.com
// Copyright (c) Noesis Technologies S.L. All Rights Reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __GUI_FREEZABLE_H__
#define __GUI_FREEZABLE_H__
#include <NsCore/Noesis.h>
#include <NsGui/DependencySystemApi.h>
#include <NsGui/DependencyObject.h>
#include <NsGui/ISealable.h>
namespace Noesis
{
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Type of change occurred in the freezable
////////////////////////////////////////////////////////////////////////////////////////////////////
enum FreezableEventReason: int32_t
{
FreezableEventReason_Frozen,
FreezableEventReason_PropertyChanged
};
NS_WARNING_PUSH
NS_MSVC_WARNING_DISABLE(4251 4275)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Defines an object that has a modifiable state and a read-only (frozen) state.
///
/// Classes that derive from Freezable provide detailed change notification, can be made immutable,
/// and can clone themselves. The Freezable class provides special features that can help improve
/// application performance when using objects that are expensive to modify or copy.
///
/// A class that derives from Freezable gains the following features:
///
/// * Special states: a read-only (frozen) state and a writable state.
/// * Thread safety: a frozen Freezable object can be shared across threads.
/// * Detailed change notification: Unlike other DependencyObject objects, a Freezable object
/// provides change notifications when sub-property values change
/// * Easy cloning: the Freezable class has already implemented several methods that produce
/// deep clones
///
/// https://docs.microsoft.com/en-us/dotnet/api/system.windows.freezable
////////////////////////////////////////////////////////////////////////////////////////////////////
class NS_GUI_DEPENDENCYSYSTEM_API Freezable: public DependencyObject, public ISealable
{
public:
Freezable();
virtual ~Freezable() = 0;
/// Gets a value that indicates whether the object can be made unmodifiable.
/// \prop
bool CanFreeze() const;
/// Gets a value that indicates whether the object is currently modifiable.
/// \prop
bool IsFrozen() const;
/// Makes the current object unmodifiable and sets its IsFrozen property to true.
void Freeze();
/// Creates a modifiable clone of the Freezable, making deep copies of the object's values.
/// When copying the object's dependency properties, this method copies expressions (which
/// might no longer resolve) but not animations or their current values.
/// The cloned Freezable::IsFrozen property is false even if the source's IsFrozen property is
/// true.
/// \note The cloned element is not initialized
Ptr<Freezable> Clone() const;
/// Creates a modifiable clone (deep copy) of the Freezable using its current values.
/// The cloned object's IsFrozen property is false even if the source's IsFrozen property is
/// true.
/// \note The cloned element is not initialized
Ptr<Freezable> CloneCurrentValue() const;
/// Creates a frozen copy of the Freezable, using base (non-animated) property values. Because
/// the copy is frozen, any frozen sub-objects are copied by reference.
/// The copy's IsFrozen property is set to true.
/// Throws if the Freezable cannot be frozen because it contains expressions or animated
/// properties.
/// \note The cloned element is not initialized
Ptr<Freezable> GetAsFrozen() const;
/// Creates a frozen copy of the Freezable using current property values. Because the copy is
/// frozen, any frozen sub-objects are copied by reference.
/// The copy's IsFrozen property is set to true.
/// \note The cloned element is not initialized
Ptr<Freezable> GetCurrentValueAsFrozen() const;
/// Occurs when the Freezable or an object it contains is modified.
typedef Delegate<void (Freezable*, FreezableEventReason)> FreezableChangedEvent;
FreezableChangedEvent& Changed();
/// From ISealable
//@{
bool CanSeal() const final override;
bool IsSealed() const final override;
void Seal() final override;
//@}
NS_IMPLEMENT_INTERFACE_FIXUP
protected:
/// Makes the Freezable object unmodifiable or tests whether it can be made unmodifiable.
virtual bool FreezeCore(bool isChecking);
/// Makes the instance a clone (deep copy) of the specified Freezable using base (non-animated)
/// property values.
virtual void CloneCore(const Freezable* source);
/// Makes the instance a modifiable clone (deep copy) of the specified Freezable using current
/// property values.
virtual void CloneCurrentValueCore(const Freezable* source);
/// Makes the instance a frozen clone of the specified Freezable using base (non-animated)
/// property values.
virtual void GetAsFrozenCore(const Freezable* source);
/// Makes the current instance a frozen clone of the specified Freezable. If the object has
/// animated dependency properties, their current animated values are copied.
virtual void GetCurrentValueAsFrozenCore(const Freezable* source);
/// Called at the end of CloneCommon (this implies this method is called at the end of
/// CloneCore, CloneCurrentValueCore, GetAsFrozenValue and GetCurrentValueAsFrozenCore
virtual void CloneCommonCore(const Freezable* source);
/// When implemented in a derived class, creates a new instance of the Freezable derived class.
virtual Ptr<Freezable> CreateInstanceCore() const = 0;
/// Called when the current Freezable object is modified.
virtual void OnChanged(FreezableEventReason reason);
/// Raises modification event
void RaiseEvent(FreezableEventReason reason);
/// From DependencyObject
//@{
bool OnPropertyChanged(const DependencyPropertyChangedEventArgs& e) override;
//@}
private:
void CloneCommon(const Freezable* source, bool useBaseValue, bool cloneFreezables);
private:
FreezableChangedEvent mFreezableChangedEvent;
NS_DECLARE_REFLECTION(Freezable, DependencyObject)
};
NS_WARNING_POP
}
#endif