当前位置: 首页>>代码示例>>C++>>正文


C++ TfToken::IsEmpty方法代码示例

本文整理汇总了C++中TfToken::IsEmpty方法的典型用法代码示例。如果您正苦于以下问题:C++ TfToken::IsEmpty方法的具体用法?C++ TfToken::IsEmpty怎么用?C++ TfToken::IsEmpty使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在TfToken的用法示例。


在下文中一共展示了TfToken::IsEmpty方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: UsdGeomPrimvar

bool
UsdGeomPrimvarsAPI::HasPossiblyInheritedPrimvar(const TfToken &name) const
{
    TRACE_FUNCTION();

    UsdPrim prim = GetPrim();
    if (!prim) {
        TF_CODING_ERROR("HasPossiblyInheritedPrimvar called on invalid prim: %s", 
                        UsdDescribe(prim).c_str());
        return false;
    }
    UsdGeomPrimvar  pv = GetPrimvar(name);
    if (pv.HasAuthoredValue()){
        return true;
    }

    const TfToken attrName = UsdGeomPrimvar::_MakeNamespaced(name);
    if (attrName.IsEmpty()) {
        return false;
    }
    for (prim = prim.GetParent(); prim && !prim.IsPseudoRoot();
         prim = prim.GetParent()) {
        UsdAttribute attr = prim.GetAttribute(attrName);
        if (attr.HasAuthoredValue() && UsdGeomPrimvar::IsPrimvar(attr)) {
            // Only constant primvars can be inherited.
            // Non-constant interpolation blocks inheritance.
            return UsdGeomPrimvar(attr).GetInterpolation()
                == UsdGeomTokens->constant;
        }
    }
    return false;
}
开发者ID:PixarAnimationStudios,项目名称:USD,代码行数:32,代码来源:primvarsAPI.cpp

示例2: _DoAddNewPrimSpec

static
void _DoAddNewPrimSpec(
    const SdfLayerHandle& destLayer, const _SpecDataEntry& specData)
{
    // Need to determine whether this property is considered inert when
    // being initially created based on fields being copied in. This mimics
    // what's done in the SdfPrimSpec constructor.
    TfToken type;
    SdfSpecifier specifier = SdfSpecifierOver;
    for (const _FieldValuePair& fieldValue : specData.dataToCopy) {
        if (fieldValue.second.IsEmpty()) {
            continue;
        }

        if (fieldValue.first == SdfFieldKeys->TypeName) {
            type = fieldValue.second.Get<TfToken>();
        }
        else if (fieldValue.first == SdfFieldKeys->Specifier) {
            specifier = fieldValue.second.Get<SdfSpecifier>();
        }
    }

    const bool inert = (specifier == SdfSpecifierOver && type.IsEmpty());
    Sdf_ChildrenUtils<Sdf_PrimChildPolicy>::CreateSpec(
        destLayer, specData.dstPath, SdfSpecTypePrim,
        /* inert = */ inert);
}
开发者ID:lvxejay,项目名称:USD,代码行数:27,代码来源:copyUtils.cpp

示例3: GetValueTypeName

UsdGeomXformOp::UsdGeomXformOp(
    UsdPrim const& prim, 
    UsdGeomXformOp::Type const opType,
    UsdGeomXformOp::Precision const precision, 
    TfToken const &opSuffix,
    bool isInverseOp)
    : _opType(opType)
    , _isInverseOp(isInverseOp)
{
    // Determine the typeName of the xformOp attribute to be created.
    const SdfValueTypeName &typeName = GetValueTypeName(opType, precision);

    if (!typeName) { 
        TF_CODING_ERROR("Invalid xform-op: incompatible combination of "
            "opType (%s) and precision (%s).", 
            TfEnum::GetName(opType).c_str(),
            TfEnum::GetName(precision).c_str());
        return;
    } 

    TfToken attrName = UsdGeomXformOp::GetOpName(opType, opSuffix, 
        // isInverseOp is handled below
        /*isInverseOp*/ false);

    // attrName can never be empty.
    TF_VERIFY(!attrName.IsEmpty());

    // Create an  attribute in the xformOp: namespace with the
    // computed typeName.
    _attr = prim.CreateAttribute(attrName, typeName, /* custom */ false);

    // If a problem occurred, an error should already have been issued,
    // and _attr will be invalid, which is what we want
}
开发者ID:JT-a,项目名称:USD,代码行数:34,代码来源:xformOp.cpp

