Represents information about any of the following declarations in the Xc++ language:
typedef ptr<IObject> (__stdcall *CreateClassVariableFn)();
$struct+ ReflectedClass
{
$uint32 GetFlags() const { return m_flags; }
$bool IsStruct() const { return (m_flags & (1 << RCF_CLASS)) != 0; }
$bool IsModel() const { return (m_flags & (1 << RCF_MODEL)) != 0; }
$bool ReferencesModel() const { return (m_flags & (1 << RCF_REFERENCES_MODEL)) != 0; }
$bool IsAdt() const { return (m_flags & (1 << RCF_ADT)) != 0; }
$bool ReplicateOnDemand() const { return (m_flags & (1 << RCF_REPLICATE_ON_DEMAND)) != 0; }
$ConstStringZ GetName() const { return m_name; }
$ssize_t GetSize() const { return m_size; }
$ssize_t GetNumFields() const { return m_numFields; }
$const ReflectedField& GetField(ssize_t i) const { return m_fields[i]; }
// Equivalent to IsModel() || ReferencesModel()
bool HasOrRefsModel() const { return m_modelFields != nullptr; }
// May throw ReflectedClassNotFoundException
const ReflectedClass& GetModel(ssize_t& offset) const
{
cxAssert(m_modelFields);
if (m_numModelFields == 0)
{
offset = m_modelFields[0].m_offset;
return FindReflectedClass(m_modelFields[0].m_name);
}
else
{
offset = 0;
return *this;
}
}
$ssize_t GetNumModelFields() const { return m_numModelFields; }
$const ReflectedModelField& GetModelField(ssize_t i) const { return m_modelFields[i]; }
$ssize_t GetNumMethods() const { return m_numMethods; }
$const ReflectedClassMethod& GetMethod(ssize_t i) const { return m_methods[i]; }
$ssize_t GetNumIndirectInterfaces() const { return m_numIndirectInterfaces; }
$ssize_t GetNumDirectInterfaces() const { return m_numDirectInterfaces; }
$ssize_t GetNumInterfaces() const { return m_numIndirectInterfaces + m_numDirectInterfaces; }
$ConstStringZ GetInterfaceName(ssize_t i) const { return m_interfaces[i]; }
$bool CanCreate() const { return m_createFn != nullptr; }
$ptr<IObject> Create() const
{
if (m_createFn)
{
ptr<IObject> p = m_createFn();
RegisterGcObject(p);
return p;
}
else return null;
}
//////////////// State //////////////////
uint32 m_flags;
ConstStringZ m_name;
ssize_t m_size;
const octet_t* m_metaData;
const ReflectedField* m_fields;
ssize_t m_numFields;
const ReflectedModelField* m_modelFields;
ssize_t m_numModelFields;
const ReflectedDepField* m_depFields;
ssize_t m_numDepFields;
const ReflectedClassMethod* m_methods;
ssize_t m_numMethods;
ConstStringZ const* m_stringTable;
ConstStringZ const* m_interfaces;
ssize_t m_numIndirectInterfaces;
ssize_t m_numDirectInterfaces;
const IObject::FnTable* m_IObjectFnTable;
CreateClassVariableFn m_createFn;
TypeOps m_ops;
};
uint32 m_flags
Bit flags defined by EReflectedClassBits providing information about the class.
ConstStringZ m_name
The fully qualified name of the class represented as a pointer to a UTF-8 encoded null-terminated string (see ConstStringZ).
ssize_t m_size
The size of the class in bytes.
const octet_t* m_metaData
Pointer to metadata byte code on the class or null if no metadata declared.
const ReflectedField* m_fields
Pointer to an array of ReflectedField elements. These correspond to the member variables which are preceded with '$' in the class definition so they are reflected. For example:
$struct+ Point
{
$float32 x;
$float32 y;
};
ssize_t m_numFields
The number of elements in the m_fields array.
const ReflectedModelField* m_modelFields
Pointer to an array of ReflectedModelField elements. These correspond to the member variables which appear in a $model (either because the class itself is a $model or it embeds a model). Note that it includes members which have been dropped from the schema.
The order is determined by the order in which they were added to the $schema. This means that dropped fields are mixed together with existing fields. The index position is immutable in the sense of being unaffected by schema changes and this allows the index to be used for recording operations on the model independently of schema changes.
$model+ Point
{
float32 x;
float32 y;
};
ssize_t m_numModelFields
The number of elements in the m_modelFields array.
const ReflectedDepField* m_depFields
Pointer to an array of ReflectedDepField elements. These correspond to the $dep member variables. For example:
$struct+ X
{
$dep int32 x = f();
};
ssize_t m_numDepFields
The number of elements in the m_depFields array.
const ReflectedClassMethod* m_methods
Pointer to an array of ReflectedClassMethod elements. These correspond to the methods which are preceded with '$' in the class definition so they are reflected. For example:
$struct+ X
{
$void foo();
};
ssize_t m_numMethods
The number of elements in the m_methods array.
ConstStringZ const* m_stringTable
The address of an array of pointers to UTF-8 encoded null-terminated strings (see ConstStringZ), which is the string table associated with the byte code used to represent the types of the class members and the metadata on the class. May be null if no string table is required.
ConstStringZ const* m_interfaces
The address of an array of pointers to UTF-8 encoded null-terminated strings (see ConstStringZ), which are the fully qualified names of the interfaces implemented by the class or struct.
The set of direct interfaces is the set of interfaces listed after the 'isa' keyword.
The set of indirect interfaces is the set of strict superinterfaces of the direct interfaces.
The array of strings contains the indirect interfaces followed by the direct interfaces. The number of elements in the array equals (m_numIndirectInterfaces + m_numDirectInterfaces).
In the following example:
namespace ns
{
$interface+ Ix : ceda::IObject {};
$interface+ Iy : ceda::IObject {};
$struct+ X isa Ix, Iy {};
}
The following ReflectedClass members will be set to these values:
m_interfaces |
{ "ceda::IObject", "ns::Ix", "ns::Iy", } |
m_numIndirectInterfaces | 1 |
m_numDirectInterfaces | 2 |
ssize_t m_numIndirectInterfaces
Number of indirectly inherited interfaces
ssize_t m_numDirectInterfaces
Number of directly specified interfaces
const IObject::FnTable* m_IObjectFnTable
A $interface is implemented in terms of a member FnTable which is a vtable of function pointers.
If the class/struct either directly or indirectly implements interface IObject then m_IObjectFnTable is set to a pointer to the vtable for interface IObject.
CreateClassVariableFn m_createFn
If a default constructor exists then this points at a function which creates an object instance of the class/struct on the heap (see CreateClassVariableFn). It doesn't register the object with a CSpace
TypeOps m_ops
Records pointers to various functions to construct, destruct, copy construct, etc object instances (see TypeOps).
namespace ns
{
$model+ Point
{
float64 r;
float64 theta;
$dropped
{
float64 x;
float64 y;
float64 z;
}
$schema
{
1: +x +y // Release #1 : (x,y)
2: +z // Release #2,3 : (x,y,z)
4: -z // Release #4 : (x,y)
5: -x -y +r +theta // Release #5- : (r,theta)
}
$evolve
{
r(x,y) { r = sqrt(x*x + y*y); }
theta(x,y) { theta = atan2(y,x); }
}
};
}
namespace ns
{
struct Point
{
Point() : r(0),theta(0) {}
Point(ceda::float64 const& r_,ceda::float64 const& theta_) : r(r_),theta(theta_) {}
void Serialise(ceda::Archive&) const;
ceda::InputArchive Deserialise(ceda::InputArchive);
void EvictDgsNodes() const;
void VisitObjects(ceda::IObjectVisitor& _v) const;
void VisitPrefs(ceda::IPrefVisitor& _v) const;
bool operator<(Point const& _rhs) const
{
return (r < _rhs.r || (r == _rhs.r &&
(theta < _rhs.theta)));
}
bool operator==(Point const& _rhs) const
{
return r == _rhs.r &&
theta == _rhs.theta;
}
bool operator!=(Point const& _rhs) const { return !operator==(_rhs); }
bool operator<=(Point const& _rhs) const { return !_rhs.operator<(*this); }
bool operator>(Point const& _rhs) const { return _rhs.operator<(*this); }
bool operator>=(Point const& _rhs) const { return !operator<(_rhs); }
static void GetrPath(ceda::Path& _path) { ceda::octet_t* p=_path.InitLocalBuffer(1); p[0]=3; }
static ceda::Path GetrPath() { ceda::Path _path; GetrPath(_path); return _path; }
ceda::float64 const& _model__r() const { return r; }
ceda::float64& _model__r() { return r; }
ceda::float64 const& Getr() const { return r; }
ceda::float64& Writer() { return r; }
void Setr(ceda::float64 const& _v) { r = _v; }
static void GetthetaPath(ceda::Path& _path) { ceda::octet_t* p=_path.InitLocalBuffer(1); p[0]=4; }
static ceda::Path GetthetaPath() { ceda::Path _path; GetthetaPath(_path); return _path; }
ceda::float64 const& _model__theta() const { return theta; }
ceda::float64& _model__theta() { return theta; }
ceda::float64 const& Gettheta() const { return theta; }
ceda::float64& Writetheta() { return theta; }
void Settheta(ceda::float64 const& _v) { theta = _v; }
ceda::float64 r;
ceda::float64 theta;
};
ceda::ReflectedClass const& _GetReflected(Point const*);
ceda::TypeOps const& _GetTypeOps(Point const*);
template <typename BC>
struct Point_model_mixin : public BC
{
using typename BC::FinalClass;
bool operator<(Point_model_mixin const& _rhs) const {return _model_ < _rhs._model_;}
bool operator==(Point_model_mixin const& _rhs) const {return _model_ == _rhs._model_;}
bool operator!=(Point_model_mixin const& _rhs) const { return !operator==(_rhs); }
bool operator<=(Point_model_mixin const& _rhs) const { return !_rhs.operator<(*this); }
bool operator>(Point_model_mixin const& _rhs) const { return _rhs.operator<(*this); }
bool operator>=(Point_model_mixin const& _rhs) const { return !operator<(_rhs); }
void EvictDgsNodes() const {BC::EvictDgsNodes();_model_.EvictDgsNodes();}
void VisitObjects(ceda::IObjectVisitor& _v) const {BC::VisitObjects(_v); _model_.VisitObjects(_v);}
void VisitPrefs(ceda::IPrefVisitor& _v) const {BC::VisitPrefs(_v); _model_.VisitPrefs(_v);}
static void GetrPath(ceda::Path& _path) { ceda::octet_t* p=_path.InitLocalBuffer(1); p[0]=3; }
static ceda::Path GetrPath() { ceda::Path _path; GetrPath(_path); return _path; }
ceda::float64 const& _model__r() const { return _model_.r; }
ceda::float64& _model__r() { return _model_.r; }
ceda::float64 const& Getr() const { ceda::DataSourceReadBarrier(&_model_.r,ceda::null,"Point::_model_.r"); return _model_.r; }
ceda::float64& Writer() { ceda::DataSourceWriteBarrier(&_model_.r,ceda::null,"Point::_model_.r"); return _model_.r; }
void Setr(ceda::float64 const& _v) { ceda::DataSourceWriteBarrier(&_model_.r,ceda::null,"Point::_model_.r"); _model_.r = _v; }
static void GetthetaPath(ceda::Path& _path) { ceda::octet_t* p=_path.InitLocalBuffer(1); p[0]=4; }
static ceda::Path GetthetaPath() { ceda::Path _path; GetthetaPath(_path); return _path; }
ceda::float64 const& _model__theta() const { return _model_.theta; }
ceda::float64& _model__theta() { return _model_.theta; }
ceda::float64 const& Gettheta() const { ceda::DataSourceReadBarrier(&_model_.theta,ceda::null,"Point::_model_.theta"); return _model_.theta; }
ceda::float64& Writetheta() { ceda::DataSourceWriteBarrier(&_model_.theta,ceda::null,"Point::_model_.theta"); return _model_.theta; }
void Settheta(ceda::float64 const& _v) { ceda::DataSourceWriteBarrier(&_model_.theta,ceda::null,"Point::_model_.theta"); _model_.theta = _v; }
union
{
struct
{
operator ceda::float64 const&() const { return CONST_ATTRIB_CAST(Point_model_mixin,r)->Getr(); }
ceda::float64 const& read() const { return CONST_ATTRIB_CAST(Point_model_mixin,r)->Getr(); }
ceda::float64 & write() { return ATTRIB_CAST(Point_model_mixin,r)->Writer(); }
ceda::float64 const& model() const { return CONST_ATTRIB_CAST(Point_model_mixin,r)->_model__r(); }
ceda::float64& model() { return ATTRIB_CAST(Point_model_mixin,r)->_model__r(); }
ceda::Path path() const { return CONST_ATTRIB_CAST(Point_model_mixin,r)->GetrPath(); }
void operator=(ceda::float64 const& _v) { ATTRIB_CAST(Point_model_mixin,r)->Setr(_v); }
} r;
struct
{
operator ceda::float64 const&() const { return CONST_ATTRIB_CAST(Point_model_mixin,theta)->Gettheta(); }
ceda::float64 const& read() const { return CONST_ATTRIB_CAST(Point_model_mixin,theta)->Gettheta(); }
ceda::float64 & write() { return ATTRIB_CAST(Point_model_mixin,theta)->Writetheta(); }
ceda::float64 const& model() const { return CONST_ATTRIB_CAST(Point_model_mixin,theta)->_model__theta(); }
ceda::float64& model() { return ATTRIB_CAST(Point_model_mixin,theta)->_model__theta(); }
ceda::Path path() const { return CONST_ATTRIB_CAST(Point_model_mixin,theta)->GetthetaPath(); }
void operator=(ceda::float64 const& _v) { ATTRIB_CAST(Point_model_mixin,theta)->Settheta(_v); }
} theta;
};
typedef ns::Point model_type;
ns::Point const& model() const { return _model_; }
ns::Point& model() { return _model_; }
ns::Point const& read() const { ceda::DataSourceReadBarrier(static_cast<const typename BC::FinalClass*>(this), ceda::null,"Point"); return _model_; }
ns::Point & write() { ceda::DataSourceWriteBarrier(static_cast<typename BC::FinalClass*>(this), ceda::null,"Point"); return _model_; }
ns::Point _model_;
};
inline ceda::IObjectVisitor& operator<<(ceda::IObjectVisitor& _v,Point const& _x) { _x.VisitObjects(_v); return _v; }
inline ceda::IObjectVisitor& operator<<(ceda::IObjectVisitor& _v,Point const*) { return _v; }
inline ceda::IPrefVisitor& operator<<(ceda::IPrefVisitor& _v,Point const& _x) { _x.VisitPrefs(_v); return _v; }
inline ceda::Archive& operator<<(ceda::Archive& _ar,Point const& _x) { _x.Serialise(_ar); return _ar; }
inline ceda::InputArchive operator>>(ceda::InputArchive _ar,Point& _x) { return _x.Deserialise(_ar); }
inline ceda::xostream& operator<<(ceda::xostream& _os,Point const& _x)
{
_os << "Point(" << _x.r << ',' << _x.theta << ')';
return _os;
}
} //ns
namespace ceda
{
template<> struct TypeTraits<ns::Point>
{
static const bool is_exported = 1;
static const bool is_reflected = 1;
static const bool is_registered = 1;
static const ceda::ETypeTraitKind kind = ceda::TTK_model;
static const bool has_metadata = 0;
};
template<> struct ClassTypeTraits<ns::Point>
{
static const bool has_reflected_default_ctor = 1;
static const bool has_reflected_dtor = 1;
static const bool has_reflected_copy_ctor = 1;
static const bool has_reflected_equality = 1;
static const bool has_reflected_compare = 1;
static const bool has_reflected_write_xostream = 1;
static const bool has_reflected_serialise = 1;
static const bool has_reflected_visit_IObjects = 0;
static const bool has_reflected_visit_Prefs = 0;
static const bool implements_IObject = 0;
static const bool implements_IPersistable = 0;
static const bool can_serialise_model = 1;
static const bool has_model = 1;
static const bool using_model_base_class = 0;
};
} // namespace ceda
Generates the following code to register the ReflectedClass:
//### $model+ ns::Point
namespace ceda { XTarget* Ceda_Core_Object_exObject_GetXTarget(); }
namespace ceda { RSN Ceda_Core_Object_exObject_GetModelRsn(); }
namespace ns
{
ceda::ReflectedClass const& _GetReflected(Point const*)
{
static const ceda::octet_t Point_x[] =
{
0x0d
};
static const ceda::octet_t Point_y[] =
{
0x0d
};
static const ceda::octet_t Point_z[] =
{
0x0d
};
static const ceda::octet_t Point_r[] =
{
0x0d
};
static const ceda::octet_t Point_theta[] =
{
0x0d
};
static const ceda::ReflectedModelField Point_modelFields[] =
{
{ "x", -1, Point_x, 1, 5 },
{ "y", -1, Point_y, 1, 5 },
{ "z", -1, Point_z, 2, 4 },
{ "r", offsetof(Point,r), Point_r, 5, -1 },
{ "theta", offsetof(Point,theta), Point_theta, 5, -1 },
};
static const ceda::ReflectedClass Point_class =
{
2,
"ns::Point",
sizeof(Point),
0,
0,0,
Point_modelFields,5,
0,0,
0,0,
0,
0,0,0,
0,
0,
{
sizeof(Point),
(ceda::CompareVariableFn) (bool (*)(Point const*, Point const*)) ceda::VariableEqual<Point>,
(ceda::CompareVariableFn) (bool (*)(Point const*, Point const*)) ceda::VariableLess<Point>,
(ceda::PrintVariableFn) (void (*)(ceda::xostream&, Point const*)) ceda::PrintVariable<Point>,
(ceda::ConstructArrayFn) (void (*)( Point*, ceda::ssize_t, ceda::ssize_t)) ceda::ConstructArray<Point>,
(ceda::CopyConstructArrayFn) (void (*)(Point*, ceda::ssize_t, Point const*, ceda::ssize_t, ceda::ssize_t)) ceda::CopyConstructArray<Point>,
(ceda::AssignArrayFn) (void (*)(Point*, ceda::ssize_t, Point const*, ceda::ssize_t, ceda::ssize_t)) ceda::AssignArray<Point>,
(ceda::DestructArrayFn) (void (*)( Point*, ceda::ssize_t, ceda::ssize_t)) ceda::DestructArray<Point>,
(ceda::SerialiseArrayFn) (void (*)(ceda::Archive&, Point const*, ceda::ssize_t, ceda::ssize_t)) ceda::SerialiseArray<Point>,
(ceda::DeserialiseArrayFn) (ceda::InputArchive (*)(ceda::InputArchive, Point*, ceda::ssize_t, ceda::ssize_t)) ceda::DeserialiseArray<Point>,
0,
0,
(ceda::FindInArrayFn) (ceda::ssize_t (*)(Point const*, ceda::ssize_t, ceda::ssize_t, Point const*)) ceda::BinaryLowerBound<Point>,
(ceda::FindInArrayFn) (ceda::ssize_t (*)(Point const*, ceda::ssize_t, ceda::ssize_t, Point const*)) ceda::BinaryUpperBound<Point>
}
};
return Point_class;
}
ceda::TypeOps const& _GetTypeOps(Point const*)
{
return ceda::GetReflectedClass<Point>().m_ops;
}
void Point::EvictDgsNodes() const {ceda::DataSourceEvict(&r);ceda::DataSourceEvict(&theta);}
void Point::VisitObjects(ceda::IObjectVisitor& _v) const {}
void Point::VisitPrefs(ceda::IPrefVisitor& _v) const {}
void Point::Serialise(ceda::Archive& _ar) const
{
cxAssert(_ar.IsStoring());
_ar << this->r
<< this->theta;
}
ceda::InputArchive Point::Deserialise(ceda::InputArchive _ar)
{
ceda::RSN _rsn = ceda::Ceda_Core_Object_exObject_GetModelRsn();
struct EvolveCode
{
static void calc_r(ceda::float64& r,ceda::float64 const& x,ceda::float64 const& y) { r = sqrt(x*x + y*y); }
static void calc_theta(ceda::float64& theta,ceda::float64 const& x,ceda::float64 const& y) { theta = atan2(y,x); }
};
ceda::float64 x;
if (_rsn < 5) _ar = _ar >> x;
ceda::float64 y;
if (_rsn < 5) _ar = _ar >> y;
ceda::float64 z;
if (_rsn <= 1) { }
else if (_rsn < 4) _ar = _ar >> z;
if (_rsn <= 4) { EvolveCode::calc_r(r,x,y); }
else _ar = _ar >> this->r;
if (_rsn <= 4) { EvolveCode::calc_theta(theta,x,y); }
else _ar = _ar >> this->theta;
return _ar;
}
// Registration of $model+ ns::Point
void _Register_Point()
{
cxVerify(ceda::RegisterReflectedClass(&_GetReflected( (Point*) 0),ceda::Ceda_Core_Object_exObject_GetXTarget()) == ceda::NSE_OK);
}
} // ns