.. _handles: ========================== 公开 C++ 处理类型 ========================== 处理类型表示旨在向 Daslang 公开 C++ 类型的机制。 处理类型是通过从 TypeAnnotation 派生自定义类型注释并将该注释的实例添加到所需的模块来创建的。例如:: template class MatrixAnnotation : public TypeAnnotation { ... typedef MatrixAnnotation float4x4_ann; Module_Math() : Module("math") { ... addAnnotation(make_smart()); -------------- TypeAnnotation -------------- ``TypeAnnotation`` 包含一组用于描述类型属性的虚拟方法,以及用于实现特定功能的模拟节点的方法。 ``canAot`` 返回true,如果类型可以出现在 :ref:`AOT `:: virtual bool canAot(das_set &) 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 * ) -------------------------- 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 { ObjectStructureTypeAnnotation(ModuleLibrary & ml) : ManagedStructureAnnotation ("Object",ml) { ... ``addField`` 和 ``addProperty`` 用于相应地添加字段和属性。 字段注册为 ref 值。 属性注册的偏移量为 -1,并按值返回:: ObjectStructureTypeAnnotation(ModuleLibrary & ml) : ManagedStructureAnnotation ("Object",ml) { addField("position","pos"); addField("velocity","vel"); addProperty("speed","speed"); 之后,我们注册一个类型工厂并向模块添加类型注释:: MAKE_TYPE_FACTORY(Object, Object) addAnnotation(make_smart(lib)); ``addFieldEx`` 允许注册自定义偏移量或类型:: addFieldEx ( "flags", "flags", offsetof(MakeFieldDecl, flags), makeMakeFieldDeclFlags() ); 这样,一种类型的字段可以注册为另一种类型。 Managed structure annotation 会自动为公开的字段实现 ``walk`` 。 ------------------- 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 不知道任何关于单位类型的信息(除了它存在)。 ----------------------- ManagedVectorAnnotation ----------------------- ``ManagedVectorAnnotation`` 用于将标准库向量公开给 Daslang。 在大多数情况下,不需要集成,并且 vector 注释会自动添加到模块中,这些模块会以任何形式注册与 vector 相关的任何内容。 向量与以下 4 个函数一起注册,类似于 Daslang 数组的函数:: push(vec, value) pop(vec) clear(vec) resize(vec, newSize) Vectors 还暴露了字段 ``length`` ,它返回 vector 的当前大小。 托管向量注释会自动实现 ``walk``,类似于 Daslang 数组。 ---------------------- ManagedValueAnnotation ---------------------- ``ManagedValueAnnotation`` 旨在公开 C++ POD 类型,这些类型按值传递。 它期望为该类型实现 :ref:`cast ` 机制。