266 lines
8.7 KiB
Plaintext
266 lines
8.7 KiB
Plaintext
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
// NoesisGUI - http://www.noesisengine.com
|
||
|
|
// Copyright (c) Noesis Technologies S.L. All Rights Reserved.
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
|
||
|
|
#include <NsCore/Ptr.h>
|
||
|
|
#include <NsCore/Boxing.h>
|
||
|
|
#include <NsCore/Memory.h>
|
||
|
|
#include <NsCore/CompilerTools.h>
|
||
|
|
#include <NsGui/DependencyObject.h>
|
||
|
|
|
||
|
|
|
||
|
|
namespace Noesis
|
||
|
|
{
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T> struct ValueStorageManagerHelper
|
||
|
|
{
|
||
|
|
static bool CheckType(const Type*, BaseComponent* value)
|
||
|
|
{
|
||
|
|
return Boxing::CanUnbox<T>(value);
|
||
|
|
}
|
||
|
|
|
||
|
|
static Ptr<BaseComponent> Box(const void* value)
|
||
|
|
{
|
||
|
|
return Boxing::Box<T>(*static_cast<const T*>(value));
|
||
|
|
}
|
||
|
|
|
||
|
|
static typename Boxing::Boxer<T>::UnboxType Unbox(BaseComponent* value)
|
||
|
|
{
|
||
|
|
return Boxing::Unbox<T>(value);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
template<class T> struct ValueStorageManagerHelper<Ptr<T>>
|
||
|
|
{
|
||
|
|
static bool CheckType(const Type* type, BaseComponent* value)
|
||
|
|
{
|
||
|
|
return value != 0 ? type->IsAssignableFrom(value->GetClassType()) : true;
|
||
|
|
}
|
||
|
|
|
||
|
|
static Ptr<BaseComponent> Box(const void* value)
|
||
|
|
{
|
||
|
|
return *static_cast<const Ptr<T>*>(value);
|
||
|
|
}
|
||
|
|
|
||
|
|
static Ptr<T> Unbox(BaseComponent* value)
|
||
|
|
{
|
||
|
|
return Ptr<T>(static_cast<T*>(value));
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
ValueStorageManager* ValueStorageManagerImpl<T>::Clone() const
|
||
|
|
{
|
||
|
|
return new ValueStorageManagerImpl<T>();
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
uint32_t ValueStorageManagerImpl<T>::Size() const
|
||
|
|
{
|
||
|
|
return sizeof(T);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
bool ValueStorageManagerImpl<T>::CheckType(const Type* type) const
|
||
|
|
{
|
||
|
|
return type->IsAssignableFrom(TypeOf<RemovePtr<T>>());
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
bool ValueStorageManagerImpl<T>::CheckType(const Type* type,
|
||
|
|
BaseComponent* value) const
|
||
|
|
{
|
||
|
|
return ValueStorageManagerHelper<T>::CheckType(type, value);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
bool ValueStorageManagerImpl<T>::Validate(ValidateValueCallback validate,
|
||
|
|
BaseComponent* value) const
|
||
|
|
{
|
||
|
|
const T& value_ = ValueStorageManagerHelper<T>::Unbox(value);
|
||
|
|
return validate(&value_);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
void ValueStorageManagerImpl<T>::Construct(ValueStorage* storage, const void* value) const
|
||
|
|
{
|
||
|
|
switch ((int)(sizeof(T) <= sizeof(ValueStorage)))
|
||
|
|
{
|
||
|
|
case true:
|
||
|
|
{
|
||
|
|
new(Placement(), storage) T(*static_cast<const T*>(value));
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case false:
|
||
|
|
{
|
||
|
|
void* storage_ = Alloc(sizeof(T));
|
||
|
|
*storage = new(Placement(), storage_) T(*static_cast<const T*>(value));
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
default: NS_ASSERT_UNREACHABLE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
void ValueStorageManagerImpl<T>::Destroy(ValueStorage* storage) const
|
||
|
|
{
|
||
|
|
switch ((int)(sizeof(T) <= sizeof(ValueStorage)))
|
||
|
|
{
|
||
|
|
case true:
|
||
|
|
{
|
||
|
|
static_cast<T*>(static_cast<void*>(storage))->~T();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case false:
|
||
|
|
{
|
||
|
|
static_cast<T*>(static_cast<void*>(*storage))->~T();
|
||
|
|
Dealloc(*storage);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
default: NS_ASSERT_UNREACHABLE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
void* ValueStorageManagerImpl<T>::ToValue(const ValueStorage* storage) const
|
||
|
|
{
|
||
|
|
switch ((int)(sizeof(T) <= sizeof(ValueStorage)))
|
||
|
|
{
|
||
|
|
case true:
|
||
|
|
{
|
||
|
|
return const_cast<void*>(static_cast<const void*>(storage));
|
||
|
|
}
|
||
|
|
case false:
|
||
|
|
{
|
||
|
|
return const_cast<void*>(*static_cast<void*const*>(storage));
|
||
|
|
}
|
||
|
|
default: NS_ASSERT_UNREACHABLE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
void ValueStorageManagerImpl<T>::Copy(void* dst, const void* value) const
|
||
|
|
{
|
||
|
|
T& dst_ = *static_cast<T*>(dst);
|
||
|
|
dst_ = *static_cast<const T*>(value);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
void ValueStorageManagerImpl<T>::Copy(void* dst, BaseComponent* value) const
|
||
|
|
{
|
||
|
|
const T& val = ValueStorageManagerHelper<T>::Unbox(value);
|
||
|
|
ValueStorageManagerImpl::Copy(dst, &val);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
Ptr<BaseComponent> ValueStorageManagerImpl<T>::Box(const void* value) const
|
||
|
|
{
|
||
|
|
return ValueStorageManagerHelper<T>::Box(value);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
const void* ValueStorageManagerImpl<T>::GetValue(const DependencyObject* dob,
|
||
|
|
const DependencyProperty* dp) const
|
||
|
|
{
|
||
|
|
return &dob->GetValue<T>(dp);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
const void* ValueStorageManagerImpl<T>::GetBaseValue(const DependencyObject* dob,
|
||
|
|
const DependencyProperty* dp) const
|
||
|
|
{
|
||
|
|
return &dob->GetBaseValue<T>(dp);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T> bool IsSameValue(const T& l, const T& r)
|
||
|
|
{
|
||
|
|
return Noesis::Equals(l, r);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
inline bool IsSameValue(const Ptr<BaseComponent>& l, const Ptr<BaseComponent>& r)
|
||
|
|
{
|
||
|
|
return BaseObject::Equals(l, r);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
bool ValueStorageManagerImpl<T>::IsSame(const void* left, const void* right) const
|
||
|
|
{
|
||
|
|
const T& l = *static_cast<const T*>(left);
|
||
|
|
const T& r = *static_cast<const T*>(right);
|
||
|
|
return IsSameValue(l, r);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
bool ValueStorageManagerImpl<T>::IsSame(const void* left, BaseComponent* right) const
|
||
|
|
{
|
||
|
|
const T& l = *static_cast<const T*>(left);
|
||
|
|
const T& r = ValueStorageManagerHelper<T>::Unbox(right);
|
||
|
|
return IsSameValue(l, r);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
void ValueStorageManagerImpl<T>::SetValue(DependencyObject* dob, const DependencyProperty* dp,
|
||
|
|
const void* value, uint8_t priority, Expression* expression, const PropertyMetadata* metadata,
|
||
|
|
Value::Destination destination) const
|
||
|
|
{
|
||
|
|
const T& value_ = *static_cast<const T*>(value);
|
||
|
|
|
||
|
|
T oldValue, coercedValue;
|
||
|
|
dob->InternalSetValue(dp, sizeof(T), &oldValue, &value_, &coercedValue, priority, expression,
|
||
|
|
metadata, destination, IsPtr<T>::Result);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
void ValueStorageManagerImpl<T>::SetValue(DependencyObject* dob, const DependencyProperty* dp,
|
||
|
|
BaseComponent* value, uint8_t priority, Expression* expression,
|
||
|
|
const PropertyMetadata* metadata, Value::Destination destination) const
|
||
|
|
{
|
||
|
|
const T& value_ = ValueStorageManagerHelper<T>::Unbox(value);
|
||
|
|
|
||
|
|
T oldValue, coercedValue;
|
||
|
|
dob->InternalSetValue(dp, sizeof(T), &oldValue, &value_, &coercedValue, priority, expression,
|
||
|
|
metadata, destination, IsPtr<T>::Result);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
void ValueStorageManagerImpl<T>::ClearAnimation(DependencyObject* dob,
|
||
|
|
const DependencyProperty* dp) const
|
||
|
|
{
|
||
|
|
dob->ClearAnimation<T>(dp);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
template<class T>
|
||
|
|
void ValueStorageManagerImpl<T>::CoerceValue(DependencyObject* dob, const DependencyProperty* dp,
|
||
|
|
StoredValue* storedValue, const void* defaultValue, const PropertyMetadata* metadata) const
|
||
|
|
{
|
||
|
|
T oldValue, coercedValue;
|
||
|
|
dob->InternalCoerceValue(dp, sizeof(T), storedValue, defaultValue, &oldValue, &coercedValue,
|
||
|
|
metadata, IsPtr<T>::Result);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|