示例4: primvar

PXR_NAMESPACE_CLOSE_SCOPE

// ===================================================================== //
// Feel free to add custom code below this line. It will be preserved by
// the code generator.
//
// Just remember to wrap code in the appropriate delimiters:
// 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'.
// ===================================================================== //
// --(BEGIN CUSTOM CODE)--

PXR_NAMESPACE_OPEN_SCOPE

UsdGeomPrimvar 
UsdGeomPrimvarsAPI::CreatePrimvar(const TfToken& attrName,
                                const SdfValueTypeName &typeName,
                                const TfToken& interpolation,
                                int elementSize) const
{
    const UsdPrim &prim = GetPrim();

    UsdGeomPrimvar primvar(prim, attrName, typeName);

    if (primvar){
        if (!interpolation.IsEmpty())
            primvar.SetInterpolation(interpolation);
        if (elementSize > 0)
            primvar.SetElementSize(elementSize);
    }
    // otherwise, errors have already been issued
    return primvar;
}
开发者ID:PixarAnimationStudios,项目名称:USD,代码行数:32,代码来源:primvarsAPI.cpp

示例5: TfToken

TfToken 
UsdGeomCollectionAPI::_GetCollectionPropertyName(
    const TfToken &baseName /* =TfToken() */) const
{
    return TfToken(UsdGeomTokens->collection.GetString() + ":" + 
                   _name.GetString() + 
                   (baseName.IsEmpty() ? "" : (":" + baseName.GetString())));
}
开发者ID:JT-a,项目名称:USD,代码行数:8,代码来源:collectionAPI.cpp

示例6: GetPrim

bool
UsdGeomPrimvarsAPI::HasPrimvar(const TfToken &name) const
{
    TfToken primvarName = UsdGeomPrimvar::_MakeNamespaced(name, /* quiet */true);
    const UsdPrim &prim = GetPrim();
    if (!prim) {
        TF_CODING_ERROR("HasPrimvar called on invalid prim: %s", 
                        UsdDescribe(prim).c_str());
        return false;
    }
    return primvarName.IsEmpty() ? false : 
        UsdGeomPrimvar::IsPrimvar(prim.GetAttribute(primvarName));
}
开发者ID:PixarAnimationStudios,项目名称:USD,代码行数:13,代码来源:primvarsAPI.cpp

示例7: UsdSkelInbetweenShape

/* static */
UsdSkelInbetweenShape
UsdSkelInbetweenShape::_Create(const UsdPrim& prim, const TfToken& name)
{
    if(TF_VERIFY(prim)) {
        TfToken attrName = _MakeNamespaced(name);

        if(!attrName.IsEmpty()) {
            return UsdSkelInbetweenShape(
                prim.CreateAttribute(attrName, SdfValueTypeNames->Point3fArray,
                                     /*custom*/ false, SdfVariabilityUniform));
        }
    }
    return UsdSkelInbetweenShape();
}
开发者ID:PixarAnimationStudios,项目名称:USD,代码行数:15,代码来源:inbetweenShape.cpp

示例8: TfToken

/* static */
TfToken 
UsdGeomXformOp::GetOpName(
    const Type opType, 
    const TfToken &opSuffix,
    bool isInverseOp)
{
    TfToken opName = _MakeNamespaced(GetOpTypeToken(opType));

    if (!opSuffix.IsEmpty())
        opName = TfToken(opName.GetString() + ":" + opSuffix.GetString());

    if (isInverseOp)
        opName = TfToken(_tokens->invertPrefix.GetString() + opName.GetString());

    return opName;
}
开发者ID:JT-a,项目名称:USD,代码行数:17,代码来源:xformOp.cpp

示例9:

UsdGeomPrimvar::UsdGeomPrimvar(const UsdPrim& prim, 
                               const TfToken& baseName,
                               const SdfValueTypeName &typeName,
                               bool custom)
{
    TF_VERIFY(prim);

    TfToken attrName = _MakeNamespaced(baseName);

    if (!attrName.IsEmpty()){
        _attr = prim.CreateAttribute(attrName, typeName, custom);
    }
    // If a problem occurred, an error should already have been issued,
    // and _attr will be invalid, which is what we want

    _SetIdTargetRelName();
}
开发者ID:JT-a,项目名称:USD,代码行数:17,代码来源:primvar.cpp

