mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
2016 lines
56 KiB
C++
2016 lines
56 KiB
C++
#include "reflection/enumconverter.h"
|
|
|
|
#include "G3D/Color3uint8.h"
|
|
#include "util/exception.h"
|
|
#include "Util/BrickColor.h"
|
|
#include "Util/NormalId.h"
|
|
#include "Util/SystemAddress.h"
|
|
#include "Util/Region3.h"
|
|
#include "Util/Region3int16.h"
|
|
#include "Util/UDim.h"
|
|
#include "Util/Faces.h"
|
|
#include "Util/Axes.h"
|
|
#include "Util/BinaryString.h"
|
|
#include "Util/base64.hpp"
|
|
#include "Util/PhysicalProperties.h"
|
|
#include "v8tree/Instance.h"
|
|
#include "Script/ThreadRef.h"
|
|
#include "rbx/make_shared.h"
|
|
#include "rbx/signal.h"
|
|
|
|
using namespace RBX;
|
|
using namespace RBX::Reflection;
|
|
|
|
namespace RBX {
|
|
float getElementValueOrDefault(const XmlElement* ele, int dflt)
|
|
{
|
|
float output;
|
|
if (ele)
|
|
ele->getValue(output);
|
|
else
|
|
output = dflt;
|
|
|
|
return output;
|
|
}
|
|
|
|
template<>
|
|
bool StringConverter<NormalId>::convertToValue(const std::string& text, NormalId& value)
|
|
{
|
|
if(text.find("Top") != std::string::npos || text.find("top") != std::string::npos ){
|
|
value = NORM_Y;
|
|
return true;
|
|
}
|
|
if(text.find("Bottom") != std::string::npos || text.find("bottom") != std::string::npos ){
|
|
value = NORM_Y_NEG;
|
|
return true;
|
|
}
|
|
if(text.find("Back") != std::string::npos || text.find("back") != std::string::npos ){
|
|
value = NORM_Z;
|
|
return true;
|
|
}
|
|
if(text.find("Front") != std::string::npos || text.find("front") != std::string::npos ){
|
|
value = NORM_Z_NEG;
|
|
return true;
|
|
}
|
|
if(text.find("Right") != std::string::npos || text.find("right") != std::string::npos ){
|
|
value = NORM_X;
|
|
return true;
|
|
}
|
|
if(text.find("Left") != std::string::npos || text.find("left") != std::string::npos ){
|
|
value = NORM_X_NEG;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
bool StringConverter<SystemAddress>::convertToValue(const std::string& text, SystemAddress& value)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
std::string StringConverter<BinaryString>::convertToString(const BinaryString& value)
|
|
{
|
|
return value.value();
|
|
}
|
|
|
|
template<>
|
|
bool StringConverter<BinaryString>::convertToValue(const std::string& text, BinaryString& value)
|
|
{
|
|
value = BinaryString(text);
|
|
return true;
|
|
}
|
|
|
|
} //namespace RBX
|
|
|
|
|
|
namespace RBX {
|
|
namespace Reflection
|
|
{
|
|
//////////////////////////////////////////////////////////
|
|
template<>
|
|
Reflection::EnumDesc<NormalId>::EnumDesc()
|
|
:Reflection::EnumDescriptor("NormalId")
|
|
{
|
|
/*
|
|
TODO:
|
|
Should be: (Also in PartInstance)
|
|
> -Z eyes, nose, mouth
|
|
> +Z back
|
|
> -X left ear
|
|
> +X right ear
|
|
> -Y neck
|
|
> +Y top
|
|
*/
|
|
|
|
addPair(NORM_Y, "Top");
|
|
addPair(NORM_Y_NEG, "Bottom");
|
|
addPair(NORM_Z, "Back");
|
|
addPair(NORM_Z_NEG, "Front");
|
|
addPair(NORM_X, "Right");
|
|
addPair(NORM_X_NEG, "Left");
|
|
|
|
//addPair(NORM_UNDEFINED, "Undefined");
|
|
}
|
|
|
|
template<>
|
|
RBX::NormalId& RBX::Reflection::Variant::convert<RBX::NormalId>(void)
|
|
{
|
|
return genericConvert<RBX::NormalId>();
|
|
}
|
|
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<std::string>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(std::string) + getValue(instance).size();
|
|
}
|
|
template<>
|
|
bool RBX::Reflection::TypedPropertyDescriptor<std::string>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string RBX::Reflection::TypedPropertyDescriptor<std::string>::getStringValue(const DescribedBase* instance) const{
|
|
return getValue(instance);
|
|
}
|
|
template<>
|
|
bool RBX::Reflection::TypedPropertyDescriptor<std::string>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
setValue(instance, text);
|
|
return true;
|
|
}
|
|
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<bool>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(bool);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<bool>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<bool>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<bool>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<bool>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
bool value;
|
|
if (StringConverter<bool>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<float>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(float);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<float>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<float>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<float>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<float>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
float value;
|
|
if (StringConverter<float>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<double>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(double);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<double>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<double>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<double>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<double>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
double value;
|
|
if (StringConverter<double>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<int>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(int);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<int>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<int>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<int>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<int>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
int value;
|
|
if (StringConverter<int>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<RBX::Region3>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(RBX::Region3);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::Region3>::hasStringValue() const {
|
|
return false;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<RBX::Region3>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<RBX::Region3>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::Region3>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
RBX::Region3 value;
|
|
if (StringConverter<RBX::Region3>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
static bool ReadValue(Vector3int16& output, const XmlElement* element)
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* xElement = element->findFirstChildByTag(tag_X);
|
|
if (!xElement)
|
|
return false;
|
|
const XmlElement* yElement = element->findFirstChildByTag(tag_Y);
|
|
const XmlElement* zElement = element->findFirstChildByTag(tag_Z);
|
|
|
|
xElement->getValue((int&)output.x);
|
|
yElement->getValue((int&)output.y);
|
|
zElement->getValue((int&)output.z);
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
static void WriteValue(XmlElement* element, const Vector3int16& v)
|
|
{
|
|
XmlElement* xElement = element->addChild(tag_X);
|
|
XmlElement* yElement = element->addChild(tag_Y);
|
|
XmlElement* zElement = element->addChild(tag_Z);
|
|
|
|
xElement->setValue((int&)v.x);
|
|
yElement->setValue((int&)v.y);
|
|
zElement->setValue((int&)v.z);
|
|
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<RBX::Region3int16>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(Region3int16);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::Region3int16>::hasStringValue() const {
|
|
return false;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<RBX::Region3int16>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<RBX::Region3int16>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::Region3int16>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
RBX::Region3int16 value;
|
|
if (StringConverter<RBX::Region3int16>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::Region3int16>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* minElement = element->findFirstChildByTag(tag_Min);
|
|
const XmlElement* maxElement = element->findFirstChildByTag(tag_Max);
|
|
|
|
Vector3int16 min, max;
|
|
if(ReadValue(min, minElement) && ReadValue(max, maxElement))
|
|
{
|
|
Region3int16 v( min, max );
|
|
setValue(instance, v);
|
|
}
|
|
}
|
|
}
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::Region3int16>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
XmlElement* minElement = element->addChild(tag_Min);
|
|
XmlElement* maxElement = element->addChild(tag_Max);
|
|
|
|
Region3int16 v = getValue(instance);
|
|
WriteValue(minElement, v.getMinPos());
|
|
WriteValue(maxElement, v.getMaxPos());
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<G3D::Vector3>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(G3D::Vector3);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Vector3>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<G3D::Vector3>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<G3D::Vector3>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Vector3>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
G3D::Vector3 value;
|
|
if (StringConverter<G3D::Vector3>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<G3D::Vector2>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(G3D::Vector2);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Vector2>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<G3D::Vector2>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<G3D::Vector2>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Vector2>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
G3D::Vector2 value;
|
|
if (StringConverter<G3D::Vector2>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<std::string>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
std::string value;
|
|
if (element->getValue(value))
|
|
setValue(instance, value);
|
|
}
|
|
}
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<std::string>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
element->setValue(getValue(instance));
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<float>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
float value;
|
|
if (element->getValue(value))
|
|
setValue(instance, value);
|
|
}
|
|
}
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<float>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
element->setValue(getValue(instance));
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<bool>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
bool value;
|
|
if (element->getValue(value))
|
|
setValue(instance, value);
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<double>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
element->setValue(getValue(instance));
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<double>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
double value;
|
|
if (element->getValue(value))
|
|
setValue(instance, value);
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<bool>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
element->setValue(getValue(instance));
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<int>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
int value;
|
|
if (element->getValue(value))
|
|
setValue(instance, value);
|
|
}
|
|
}
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<int>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
element->setValue(getValue(instance));
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<class G3D::Vector2>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* xElement = element->findFirstChildByTag(tag_X);
|
|
if (!xElement)
|
|
return;
|
|
const XmlElement* yElement = element->findFirstChildByTag(tag_Y);
|
|
|
|
G3D::Vector2 v;
|
|
xElement->getValue(v.x);
|
|
yElement->getValue(v.y);
|
|
setValue(instance, v);
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<class G3D::Vector2>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
// Write the data out in accordance with ROBLOX Schema
|
|
|
|
XmlElement* xElement = element->addChild(tag_X);
|
|
XmlElement* yElement = element->addChild(tag_Y);
|
|
|
|
G3D::Vector2 v = getValue(instance);
|
|
xElement->setValue(v.x);
|
|
yElement->setValue(v.y);
|
|
}
|
|
|
|
static bool ReadValue(Vector3& output, const XmlElement* element)
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* xElement = element->findFirstChildByTag(tag_X);
|
|
if (!xElement)
|
|
return false;
|
|
const XmlElement* yElement = element->findFirstChildByTag(tag_Y);
|
|
const XmlElement* zElement = element->findFirstChildByTag(tag_Z);
|
|
|
|
xElement->getValue(output.x);
|
|
yElement->getValue(output.y);
|
|
zElement->getValue(output.z);
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
static void WriteValue(XmlElement* element, const Vector3& v)
|
|
{
|
|
XmlElement* xElement = element->addChild(tag_X);
|
|
XmlElement* yElement = element->addChild(tag_Y);
|
|
XmlElement* zElement = element->addChild(tag_Z);
|
|
|
|
xElement->setValue(v.x);
|
|
yElement->setValue(v.y);
|
|
zElement->setValue(v.z);
|
|
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<class G3D::Vector3>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
G3D::Vector3 v;
|
|
if(ReadValue(v, element)){
|
|
setValue(instance, v);
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<class G3D::Vector3>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
G3D::Vector3 v = getValue(instance);
|
|
WriteValue(element, v);
|
|
}
|
|
|
|
template<>
|
|
const Reflection::Type& Reflection::Type::getSingleton< shared_ptr<Reflection::DescribedBase> >()
|
|
{
|
|
static TType< shared_ptr<Reflection::DescribedBase> > type("Object");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
const Type& Reflection::Type::getSingleton< shared_ptr<Instance> >()
|
|
{
|
|
static TType< shared_ptr<Instance> > type("Instance");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<shared_ptr<const Instances> >()
|
|
{
|
|
static TType<shared_ptr<const Instances> > type("Objects");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<int>()
|
|
{
|
|
static TType<int> type("int");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<long>()
|
|
{
|
|
static TType<long> type("long");
|
|
return type;
|
|
}
|
|
|
|
|
|
template<>
|
|
int& RBX::Reflection::Variant::convert<int>(void)
|
|
{
|
|
// Convert double to int
|
|
if (_type->isType<double>())
|
|
{
|
|
value = G3D::iRound(cast<double>());
|
|
_type = &Type::singleton<int>();
|
|
}
|
|
|
|
// Convert float to int
|
|
if (_type->isType<float>())
|
|
{
|
|
value = G3D::iRound(cast<float>());
|
|
_type = &Type::singleton<int>();
|
|
}
|
|
|
|
// Convert bool to int
|
|
if (_type->isType<bool>())
|
|
{
|
|
value = (cast<bool>() ? 1 : 0);
|
|
_type = &Type::singleton<int>();
|
|
}
|
|
|
|
return genericConvert<int>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<bool>()
|
|
{
|
|
static TType<bool> type("bool");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
bool& RBX::Reflection::Variant::convert<bool>(void)
|
|
{
|
|
// Convert int to bool
|
|
if (_type->isType<int>())
|
|
{
|
|
value = (bool) (cast<int>()!=0);
|
|
_type = &Type::singleton<bool>();
|
|
}
|
|
|
|
// Convert float to bool
|
|
else if (_type->isType<float>())
|
|
{
|
|
value = (bool) (cast<float>()!=0.0f);
|
|
_type = &Type::singleton<bool>();
|
|
}
|
|
|
|
// Convert double to bool
|
|
else if (_type->isType<double>())
|
|
{
|
|
value = (bool) (cast<double>()!=0.0);
|
|
_type = &Type::singleton<bool>();
|
|
}
|
|
|
|
return genericConvert<bool>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<float>()
|
|
{
|
|
static TType<float> type("float");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
float& RBX::Reflection::Variant::convert<float>(void)
|
|
{
|
|
// Convert double to float
|
|
if (_type->isType<double>())
|
|
{
|
|
value = (float) cast<double>();
|
|
_type = &Type::singleton<float>();
|
|
}
|
|
|
|
// Convert int to float
|
|
else if (_type->isType<int>())
|
|
{
|
|
value = (float) cast<int>();
|
|
_type = &Type::singleton<float>();
|
|
}
|
|
|
|
// Convert bool to float
|
|
else if (_type->isType<bool>())
|
|
{
|
|
value = (float) (cast<bool>() ? 1 : 0);
|
|
_type = &Type::singleton<float>();
|
|
}
|
|
|
|
return genericConvert<float>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<double>()
|
|
{
|
|
static TType<double> type("double");
|
|
return type;
|
|
}
|
|
|
|
|
|
|
|
|
|
template<>
|
|
double& RBX::Reflection::Variant::convert<double>(void)
|
|
{
|
|
// Convert int to double
|
|
if (_type->isType<int>())
|
|
{
|
|
value = (double) cast<int>();
|
|
_type = &Type::singleton<double>();
|
|
}
|
|
|
|
// Convert bool to double
|
|
else if (_type->isType<bool>())
|
|
{
|
|
value = (double) (cast<bool>() ? 1 : 0);
|
|
_type = &Type::singleton<double>();
|
|
}
|
|
|
|
// Convert float to double
|
|
else if (_type->isType<float>())
|
|
{
|
|
value = (double) cast<float>();
|
|
_type = &Type::singleton<double>();
|
|
}
|
|
|
|
return genericConvert<double>();
|
|
}
|
|
|
|
|
|
template<>
|
|
RBX::Region3& RBX::Reflection::Variant::convert<RBX::Region3>(void)
|
|
{
|
|
return genericConvert<RBX::Region3>();
|
|
}
|
|
|
|
template<>
|
|
RBX::Region3int16& RBX::Reflection::Variant::convert<RBX::Region3int16>(void)
|
|
{
|
|
return genericConvert<RBX::Region3int16>();
|
|
}
|
|
|
|
template<>
|
|
G3D::Vector3& RBX::Reflection::Variant::convert<G3D::Vector3>(void)
|
|
{
|
|
return genericConvert<G3D::Vector3>();
|
|
}
|
|
|
|
template<>
|
|
RBX::Vector2& RBX::Reflection::Variant::convert<RBX::Vector2>(void)
|
|
{
|
|
return genericConvert<RBX::Vector2>();
|
|
}
|
|
|
|
template<>
|
|
G3D::CoordinateFrame& RBX::Reflection::Variant::convert<G3D::CoordinateFrame>(void)
|
|
{
|
|
return genericConvert<G3D::CoordinateFrame>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<RBX::ContentId>()
|
|
{
|
|
static TType<RBX::ContentId> type("Content");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
ContentId& RBX::Reflection::Variant::convert<ContentId>(void)
|
|
{
|
|
if (_type->isType<std::string>())
|
|
{
|
|
value = ContentId(cast<std::string>());
|
|
_type = &Type::singleton<ContentId>();
|
|
}
|
|
return genericConvert<ContentId>();
|
|
}
|
|
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<std::string>()
|
|
{
|
|
static TType<std::string> type("string");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<G3D::Vector3>()
|
|
{
|
|
static TType<G3D::Vector3> type("Vector3");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<RBX::Vector2>()
|
|
{
|
|
static TType<RBX::Vector2> type("Vector2");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<rbx::signals::connection>()
|
|
{
|
|
static TType<rbx::signals::connection> type("Connection");
|
|
return type;
|
|
}
|
|
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<shared_ptr<const Tuple> >()
|
|
{
|
|
static TType<shared_ptr<const Tuple> > type("Tuple");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
std::string& RBX::Reflection::Variant::convert<std::string>(void)
|
|
{
|
|
// TODO: This should be made compact somehow!!!
|
|
if (isType<bool>())
|
|
{
|
|
value = StringConverter<bool>::convertToString(cast<bool>());
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if (isType<int>())
|
|
{
|
|
value = StringConverter<int>::convertToString(cast<int>());
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if (isType<long>())
|
|
{
|
|
value = StringConverter<long>::convertToString(cast<long>());
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if (isType<float>())
|
|
{
|
|
value = StringConverter<float>::convertToString(cast<float>());
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if (isType<double>())
|
|
{
|
|
value = StringConverter<double>::convertToString(cast<double>());
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if (isType<G3D::Vector3>())
|
|
{
|
|
value = StringConverter<G3D::Vector3>::convertToString(cast<G3D::Vector3>());
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if (isType<RBX::CoordinateFrame>())
|
|
{
|
|
if (cast<RBX::CoordinateFrame>() == RBX::CoordinateFrame())
|
|
value = std::string("Identity");
|
|
else
|
|
value = std::string("?");
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if (isType<Lua::WeakFunctionRef>())
|
|
{
|
|
if(cast<Lua::WeakFunctionRef>().empty())
|
|
value = std::string("nil");
|
|
else
|
|
value = std::string("function");
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if (isType<shared_ptr<Instance> >())
|
|
{
|
|
const shared_ptr<Instance>& v = cast<shared_ptr<Instance> >();
|
|
if (v)
|
|
value = std::string(Type::singleton< shared_ptr<Instance> >().name.c_str());
|
|
else
|
|
value = std::string("nil");
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if(isType<shared_ptr<const Reflection::ValueArray> >())
|
|
{
|
|
value = std::string("{}");
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
else if (const Reflection::EnumDescriptor* desc = Reflection::EnumDescriptor::lookupDescriptor(type()))
|
|
{
|
|
const Reflection::EnumDescriptor::Item* item = desc->lookup(*this);
|
|
if (item!=NULL)
|
|
{
|
|
std::string stringValue;
|
|
if(item->convertToString(stringValue)){
|
|
value = stringValue;
|
|
_type = &Type::singleton<std::string>();
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string* id = tryCast<std::string>();
|
|
if (id==NULL)
|
|
throw std::runtime_error("Unable to cast value to std::string");
|
|
return *id;
|
|
}
|
|
|
|
|
|
template<>
|
|
shared_ptr<Instance>& Reflection::Variant::convert<shared_ptr<Instance> >(void)
|
|
{
|
|
// Interpret "void" (Lua nil) as a null Instance
|
|
if (isType<void>())
|
|
{
|
|
value = shared_ptr<Instance>();
|
|
_type = &Type::singleton<shared_ptr<Instance> >();
|
|
}
|
|
else if (isType<shared_ptr<Reflection::DescribedBase> >())
|
|
{
|
|
const shared_ptr<Reflection::DescribedBase>& v = cast<shared_ptr<Reflection::DescribedBase> >();
|
|
|
|
value = shared_dynamic_cast<Instance>(v);
|
|
_type = &Type::singleton<shared_ptr<Instance> >();
|
|
}
|
|
|
|
shared_ptr<Instance>* v = tryCast<shared_ptr<Instance> >();
|
|
if (v==NULL)
|
|
throw std::runtime_error("Unable to cast value to Object");
|
|
return *v;
|
|
}
|
|
}}
|
|
|
|
static void CastInstance(Variant value, shared_ptr<Instances> instancesCollection)
|
|
{
|
|
instancesCollection->push_back(value.convert<shared_ptr<Instance> >());
|
|
}
|
|
|
|
namespace RBX {
|
|
namespace Reflection {
|
|
|
|
template<>
|
|
shared_ptr<const Instances>& Reflection::Variant::convert<shared_ptr<const Instances> >(void)
|
|
{
|
|
{
|
|
shared_ptr<const Instances>* v = tryCast<shared_ptr<const Instances> >();
|
|
if (v!=NULL){
|
|
return *v;
|
|
}
|
|
}
|
|
|
|
{
|
|
shared_ptr<const ValueArray>* v = tryCast<shared_ptr<const ValueArray> >();
|
|
if(v != NULL){
|
|
shared_ptr<Instances> newInstances(new Instances());
|
|
std::for_each((*v)->begin(), (*v)->end(), boost::bind(&CastInstance, _1, newInstances));
|
|
|
|
value = shared_ptr<const Instances>(newInstances);
|
|
_type = &Type::singleton<shared_ptr<const Instances> >();
|
|
|
|
return cast<shared_ptr<const Instances> >();
|
|
}
|
|
}
|
|
throw std::runtime_error("Unable to cast value to Objects");
|
|
}
|
|
|
|
template<>
|
|
shared_ptr<Reflection::DescribedBase>& Reflection::Variant::convert<shared_ptr<Reflection::DescribedBase> >(void)
|
|
{
|
|
// Interpret "void" (Lua nil) as a null Instance
|
|
if (isType<void>())
|
|
{
|
|
value = shared_ptr<Reflection::DescribedBase>();
|
|
_type = &Type::singleton<shared_ptr<Reflection::DescribedBase> >();
|
|
}
|
|
|
|
else if (isType<shared_ptr<Instance> >())
|
|
{
|
|
const shared_ptr<Instance>& v = cast<shared_ptr<Instance> >();
|
|
value = shared_static_cast<Reflection::DescribedBase>(v);
|
|
_type = &Type::singleton<shared_ptr<Reflection::DescribedBase> >();
|
|
}
|
|
|
|
shared_ptr<Reflection::DescribedBase>* v = tryCast<shared_ptr<Reflection::DescribedBase> >();
|
|
if (v==NULL)
|
|
throw std::runtime_error("Unable to cast value to Object");
|
|
return *v;
|
|
}
|
|
|
|
template<>
|
|
shared_ptr<const Tuple>& Variant::convert<shared_ptr<const Tuple> >(void)
|
|
{
|
|
shared_ptr<const Tuple>* v = tryCast<shared_ptr<const Tuple> >();
|
|
if (v != NULL)
|
|
return *v;
|
|
|
|
if (isVoid())
|
|
{
|
|
value = shared_ptr<const Tuple>(); // null is equivalent to 0 items (optimization)
|
|
_type = &Type::singleton< shared_ptr<const Tuple> >();
|
|
return cast< shared_ptr<const Tuple> >();
|
|
}
|
|
|
|
// Any value can be converted to a tuple of 1
|
|
shared_ptr<Tuple> tuple = rbx::make_shared<Tuple>(1);
|
|
tuple->values[0] = *this;
|
|
value = shared_ptr<const Tuple>(tuple);
|
|
_type = &Type::singleton< shared_ptr<const Tuple> >();
|
|
return cast< shared_ptr<const Tuple> >();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Vector2int16
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
G3D::Vector2int16& RBX::Reflection::Variant::convert<G3D::Vector2int16>(void)
|
|
{
|
|
return genericConvert<G3D::Vector2int16>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<G3D::Vector2int16>()
|
|
{
|
|
static TType<G3D::Vector2int16> type("Vector2int16");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<G3D::Vector2int16>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(G3D::Vector2int16);
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Vector2int16>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
|
|
template<>
|
|
std::string TypedPropertyDescriptor<G3D::Vector2int16>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<G3D::Vector2int16>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Vector2int16>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
G3D::Vector2int16 value;
|
|
if (StringConverter<G3D::Vector2int16>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<G3D::Vector2int16>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* xElement = element->findFirstChildByTag(tag_X);
|
|
const XmlElement* yElement = element->findFirstChildByTag(tag_Y);
|
|
|
|
int x, y;
|
|
xElement->getValue(x);
|
|
yElement->getValue(y);
|
|
setValue(instance, G3D::Vector2int16(x,y));
|
|
|
|
}
|
|
}
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<G3D::Vector2int16>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
// Write the data out in accordance with ROBLOX Schema
|
|
|
|
XmlElement* xElement = element->addChild(tag_X);
|
|
XmlElement* yElement = element->addChild(tag_Y);
|
|
|
|
G3D::Vector2int16 v = getValue(instance);
|
|
xElement->setValue((int)v.x);
|
|
yElement->setValue((int)v.y);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Vector3int16
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
G3D::Vector3int16& RBX::Reflection::Variant::convert<G3D::Vector3int16>(void)
|
|
{
|
|
return genericConvert<G3D::Vector3int16>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<G3D::Vector3int16>()
|
|
{
|
|
static TType<G3D::Vector3int16> type("Vector3int16");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<G3D::Vector3int16>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(G3D::Vector3int16);
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Vector3int16>::hasStringValue() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
template<>
|
|
std::string TypedPropertyDescriptor<G3D::Vector3int16>::getStringValue(const DescribedBase* instance) const
|
|
{
|
|
return StringConverter<G3D::Vector3int16>::convertToString(getValue(instance));
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Vector3int16>::setStringValue(DescribedBase* instance, const std::string& text) const
|
|
{
|
|
G3D::Vector3int16 value;
|
|
if (StringConverter<G3D::Vector3int16>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<G3D::Vector3int16>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* xElement = element->findFirstChildByTag(tag_X);
|
|
const XmlElement* yElement = element->findFirstChildByTag(tag_Y);
|
|
const XmlElement* zElement = element->findFirstChildByTag(tag_Z);
|
|
|
|
int x, y, z;
|
|
xElement->getValue(x);
|
|
yElement->getValue(y);
|
|
zElement->getValue(z);
|
|
setValue(instance, G3D::Vector3int16(x,y,z));
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<G3D::Vector3int16>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
XmlElement* xElement = element->addChild(tag_X);
|
|
XmlElement* yElement = element->addChild(tag_Y);
|
|
XmlElement* zElement = element->addChild(tag_Z);
|
|
|
|
G3D::Vector3int16 v = getValue(instance);
|
|
xElement->setValue((int)v.x);
|
|
yElement->setValue((int)v.y);
|
|
zElement->setValue((int)v.z);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PhysicalProperties
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
template<>
|
|
PhysicalProperties& RBX::Reflection::Variant::convert<PhysicalProperties>(void)
|
|
{
|
|
return genericConvert<PhysicalProperties>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<PhysicalProperties>()
|
|
{
|
|
static TType<PhysicalProperties> type("PhysicalProperties");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<PhysicalProperties>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(PhysicalProperties);
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<PhysicalProperties>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
|
|
template<>
|
|
std::string TypedPropertyDescriptor<PhysicalProperties>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<PhysicalProperties>::convertToString(getValue(instance));
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<PhysicalProperties>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<PhysicalProperties>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
bool customPhysEnabled = false;
|
|
const XmlElement* customPhysPropElement = element->findFirstChildByTag(tag_customPhysProp);
|
|
if (customPhysPropElement)
|
|
{
|
|
customPhysPropElement->getValue(customPhysEnabled);
|
|
}
|
|
|
|
if (customPhysEnabled)
|
|
{
|
|
const XmlElement* densityElement = element->findFirstChildByTag(tag_customDensity);
|
|
const XmlElement* frictionElement = element->findFirstChildByTag(tag_customFriction);
|
|
const XmlElement* elasticityElement = element->findFirstChildByTag(tag_customElasticity);
|
|
const XmlElement* frictionWeightElement = element->findFirstChildByTag(tag_customFrictionWeight);
|
|
const XmlElement* elasticityWeightElement = element->findFirstChildByTag(tag_customElasticityWeight);
|
|
float density = getElementValueOrDefault(densityElement, 1.0f);
|
|
float friction = getElementValueOrDefault(frictionElement, 0.0f);
|
|
float elasticity = getElementValueOrDefault(elasticityElement, 0.0f);
|
|
float frictionWeight = getElementValueOrDefault(frictionWeightElement, 1.0f);
|
|
float elasticityWeight = getElementValueOrDefault(elasticityWeightElement, 1.0f);
|
|
|
|
setValue(instance, PhysicalProperties(density, friction, elasticity, frictionWeight, elasticityWeight));
|
|
}
|
|
else
|
|
{
|
|
setValue(instance, PhysicalProperties());
|
|
}
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<PhysicalProperties>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
|
|
//Only worth saving if CustomPhysicalProperties is enabled
|
|
PhysicalProperties currentProperties = getValue(instance);
|
|
bool customEnabled = currentProperties.getCustomEnabled();
|
|
|
|
XmlElement* customPhysPropElement = element->addChild(tag_customPhysProp);
|
|
customPhysPropElement->setValue(customEnabled);
|
|
if (customEnabled)
|
|
{
|
|
XmlElement* densityElement = element->addChild(tag_customDensity);
|
|
XmlElement* frictionElement = element->addChild(tag_customFriction);
|
|
XmlElement* elasticityElement = element->addChild(tag_customElasticity);
|
|
XmlElement* frictionWeightElement = element->addChild(tag_customFrictionWeight);
|
|
XmlElement* elasticityWeightElement = element->addChild(tag_customElasticityWeight);
|
|
|
|
densityElement->setValue(currentProperties.getDensity());
|
|
frictionElement->setValue(currentProperties.getFriction());
|
|
elasticityElement->setValue(currentProperties.getElasticity());
|
|
frictionWeightElement->setValue(currentProperties.getFrictionWeight());
|
|
elasticityWeightElement->setValue(currentProperties.getElasticityWeight());
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Rect2D
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
G3D::Rect2D& RBX::Reflection::Variant::convert<G3D::Rect2D>(void)
|
|
{
|
|
return genericConvert<G3D::Rect2D>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<G3D::Rect2D>()
|
|
{
|
|
static TType<G3D::Rect2D> type("Rect2D");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<G3D::Rect2D>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(G3D::Rect2D);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Rect2D>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<G3D::Rect2D>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<G3D::Rect2D>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Rect2D>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
return false;
|
|
}
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<G3D::Rect2D>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* minElement = element->findFirstChildByTag(tag_Min);
|
|
const XmlElement* maxElement = element->findFirstChildByTag(tag_Max);
|
|
|
|
Vector2 min;
|
|
Vector2 max;
|
|
|
|
// TODO: re-use vector2 code?
|
|
{
|
|
const XmlElement* xElement = minElement->findFirstChildByTag(tag_X);
|
|
const XmlElement* yElement = minElement->findFirstChildByTag(tag_Y);
|
|
|
|
xElement->getValue(min.x);
|
|
yElement->getValue(min.y);
|
|
}
|
|
{
|
|
const XmlElement* xElement = maxElement->findFirstChildByTag(tag_X);
|
|
const XmlElement* yElement = maxElement->findFirstChildByTag(tag_Y);
|
|
|
|
xElement->getValue(max.x);
|
|
yElement->getValue(max.y);
|
|
}
|
|
|
|
setValue(instance, G3D::Rect2D(min,max));
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<G3D::Rect2D>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
// Write the data out in accordance with ROBLOX Schema
|
|
|
|
XmlElement* minElement = element->addChild(tag_Min);
|
|
XmlElement* maxElement = element->addChild(tag_Max);
|
|
|
|
// TODO: re-use vector2 code?
|
|
G3D::Rect2D v = getValue(instance);
|
|
{
|
|
XmlElement* xElement = minElement->addChild(tag_X);
|
|
XmlElement* yElement = minElement->addChild(tag_Y);
|
|
|
|
xElement->setValue(v.x0());
|
|
yElement->setValue(v.y0());
|
|
}
|
|
{
|
|
XmlElement* xElement = maxElement->addChild(tag_X);
|
|
XmlElement* yElement = maxElement->addChild(tag_Y);
|
|
|
|
xElement->setValue(v.x1());
|
|
yElement->setValue(v.y1());
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// UDim
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
RBX::UDim& RBX::Reflection::Variant::convert<RBX::UDim>(void)
|
|
{
|
|
return genericConvert<RBX::UDim>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<RBX::UDim>()
|
|
{
|
|
static TType<RBX::UDim> type("UDim");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<RBX::UDim>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(RBX::UDim);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::UDim>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<RBX::UDim>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<RBX::UDim>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::UDim>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
return false;
|
|
}
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::UDim>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* sElement = element->findFirstChildByTag(tag_S);
|
|
const XmlElement* oElement = element->findFirstChildByTag(tag_O);
|
|
|
|
float s;
|
|
int o;
|
|
sElement->getValue(s);
|
|
oElement->getValue(o);
|
|
setValue(instance, RBX::UDim(s,o));
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::UDim>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
// Write the data out in accordance with ROBLOX Schema
|
|
|
|
XmlElement* sElement = element->addChild(tag_S);
|
|
XmlElement* oElement = element->addChild(tag_O);
|
|
|
|
RBX::UDim v = getValue(instance);
|
|
sElement->setValue(v.scale);
|
|
oElement->setValue((int)v.offset);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// UDim2
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
RBX::UDim2& RBX::Reflection::Variant::convert<RBX::UDim2>(void)
|
|
{
|
|
return genericConvert<RBX::UDim2>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<RBX::UDim2>()
|
|
{
|
|
static TType<RBX::UDim2> type("UDim2");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<RBX::UDim2>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(RBX::UDim2);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::UDim2>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<RBX::UDim2>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<RBX::UDim2>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::UDim2>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::UDim2>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* xsElement = element->findFirstChildByTag(tag_XS);
|
|
const XmlElement* xoElement = element->findFirstChildByTag(tag_XO);
|
|
const XmlElement* ysElement = element->findFirstChildByTag(tag_YS);
|
|
const XmlElement* yoElement = element->findFirstChildByTag(tag_YO);
|
|
|
|
float xs,ys;
|
|
int xo,yo;
|
|
xsElement->getValue(xs);
|
|
xoElement->getValue(xo);
|
|
ysElement->getValue(ys);
|
|
yoElement->getValue(yo);
|
|
setValue(instance, RBX::UDim2(xs,xo, ys,yo));
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::UDim2>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
// Write the data out in accordance with ROBLOX Schema
|
|
|
|
XmlElement* xsElement = element->addChild(tag_XS);
|
|
XmlElement* xoElement = element->addChild(tag_XO);
|
|
XmlElement* ysElement = element->addChild(tag_YS);
|
|
XmlElement* yoElement = element->addChild(tag_YO);
|
|
|
|
RBX::UDim2 v = getValue(instance);
|
|
xsElement->setValue(v.x.scale);
|
|
xoElement->setValue((int)v.x.offset);
|
|
ysElement->setValue(v.y.scale);
|
|
yoElement->setValue((int)v.y.offset);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Faces
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
RBX::Faces& RBX::Reflection::Variant::convert<RBX::Faces>(void)
|
|
{
|
|
return genericConvert<RBX::Faces>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<RBX::Faces>()
|
|
{
|
|
static TType<RBX::Faces> type("Faces");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<RBX::Faces>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(RBX::Faces);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::Faces>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<RBX::Faces>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<RBX::Faces>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::Faces>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::Faces>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* facesElement = element->findFirstChildByTag(tag_faces);
|
|
|
|
int faces;
|
|
facesElement->getValue(faces);
|
|
setValue(instance, RBX::Faces(faces));
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::Faces>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
// Write the data out in accordance with ROBLOX Schema
|
|
|
|
XmlElement* facesElement = element->addChild(tag_faces);
|
|
|
|
RBX::Faces v = getValue(instance);
|
|
facesElement->setValue(v.normalIdMask);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Axes
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
RBX::Axes& RBX::Reflection::Variant::convert<RBX::Axes>(void)
|
|
{
|
|
return genericConvert<RBX::Axes>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<RBX::Axes>()
|
|
{
|
|
static TType<RBX::Axes> type("Axes");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<RBX::Axes>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(RBX::Axes);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::Axes>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<RBX::Axes>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<RBX::Axes>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::Axes>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::Axes>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* axesElement = element->findFirstChildByTag(tag_axes);
|
|
|
|
int axes;
|
|
axesElement->getValue(axes);
|
|
setValue(instance, RBX::Axes(axes));
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::Axes>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
// Write the data out in accordance with ROBLOX Schema
|
|
|
|
XmlElement* axesElement = element->addChild(tag_axes);
|
|
|
|
RBX::Axes v = getValue(instance);
|
|
axesElement->setValue(v.axisMask);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Color3
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
G3D::Color3& RBX::Reflection::Variant::convert<G3D::Color3>(void)
|
|
{
|
|
return genericConvert<G3D::Color3>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<G3D::Color3>()
|
|
{
|
|
static TType<G3D::Color3> type("Color3");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<G3D::Color3>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(G3D::Color3);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Color3>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string TypedPropertyDescriptor<G3D::Color3>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<G3D::Color3>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<G3D::Color3>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
G3D::Color3 value;
|
|
if (StringConverter<G3D::Color3>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<G3D::Color3>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
unsigned int argb;
|
|
if (element->getValue(argb))
|
|
{
|
|
setValue(instance, G3D::Color3uint8::fromARGB(argb));
|
|
}
|
|
else
|
|
{
|
|
// Old-style
|
|
const XmlElement* xElement = element->findFirstChildByTag(tag_R);
|
|
const XmlElement* yElement = element->findFirstChildByTag(tag_G);
|
|
const XmlElement* zElement = element->findFirstChildByTag(tag_B);
|
|
|
|
if (xElement && yElement && zElement)
|
|
{
|
|
G3D::Color3 v;
|
|
xElement->getValue(v.r);
|
|
yElement->getValue(v.g);
|
|
zElement->getValue(v.b);
|
|
setValue(instance, v);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<G3D::Color3>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
// Write the data out in accordance with ROBLOX Schema
|
|
|
|
G3D::Color3uint8 v = G3D::Color3uint8(getValue(instance));
|
|
element->setValue(v.asUInt32());
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Ray
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
RBX::RbxRay& RBX::Reflection::Variant::convert<RBX::RbxRay>(void)
|
|
{
|
|
return genericConvert<RBX::RbxRay>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<RBX::RbxRay>()
|
|
{
|
|
static TType<RBX::RbxRay> type("Ray");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<RBX::RbxRay>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(RBX::RbxRay);
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::RbxRay>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
|
|
template<>
|
|
std::string TypedPropertyDescriptor<RBX::RbxRay>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<RBX::RbxRay>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<RBX::RbxRay>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
RBX::RbxRay value;
|
|
if (StringConverter<RBX::RbxRay>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<class RBX::RbxRay>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
const XmlElement* originElement = element->findFirstChildByTag(tag_Origin);
|
|
const XmlElement* directionElement = element->findFirstChildByTag(tag_Direction);
|
|
|
|
RbxRay v;
|
|
if(ReadValue(v.origin(), originElement) && ReadValue(v.direction(), directionElement)){
|
|
setValue(instance, v);
|
|
}
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<class RBX::RbxRay>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
XmlElement* originElement = element->addChild(tag_Origin);
|
|
XmlElement* directionElement = element->addChild(tag_Direction);
|
|
|
|
RBX::RbxRay v = getValue(instance);
|
|
WriteValue(originElement, v.origin());
|
|
WriteValue(directionElement, v.direction());
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Brick Color
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue
|
|
|
|
template<>
|
|
RBX::BrickColor& RBX::Reflection::Variant::convert<RBX::BrickColor>(void)
|
|
{
|
|
return genericConvert<RBX::BrickColor>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<BrickColor>()
|
|
{
|
|
static TType<BrickColor> type("BrickColor", "int");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<BrickColor>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(BrickColor);
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<BrickColor>::hasStringValue() const {
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
std::string TypedPropertyDescriptor<BrickColor>::getStringValue(const DescribedBase* instance) const {
|
|
return Super::getStringValue(instance);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<BrickColor>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
return Super::setStringValue(instance, text);
|
|
}
|
|
|
|
|
|
template<>
|
|
void TypedPropertyDescriptor<BrickColor>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
int number;
|
|
if (element->getValue(number))
|
|
{
|
|
setValue(instance, BrickColor(number));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
template<>
|
|
void TypedPropertyDescriptor<BrickColor>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
// Write the data out in accordance with ROBLOX Schema
|
|
element->setValue(getValue(instance).asInt());
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SystemAddress
|
|
// convert, getSingleton, hasStringValue, getStringValue, setStringValue, readValue, writeValue, convertToValue
|
|
|
|
template<>
|
|
RBX::SystemAddress& RBX::Reflection::Variant::convert<RBX::SystemAddress>(void)
|
|
{
|
|
return genericConvert<RBX::SystemAddress>();
|
|
}
|
|
|
|
template<>
|
|
const Type& Type::getSingleton<SystemAddress>()
|
|
{
|
|
static TType<SystemAddress> type("SystemAddress");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<SystemAddress>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(SystemAddress);
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<SystemAddress>::hasStringValue() const {
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
std::string TypedPropertyDescriptor<SystemAddress>::getStringValue(const DescribedBase* instance) const {
|
|
return Super::getStringValue(instance);
|
|
}
|
|
template<>
|
|
bool TypedPropertyDescriptor<SystemAddress>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
return Super::setStringValue(instance, text);
|
|
}
|
|
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::SystemAddress>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
RBXASSERT(0); // should never be streamed... REPLICATE_ONLY
|
|
}
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::SystemAddress>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
RBXASSERT(0); // should never be streamed... REPLICATE_ONLY
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::ContentId>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
ContentId value;
|
|
if (element->getValue(value))
|
|
setValue(instance, value);
|
|
}
|
|
}
|
|
template<>
|
|
void RBX::Reflection::TypedPropertyDescriptor<RBX::ContentId>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
element->setValue(ContentId(getValue(instance)));
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<RBX::ContentId>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(RBX::ContentId) + getValue(instance).toString().size();
|
|
}
|
|
|
|
template<>
|
|
bool RBX::Reflection::TypedPropertyDescriptor<ContentId>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
template<>
|
|
std::string RBX::Reflection::TypedPropertyDescriptor<ContentId>::getStringValue(const DescribedBase* instance) const{
|
|
return StringConverter<ContentId>::convertToString(getValue(instance));
|
|
}
|
|
template<>
|
|
bool RBX::Reflection::TypedPropertyDescriptor<ContentId>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
ContentId value;
|
|
if (StringConverter<ContentId>::convertToValue(text, value))
|
|
{
|
|
setValue(instance, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// BinaryString
|
|
template<>
|
|
const Type& Type::getSingleton<BinaryString>()
|
|
{
|
|
static TType<RBX::BinaryString> type("BinaryString");
|
|
return type;
|
|
}
|
|
|
|
template<>
|
|
void TypedPropertyDescriptor<BinaryString>::readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const
|
|
{
|
|
if (!element->isXsiNil())
|
|
{
|
|
std::string text;
|
|
if (element->getValue(text))
|
|
{
|
|
std::ostringstream result;
|
|
base64<char> decoder;
|
|
int state = 0;
|
|
std::ostreambuf_iterator<char> out(result);
|
|
decoder.get(text.begin(), text.end(), out, state);
|
|
|
|
BinaryString value(result.str());
|
|
setValue(instance, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void TypedPropertyDescriptor<BinaryString>::writeValue(const DescribedBase* instance, XmlElement* element) const
|
|
{
|
|
BinaryString value = getValue(instance);
|
|
|
|
std::string result;
|
|
base64<char>::encode(value.value().c_str(), value.value().length(), result, base64<>::lf());
|
|
|
|
element->setValue(result);
|
|
}
|
|
|
|
template<>
|
|
BinaryString& Variant::convert<BinaryString>(void)
|
|
{
|
|
return genericConvert<BinaryString>();
|
|
}
|
|
|
|
template<>
|
|
int TypedPropertyDescriptor<BinaryString>::getDataSize(const DescribedBase* instance) const
|
|
{
|
|
return sizeof(BinaryString) + getValue(instance).value().length();
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<BinaryString>::hasStringValue() const {
|
|
return true;
|
|
}
|
|
|
|
template<>
|
|
std::string TypedPropertyDescriptor<BinaryString>::getStringValue(const DescribedBase* instance) const{
|
|
return getValue(instance).value();
|
|
}
|
|
|
|
template<>
|
|
bool TypedPropertyDescriptor<BinaryString>::setStringValue(DescribedBase* instance, const std::string& text) const {
|
|
setValue(instance, BinaryString(text));
|
|
return true;
|
|
}
|
|
|
|
}} // namespaces
|
|
|