text: /**
   * The MIT License (MIT)
   *
   * Copyright (c) 2012-2018 DragonBones team and other contributors
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy of
   * this software and associated documentation files (the "Software"), to deal in
   * the Software without restriction, including without limitation the rights to
   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
   * the Software, and to permit persons to whom the Software is furnished to do so,
   * subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in all
   * copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
   * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
   * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
   * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   */
  #ifndef DRAGONBONES_BONE_H
  #define DRAGONBONES_BONE_H
  
  #include "TransformObject.h"
  #include "../model/ArmatureData.h"
  #include "../animation/AnimationState.h"
  
  DRAGONBONES_NAMESPACE_BEGIN
  /**
   * - Bone is one of the most important logical units in the armature animation system,
   * and is responsible for the realization of translate, rotation, scaling in the animations.
   * A armature can contain multiple bones.
   * @see dragonBones.BoneData
   * @see dragonBones.Armature
   * @see dragonBones.Slot
   * @version DragonBones 3.0
   * @language en_US
   */
  /**
   * - 骨骼在骨骼动画体系中是最重要的逻辑单元之一，负责动画中的平移、旋转、缩放的实现。
   * 一个骨架中可以包含多个骨骼。
   * @see dragonBones.BoneData
   * @see dragonBones.Armature
   * @see dragonBones.Slot
   * @version DragonBones 3.0
   * @language zh_CN
   */
  class Bone final : public TransformObject
  {
      BIND_CLASS_TYPE_A(Bone);
  
  public:
      /**
       * - The offset mode.
       * @see #offset
       * @version DragonBones 5.5
       * @language en_US
       */
      /**
       * - 偏移模式。
       * @see #offset
       * @version DragonBones 5.5
       * @language zh_CN
       */
      OffsetMode offsetMode;
      /**
       * @internal
       */
      Transform animationPose;
      /**
       * @internal
       */
      bool _transformDirty;
      /**
       * @internal
       */
      bool _childrenTransformDirty;
      /**
       * @internal
       */
      bool _hasConstraint;
      /**
       * @internal
       */
      BlendState _blendState;
      /**
       * @internal
       */
      const BoneData* _boneData;
      /**
       * @internal
       */
      std::vector<int>* _cachedFrameIndices;
  
  protected:
      bool _localDirty;
      bool _visible;
      int _cachedFrameIndex;
      /**
       * @private
       */
      Bone* _parent;
  
  protected:
      void _onClear() override;
      void _updateGlobalTransformMatrix(bool isCache);
  
  public:
      /**
       * @internal
       */
      void init(const BoneData* boneData, Armature* armatureValue);
      /**
       * @internal
       */
      void update(int cacheFrameIndex);
      /**
       * @internal
       */
      void updateByConstraint();
      /**
       * - Forces the bone to update the transform in the next frame.
       * When the bone is not animated or its animation state is finished, the bone will not continue to update,
       * and when the skeleton must be updated for some reason, the method needs to be called explicitly.
       * @example
       * TypeScript style, for reference only.
       * <pre>
       *     let bone = armature.getBone("arm");
       *     bone.offset.scaleX = 2.0;
       *     bone.invalidUpdate();
       * </pre>
       * @version DragonBones 3.0
       * @language en_US
       */
      /**
       * - 强制骨骼在下一帧更新变换。
       * 当该骨骼没有动画状态或其动画状态播放完成时，骨骼将不在继续更新，而此时由于某些原因必须更新骨骼时，则需要显式调用该方法。
       * @example
       * TypeScript 风格，仅供参考。
       * <pre>
       *     let bone = armature.getBone("arm");
       *     bone.offset.scaleX = 2.0;
       *     bone.invalidUpdate();
       * </pre>
       * @version DragonBones 3.0
       * @language zh_CN
       */
      inline void invalidUpdate() { _transformDirty = true; }
      /**
       * - Check whether the bone contains a specific bone.
       * @see dragonBones.Bone
       * @version DragonBones 3.0
       * @language en_US
       */
      /**
       * - 检查该骨骼是否包含特定的骨骼。
       * @see dragonBones.Bone
       * @version DragonBones 3.0
       * @language zh_CN
       */
      bool contains(const Bone* value) const;
      /**
       * - The bone data.
       * @version DragonBones 4.5
       * @language en_US
       */
      /**
       * - 骨骼数据。
       * @version DragonBones 4.5
       * @language zh_CN
       */
      inline const BoneData* getBoneData() const { return _boneData; }
      /**
       * - The visible of all slots in the bone.
       * @default true
       * @see dragonBones.Slot#visible
       * @version DragonBones 3.0
       * @language en_US
       */
      /**
       * - 此骨骼所有插槽的可见。
       * @default true
       * @see dragonBones.Slot#visible
       * @version DragonBones 3.0
       * @language zh_CN
       */
      inline bool getVisible() const { return _visible; }
      void setVisible(bool value);
      /**
       * - The bone name.
       * @version DragonBones 3.0
       * @language en_US
       */
      /**
       * - 骨骼名称。
       * @version DragonBones 3.0
       * @language zh_CN
       */
      inline std::string_view getName() const { return _boneData->name; }
      /**
       * - The parent bone to which it belongs.
       * @version DragonBones 3.0
       * @language en_US
       */
      /**
       * - 所属的父骨骼。
       * @version DragonBones 3.0
       * @language zh_CN
       */
      inline Bone* getParent() const { return _parent; }
  
  public:  // For WebAssembly.
      inline int getOffsetMode() const { return (int)offsetMode; }
      inline void setOffsetMode(int value) { offsetMode = (OffsetMode)value; }
  };
  
  DRAGONBONES_NAMESPACE_END
  #endif  // DRAGONBONES_BONE_H
  