示例10:

/* static */
bool 
PxrUsdKatanaUsdInPluginRegistry::_DoFindKind(
        const TfToken& kind,
        std::string* opName,
        const _KindRegistry& reg)
{
    // can cache this if it becomes an issue.
    for (TfToken currKind = kind;
            not currKind.IsEmpty();
            currKind = KindRegistry::GetBaseKind(currKind)) {
        if (TfMapLookup(reg, currKind, opName)) {
            return true;
        }
    }

    return false;
}
开发者ID:400dama,项目名称:USD,代码行数:18,代码来源:usdInPluginRegistry.cpp

示例11: while

/* static */
bool 
PxrUsdKatanaUsdInPluginRegistry::_DoFindKind(
        const TfToken& kind,
        std::string* opName,
        const _KindRegistry& reg)
{
    // can cache this if it becomes an issue.
    TfToken currKind = kind;
    while (!currKind.IsEmpty()) {
        if (TfMapLookup(reg, currKind, opName)) {
            return true;
        }
        if (KindRegistry::HasKind(currKind)) {
            currKind = KindRegistry::GetBaseKind(currKind);
        }
        else {
            FnLogWarn(TfStringPrintf("Unknown kind: '%s'", currKind.GetText()));
            return false;
        }
    }

    return false;
}
开发者ID:mplanck,项目名称:USD,代码行数:24,代码来源:usdInPluginRegistry.cpp

示例12: HdTextureResourceSharedPtr

HdTextureResourceSharedPtr
UsdImagingGL_GetTextureResource(UsdPrim const& usdPrim,
                                SdfPath const& usdPath,
                                UsdTimeCode time)
{
    if (!TF_VERIFY(usdPrim))
        return HdTextureResourceSharedPtr();
    if (!TF_VERIFY(usdPath != SdfPath()))
        return HdTextureResourceSharedPtr();

    UsdAttribute attr = _GetTextureResourceAttr(usdPrim, usdPath);
    SdfAssetPath asset;
    if (!TF_VERIFY(attr) || !TF_VERIFY(attr.Get(&asset, time))) {
        return HdTextureResourceSharedPtr();
    }

    HdTextureType textureType = HdTextureType::Uv;

    TfToken filePath = TfToken(asset.GetResolvedPath());
    // If the path can't be resolved, it's either an UDIM texture
    // or the texture doesn't exists and we can to exit early.
    if (filePath.IsEmpty()) {
        filePath = TfToken(asset.GetAssetPath());
        if (GlfIsSupportedUdimTexture(filePath)) {
            textureType = HdTextureType::Udim;
        } else {
            TF_DEBUG(USDIMAGING_TEXTURES).Msg(
                "File does not exist, returning nullptr");
            TF_WARN("Unable to find Texture '%s' with path '%s'.",
                    filePath.GetText(), usdPath.GetText());
            return {};
        }
    } else {
        if (GlfIsSupportedPtexTexture(filePath)) {
            textureType = HdTextureType::Ptex;
        }
    }

    GlfImage::ImageOriginLocation origin =
            UsdImagingGL_ComputeTextureOrigin(usdPrim);

    HdWrap wrapS = _GetWrapS(usdPrim, textureType);
    HdWrap wrapT = _GetWrapT(usdPrim, textureType);
    HdMinFilter minFilter = _GetMinFilter(usdPrim);
    HdMagFilter magFilter = _GetMagFilter(usdPrim);
    float memoryLimit = _GetMemoryLimit(usdPrim);

    TF_DEBUG(USDIMAGING_TEXTURES).Msg(
            "Loading texture: id(%s), type(%s)\n",
            usdPath.GetText(),
            textureType == HdTextureType::Uv ? "Uv" :
            textureType == HdTextureType::Ptex ? "Ptex" : "Udim");
 
    HdTextureResourceSharedPtr texResource;
    TfStopwatch timer;
    timer.Start();
    // Udim's can't be loaded through like other textures, because
    // we can't select the right factory based on the file type.
    // We also need to pass the layer context to the factory,
    // so each file gets resolved properly.
    GlfTextureHandleRefPtr texture;
    if (textureType == HdTextureType::Udim) {
        UdimTextureFactory factory(_FindLayerHandle(attr, time));
        texture = GlfTextureRegistry::GetInstance().GetTextureHandle(
            filePath, origin, &factory);
    } else {
        texture = GlfTextureRegistry::GetInstance().GetTextureHandle(
            filePath, origin);
    }

    texResource = HdTextureResourceSharedPtr(
        new HdStSimpleTextureResource(texture, textureType, wrapS, wrapT,
                                      minFilter, magFilter, memoryLimit));
    timer.Stop();

    TF_DEBUG(USDIMAGING_TEXTURES).Msg("    Load time: %.3f s\n", 
                                     timer.GetSeconds());

    return texResource;
}
开发者ID:rodeofx,项目名称:USD,代码行数:80,代码来源:textureUtils.cpp

