0

I'm testing out YAML to see if it would be a good fit for a data storage format for a game engine. I've created this sample YAML file:

---
ShaderProperties:
    EntryPoint                      : UnlitHomogenousVS
    Profile                         : vs_4_0
    Model                           : HLSL_4
    Uniforms:
        - name                      : gTint
          type                      : kShaderUniformTypeFloat4
          defaultValue              : 1.0f, 1.0f, 1.0f, 1.0f
          constantBuffer            : cbObjectProperties
          constantBufferOffset      : 0
          usage                     : Property
    Samplers:
    ConstantBuffers:
        - name                      : cbObjectProperties
          register                  : 2
          size                      : 16
          type                      : kShaderTypeVertex
    Attributes:
        - name                      : position
          type                      : kShaderAttributeTypeFloat4
          usage                     : kShaderAttributeUsagePosition
        - name                      : color
          type                      : kShaderAttributeTypeFloat4
          usage                     : kShaderAttributeUsageColor0
ShaderText:  >
    //--
    // UnlitHomogenous.vs
    //
    // This vertex shader will color geometry with only a homogenous transform.
    //--

    //--
    // VertexInput
    //--
    struct VertexInput
    {
        float4 position : POSITION;
        float4 color    : COLOR;
    };

    //--
    // VertexOutput
    //--
    struct VertexOutput
    {
        float4 position : SV_POSITION;
        float4 color    : COLOR;
    };

    //--
    // Global Variables
    //--

    cbuffer cbObjectProperties : register(b2)
    {
        float4 gTint = float4( 1.0f, 1.0f, 1.0f, 1.0f );
    };

    //--
    // Main Function
    //--
    VertexOutput UnlitHomogenousVS( VertexInput input )
    {
        VertexOutput output = (VertexOutput)0;

        output.position = input.position * gTint;
        output.color = input.color;

        return output;
    }
...

Now, this file loads and seems to parse fine, but when I try to read in the node "EntryPoint" I get a valid node returned, but with an undefined node type, where I was expecting a scalar.

Here is the code that I'm using to read in the node.

YAML::Node root = YAML::LoadFile( filepathString );

if( root.IsNull() )
{
    return Failure_FileNotFound;
}

YAML::Node shaderProperties = root[ "ShaderProperties" ];
if( shaderProperties.IsNull() )
{
    return Failure_MalformedData;
}

YAML::Node& entryPointNode = shaderProperties[ "EntryPoint" ];
if( entryPointNode.IsNull() || !entryPointNode.IsDefined() )
{
    TC_SHADER_IMPORTER_LOG_ERROR( TCString( "Failed to parse shader: ") + mCurrentName + TCString( ", no entry point was found" ) );
    return Failure_MalformedData;
}
output->mEntryPointName = entryPointNode.as<std::string>().c_str();

Is there anything obvious that I'm missing? I am able to successfully load this file, so I assume that the YAML is valid. If I take out the check for IsDefined() and just try to cast the node to a string, I get a bad conversion.

Thanks for any and all help!

EDIT:

The issue was that I was using \t tabs between the tag name, (EntryPoint), and the colon instead of ' 's to tab.

  • What version of yaml-cpp are you using, and what compiler/OS? When I compile your test code with either 0.5.3 or HEAD on OS X with clang, it gives the error `error: non-const lvalue reference to type 'YAML::Node' cannot bind to a temporary of type 'YAML::Node'` on your definition of `entryPointNode`. And when I change it to a value (not a reference), the code seems to work as intended (successfully reads the string value). – Jesse Beder May 15 '16 at 03:42
  • I'm building on Windows 7, with Visual C++ compiler: Version 18.00.21005.1 for x86. As far as the version, I just did a clone of the repository a week a so ago, so I'm not too far off HEAD, if at all. I just did a full clean/rebuild to make sure the libraries are compiling fine, and I'm not getting any compiler errors. Also I've removed the unnecessary references, and it still is returning an undefined node. – OvertCurrent May 15 '16 at 19:00
  • @JesseBeder So I found the issue, the problem was that on my local file the line for the EntryPoint: was using \t tabs between the tag name and the colon, but when formatting the text for StackOverflow, it used spaces instead. Is that apart of the YAML spec that I missed, or is it a quirk of yaml-cpp? – OvertCurrent May 15 '16 at 19:14
  • I believe it's part of the spec. You can check it by trying the reference implementation at http://ben-kiki.org/ypaste/ – Jesse Beder May 16 '16 at 03:10
  • @JesseBeder it seems to parse the YAML just fine, and from what I can tell the wiki: https://en.wikipedia.org/wiki/YAML says that the indentation format doesn't matter as long as children nodes are indented. Can you verify? Just remove the spaces between the EntryPointName and the colon and replace that with \t tabs and the reader seems to generate the tree well enough. – OvertCurrent May 18 '16 at 03:49
  • Hmm, I think you're right; this looks like a bug in yaml-cpp. Can you file an issue? BTW, this isn't considered "indentation", and indentation *does* matter - it should be spaces - but between a key and the colon, it can be any whitespace, http://www.yaml.org/spec/1.2/spec.html#ns-s-implicit-yaml-key(c) – Jesse Beder May 20 '16 at 03:54
  • I'll file it when I'm back to my computer. I did have another issue though. When grabbing the raw text block at the end of the file, I'm not getting new lines returned in the scalar, unless their are multiple consecutive new lines. Is that intended? – OvertCurrent May 22 '16 at 03:59
  • Yes; check out > vs | in the YAML documentation. – Jesse Beder May 22 '16 at 17:47

0 Answers0