3.4. 公开 C++ 处理类型
处理类型表示旨在向 Daslang 公开 C++ 类型的机制。
处理类型是通过从 TypeAnnotation 派生自定义类型注释并将该注释的实例添加到所需的模块来创建的。例如:
template <typename VecT, int RowC>
class MatrixAnnotation : public TypeAnnotation {
...
typedef MatrixAnnotation<float4,4> float4x4_ann;
Module_Math() : Module("math") {
...
addAnnotation(make_smart<float4x4_ann>());
3.4.1. TypeAnnotation
TypeAnnotation
包含一组用于描述类型属性的虚拟方法,以及用于实现特定功能的模拟节点的方法。
canAot
返回true,如果类型可以出现在 AOT:
virtual bool canAot(das_set<Structure *> &) const
canCopy
, canMove
和 canClone
允许复制、移动或克隆类型:
virtual bool canMove() const
virtual bool canCopy() const
virtual bool canClone() const
isPod
和 isRawPod
指定类型是 plain old data 还是 plain old data (不带指针的普通旧数据):
virtual bool isPod() const
virtual bool isRawPod() const
isRefType
指定类型 ABI,即它是通过引用还是按值传递:
virtual bool isRefType() const
isLocal
允许创建该类型的局部变量:
virtual bool isLocal() const
canNew
, canDelete
和 canDeletePtr
指定是否允许对类型执行 NEW 和 DELETE作,以及是否可以删除指向该类型的指针:
virtual bool canNew() const
virtual bool canDelete() const
virtual bool canDeletePtr() const
needDelete
指定自动生成的终结器是否要删除此类型:
virtual bool needDelete() const
isIndexable
指定是否允许该类型的索引作 []
virtual bool isIndexable ( const TypeDeclPtr & ) const
isIterable
指定类型是否可以作为 for 循环的源:
virtual bool isIterable ( ) const
isShareable
指定是否可以将类型的全局变量标记为 shared:
virtual bool isShareable ( ) const
isSmart
指定指向该类型的指针是否显示为smart_ptr:
virtual bool isSmart() const
canSubstitute
查询该类型是否允许 LSP,即该类型可以向下转换:
virtual bool canSubstitute ( TypeAnnotation * /* passType */ ) const
getSmartAnnotationCloneFunction
返回 :=
运算符替换的克隆函数名称:
virtual string getSmartAnnotationCloneFunction () const { return ""; }
getSizeOf
和 getAlignOf
分别返回类型的大小和对齐方式:
virtual size_t getSizeOf() const
virtual size_t getAlignOf() const
makeFieldType
和 ``makeSafeFieldType``返回指定字段的类型 (如果未找到该字段,则返回 null):
virtual TypeDeclPtr makeFieldType ( const string & ) const
virtual TypeDeclPtr makeSafeFieldType ( const string & ) const
makeIndexType
返回给定索引表达式的 []
运算符的类型(如果不支持,则返回 null):
virtual TypeDeclPtr makeIndexType ( const ExpressionPtr & /*src*/, const ExpressionPtr & /*idx*/ ) const
makeIteratorType
返回用作 for 循环源时可迭代变量的类型(如果不支持,则返回 null):
virtual TypeDeclPtr makeIteratorType ( const ExpressionPtr & /*src*/ ) const
aotPreVisitGetField
, aotPreVisitGetFieldPtr
, aotVisitGetField
, 和 aotVisitGetFieldPtr
为字段和指针字段取消引用生成特定的 AOT 前缀和后缀:
virtual void aotPreVisitGetField ( TextWriter &, const string & )
virtual void aotPreVisitGetFieldPtr ( TextWriter &, const string & )
virtual void aotVisitGetField ( TextWriter & ss, const string & fieldName )
virtual void aotVisitGetFieldPtr ( TextWriter & ss, const string & fieldName )
有许多 simulate...
例程为不同的场景提供特定的仿真节点:
virtual SimNode * simulateDelete ( Context &, const LineInfo &, SimNode *, uint32_t ) const
virtual SimNode * simulateDeletePtr ( Context &, const LineInfo &, SimNode *, uint32_t ) const
virtual SimNode * simulateCopy ( Context &, const LineInfo &, SimNode *, SimNode * ) const
virtual SimNode * simulateClone ( Context &, const LineInfo &, SimNode *, SimNode * ) const
virtual SimNode * simulateRef2Value ( Context &, const LineInfo &, SimNode * ) const
virtual SimNode * simulateGetNew ( Context &, const LineInfo & ) const
virtual SimNode * simulateGetAt ( Context &, const LineInfo &, const TypeDeclPtr &,
const ExpressionPtr &, const ExpressionPtr &, uint32_t ) const
virtual SimNode * simulateGetAtR2V ( Context &, const LineInfo &, const TypeDeclPtr &,
const ExpressionPtr &, const ExpressionPtr &, uint32_t ) const
virtual SimNode * simulateGetIterator ( Context &, const LineInfo &, const ExpressionPtr & ) const
walk
提供自定义数据遍历功能,以允许对类型进行检查和二进制序列化:
virtual void walk ( DataWalker &, void * )
3.4.2. ManagedStructureAnnotation
ManagedStructureAnnotation
是一个帮助程序类型注释模板,旨在简化大多数 C++ 类的绑定。
让我们回顾一下以下示例:
struct Object {
das::float3 pos;
das::float3 vel;
__forceinline float speed() { return sqrt(vel.x*vel.x + vel.y*vel.y + vel.z*vel.z); }
};
为了绑定它,我们从 ManagedStructureAnnotation
继承,提供一个名称,并注册字段和属性:
struct ObjectStructureTypeAnnotation : ManagedStructureAnnotation <Object> {
ObjectStructureTypeAnnotation(ModuleLibrary & ml) : ManagedStructureAnnotation ("Object",ml) {
...
addField
和 addProperty
用于相应地添加字段和属性。
字段注册为 ref 值。
属性注册的偏移量为 -1,并按值返回:
ObjectStructureTypeAnnotation(ModuleLibrary & ml) : ManagedStructureAnnotation ("Object",ml) {
addField<DAS_BIND_MANAGED_FIELD(pos)>("position","pos");
addField<DAS_BIND_MANAGED_FIELD(vel)>("velocity","vel");
addProperty<DAS_BIND_MANAGED_PROP(speed)>("speed","speed");
之后,我们注册一个类型工厂并向模块添加类型注释:
MAKE_TYPE_FACTORY(Object, Object)
addAnnotation(make_smart<ObjectStructureTypeAnnotation>(lib));
addFieldEx
允许注册自定义偏移量或类型:
addFieldEx ( "flags", "flags", offsetof(MakeFieldDecl, flags), makeMakeFieldDeclFlags() );
这样,一种类型的字段可以注册为另一种类型。
Managed structure annotation 会自动为公开的字段实现 walk
。
3.4.3. DummyTypeAnnotation
当某个类型需要暴露给 Daslang 时,会出现 DummyTypeAnnotation
,但不允许任何内容或作。
这样,该类型可以是其他结构的一部分,并传递给需要它的 C++ 函数。
虚拟类型注释构造函数采用 Daslang 类型名称、C++ 类型名称、其大小和对齐方式:
DummyTypeAnnotation(const string & name, const string & cppName, size_t sz, size_t al)
由于 TypeAnnotation
是一个强 Daslang 类型,DummyTypeAnnotation
允许在 Daslang 中 gluing 代码,而不暴露 C++ 类型的细节。
请考虑以下示例:
send_unit_to(get_unit(“Ally”), get_unit_pos(get_unit(“Enemy”)))
get_unit
的结果直接传递给 send_unit_to
,而 Daslang 不知道任何关于单位类型的信息(除了它存在)。
3.4.4. ManagedVectorAnnotation
ManagedVectorAnnotation
用于将标准库向量公开给 Daslang。
在大多数情况下,不需要集成,并且 vector 注释会自动添加到模块中,这些模块会以任何形式注册与 vector 相关的任何内容。
向量与以下 4 个函数一起注册,类似于 Daslang 数组的函数:
push(vec, value)
pop(vec)
clear(vec)
resize(vec, newSize)
Vectors 还暴露了字段 length
,它返回 vector 的当前大小。
托管向量注释会自动实现 walk
,类似于 Daslang 数组。
3.4.5. ManagedValueAnnotation
ManagedValueAnnotation
旨在公开 C++ POD 类型,这些类型按值传递。
它期望为该类型实现 cast 机制。