示例13: self

void
Usd_PrimData::_ComposeAndCacheFlags(Usd_PrimDataConstPtr parent, 
                                    bool isMasterPrim)
{
    // Special-case the root (the only prim which has no parent) and
    // instancing masters.
    if (ARCH_UNLIKELY(not parent or isMasterPrim)) {
        _flags[Usd_PrimActiveFlag] = true;
        _flags[Usd_PrimLoadedFlag] = true;
        _flags[Usd_PrimModelFlag] = true;
        _flags[Usd_PrimGroupFlag] = true;
        _flags[Usd_PrimAbstractFlag] = false;
        _flags[Usd_PrimDefinedFlag] = true;
        _flags[Usd_PrimClipsFlag] = false;
        _flags[Usd_PrimInstanceFlag] = false;
        _flags[Usd_PrimMasterFlag] = isMasterPrim;
    } 
    else {
        // Compose and cache 'active'.
        UsdPrim self(Usd_PrimDataIPtr(this));
        bool active = true;
        self.GetMetadata(SdfFieldKeys->Active, &active);
        _flags[Usd_PrimActiveFlag] = active;

        // An active prim is loaded if it's loadable and in the load set, or
        // it's not loadable and its parent is loaded.
        _flags[Usd_PrimLoadedFlag] = active and
            (self.HasPayload() ?
             _stage->_GetPcpCache()->IsPayloadIncluded(_primIndex->GetPath()) :
             parent->IsLoaded());

        // According to Model hierarchy rules, only Model Groups may have Model
        // children (groups or otherwise).  So if our parent is not a Model
        // Group, then this prim cannot be a model (or a model group).
        // Otherwise we look up the kind metadata and consult the kind registry.
        _flags[Usd_PrimGroupFlag] = _flags[Usd_PrimModelFlag] = false;
        if (parent->IsGroup()) {
            static TfToken kindToken("kind");
            TfToken kind;
            self.GetMetadata(kindToken, &kind);

            // Use the kind registry to determine model/groupness.
            if (not kind.IsEmpty()) {
                _flags[Usd_PrimGroupFlag] = 
                    KindRegistry::IsA(kind, KindTokens->group);
                _flags[Usd_PrimModelFlag] = _flags[Usd_PrimGroupFlag] or
                    KindRegistry::IsA(kind, KindTokens->model);
            }
        }

        // Get specifier.
        SdfSpecifier specifier = GetSpecifier();

        // This prim is abstract if its parent is or if it's a class.
        _flags[Usd_PrimAbstractFlag] =
            parent->IsAbstract() or specifier == SdfSpecifierClass;

        // This prim is defined if its parent is defined and its specifier is
        // defining.
        const bool specifierIsDefining = SdfIsDefiningSpecifier(specifier);
        _flags[Usd_PrimDefinedFlag] =
            parent->IsDefined() and specifierIsDefining; 
        _flags[Usd_PrimHasDefiningSpecifierFlag] = specifierIsDefining;

        // The presence of clips that may affect attributes on this prim
        // is computed and set in UsdStage. Default to false.
        _flags[Usd_PrimClipsFlag] = false;

        // These flags indicate whether this prim is an instance or an
        // instance master.
        _flags[Usd_PrimInstanceFlag] = active and _primIndex->IsInstanceable();
        _flags[Usd_PrimMasterFlag] = parent->IsInMaster();
    }
}
开发者ID:400dama,项目名称:USD,代码行数:74,代码来源:primData.cpp

示例14: _WalkGraph

// Walk the shader graph and emit nodes in topological order
// to avoid forward-references.
static
void _WalkGraph(UsdShadeShader const & shadeNode, 
               HdMaterialNetwork *materialNetwork,
               const TfTokenVector &shaderSourceTypes)
{
    // Store the path of the node
    HdMaterialNode node;
    node.path = shadeNode.GetPath();
    if (!TF_VERIFY(node.path != SdfPath::EmptyPath())) {
        return;
    }
    // If this node has already been found via another path, we do
    // not need to add it again.
    for (HdMaterialNode const& existingNode: materialNetwork->nodes) {
        if (existingNode.path == node.path) {
            return;
        }
    }

    // Visit the inputs of this node to ensure they are emitted first.
    const std::vector<UsdShadeInput> shadeNodeInputs = shadeNode.GetInputs();
    for (UsdShadeInput const& input: shadeNodeInputs) {
        // Check if this input is a connection and if so follow the path
        UsdShadeConnectableAPI source;
        TfToken sourceName;
        UsdShadeAttributeType sourceType;
        if (UsdShadeConnectableAPI::GetConnectedSource(input, 
                &source, &sourceName, &sourceType)) {
            // When we find a connection to a shading node output,
            // walk the upstream shading node.  Do not do this for
            // other sources (ex: a connection to a material
            // public interface parameter), since they are not
            // part of the shading node graph.
            if (sourceType == UsdShadeAttributeType::Output) {
                UsdShadeShader connectedNode(source);
                _WalkGraph(connectedNode, materialNetwork, shaderSourceTypes);
            }
        }
    }

    // Extract the identifier of the node
    TfToken id;
    if (!shadeNode.GetShaderId(&id)) {
        for (auto &sourceType : shaderSourceTypes) {
            if (SdrShaderNodeConstPtr n = 
                    shadeNode.GetShaderNodeForSourceType(sourceType)) {
                id = n->GetIdentifier();
                break;
            }
        }
    }

    if (!id.IsEmpty()) {
        node.identifier = id;

        // If a node is recognizable, we will try to extract the primvar 
        // names that is using since this can help render delegates 
        // optimize what what is needed from a prim when making data 
        // accessible for renderers.
        _ExtractPrimvarsFromNode(shadeNode, node, materialNetwork);
    } else {
        TF_WARN("UsdShade Shader without an id: %s.", node.path.GetText());
        node.identifier = TfToken("PbsNetworkMaterialStandIn_2");
    }

    // Add the parameters and the relationships of this node
    VtValue value;
    for (UsdShadeInput const& input: shadeNodeInputs) {
        // Check if this input is a connection and if so follow the path
        UsdShadeConnectableAPI source;
        TfToken sourceName;
        UsdShadeAttributeType sourceType;
        if (UsdShadeConnectableAPI::GetConnectedSource(input,
            &source, &sourceName, &sourceType)) {
            if (sourceType == UsdShadeAttributeType::Output) {
                // Store the relationship
                HdMaterialRelationship relationship;
                relationship.outputId = shadeNode.GetPath();
                relationship.outputName = input.GetBaseName();
                relationship.inputId = source.GetPath();
                relationship.inputName = sourceName;
                materialNetwork->relationships.push_back(relationship);
            } else if (sourceType == UsdShadeAttributeType::Input) {
                // Connected to an input on the public interface.
                // The source is not a node in the shader network, so
                // pull the value and pass it in as a parameter.
                if (UsdShadeInput connectedInput =
                    source.GetInput(sourceName)) {
                    if (connectedInput.Get(&value)) {
                        node.parameters[input.GetBaseName()] = value;
                    }
                }
            }
        } else {
            // Parameters detected, let's store it
            if (input.Get(&value)) {
                node.parameters[input.GetBaseName()] = value;
            }
//.........这里部分代码省略.........
开发者ID:PixarAnimationStudios,项目名称:USD,代码行数:101,代码来源:materialAdapter.cpp

示例15: ID

HdTextureResource::ID
UsdImagingGL_GetTextureResourceID(UsdPrim const& usdPrim,
                                  SdfPath const& usdPath,
                                  UsdTimeCode time,
                                  size_t salt)
{
    if (!TF_VERIFY(usdPrim)) {
        return HdTextureResource::ID(-1);
    }
    if (!TF_VERIFY(usdPath != SdfPath())) {
        return HdTextureResource::ID(-1);
    }

    // If the texture name attribute doesn't exist, it might be badly specified
    // in scene data.
    UsdAttribute attr = _GetTextureResourceAttr(usdPrim, usdPath);

    SdfAssetPath asset;
    if (!attr || !attr.Get(&asset, time)) {
        TF_WARN("Unable to find texture attribute <%s> in scene data",
                usdPath.GetText());
        return HdTextureResource::ID(-1);
    }

    HdTextureType textureType = HdTextureType::Uv;
    TfToken filePath = TfToken(asset.GetResolvedPath());

    if (!filePath.IsEmpty()) {
        // If the resolved path contains a correct path, then we are 
        // dealing with a ptex or uv textures.
        if (GlfIsSupportedPtexTexture(filePath)) {
            textureType = HdTextureType::Ptex;
        } else {
            textureType = HdTextureType::Uv;
        }
    } else {
        // If the path couldn't be resolved, then it might be a Udim as they 
        // contain special characters in the path to identify them <Udim>.
        // Another option is that the path is just wrong and it can not be
        // resolved.
        filePath = TfToken(asset.GetAssetPath());
        if (GlfIsSupportedUdimTexture(filePath)) {
            const GlfContextCaps& caps = GlfContextCaps::GetInstance();
            if (!UsdImaging_UdimTilesExist(filePath, caps.maxArrayTextureLayers,
                _FindLayerHandle(attr, time))) {
                TF_WARN("Unable to find Texture '%s' with path '%s'. Fallback "
                        "textures are not supported for udim",
                        filePath.GetText(), usdPath.GetText());
                return HdTextureResource::ID(-1);
            }
            if (!caps.arrayTexturesEnabled) {
                TF_WARN("OpenGL context does not support array textures, "
                        "skipping UDIM Texture %s with path %s.",
                        filePath.GetText(), usdPath.GetText());
                return HdTextureResource::ID(-1);
            }
            textureType = HdTextureType::Udim;
        } else if (GlfIsSupportedPtexTexture(filePath)) {
            TF_WARN("Unable to find Texture '%s' with path '%s'. Fallback "
                    "textures are not supported for ptex",
                    filePath.GetText(), usdPath.GetText());
            return HdTextureResource::ID(-1);
        } else {
            TF_WARN("Unable to find Texture '%s' with path '%s'. A black "
                    "texture will be substituted in its place.",
                    filePath.GetText(), usdPath.GetText());
            return HdTextureResource::ID(-1);
        }
    }

    GlfImage::ImageOriginLocation origin =
            UsdImagingGL_ComputeTextureOrigin(usdPrim);

    // Hash on the texture filename.
    size_t hash = asset.GetHash();

    // Hash in wrapping and filtering metadata.
    HdWrap wrapS = _GetWrapS(usdPrim, textureType);
    HdWrap wrapT = _GetWrapT(usdPrim, textureType);
    HdMinFilter minFilter = _GetMinFilter(usdPrim);
    HdMagFilter magFilter = _GetMagFilter(usdPrim);
    float memoryLimit = _GetMemoryLimit(usdPrim);

    boost::hash_combine(hash, origin);
    boost::hash_combine(hash, wrapS);
    boost::hash_combine(hash, wrapT);
    boost::hash_combine(hash, minFilter);
    boost::hash_combine(hash, magFilter);
    boost::hash_combine(hash, memoryLimit);

    // Salt the result to prevent collisions in non-shared imaging.
    // Note that the salt is ignored for fallback texture hashes above.
    boost::hash_combine(hash, salt);

    return HdTextureResource::ID(hash);
}
开发者ID:rodeofx,项目名称:USD,代码行数:96,代码来源:textureUtils.cpp


注:本文中的TfToken::IsEmpty方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。