I have been trying to implement some convert structs for yaml-cpp for my own data types. Of which one is a class, not just a struct. The encode function works fine. But the decode function doesn't. I try to get a string from a yaml file and set the correct variable in the class.
template<>
struct convert<EngineNode*> {
static Node encode(EngineNode *rhs) {
Node node;
std::string type;
if(rhs->type == 0) {
type = "node";
} else if(rhs->type == 1) {
type = "scene";
} else if(rhs->type == 3) {
type = "particle";
}
node[type]["name"] = rhs->name;
node[type]["type"] = rhs->type;
node[type]["velocity"] = rhs->getVelocity();
node[type]["position"] = rhs->getPosition();
node[type]["rotation"] = rhs->getRotation();
for(unsigned i = 0; i < rhs->children.size(); i++) {
if(rhs->children[i]->type == SPRITE) {
node[type]["children"].push_back((SpriteNode*)rhs->children[i]);
} else {
node[type]["children"].push_back(rhs->children[i]);
}
}
return node;
}
static bool decode(const Node& node, EngineNode *rhs) {
if((!node["root"]["node"].IsDefined()) && (!node["root"]["scene"].IsDefined()) && (!node["particle"].IsDefined())) {
return false;
}
std::string type;
if(node["root"]["node"].IsDefined()) {
type = "node";
} else if(node["root"]["scene"].IsDefined()) {
type = "scene";
}
const Node n = node["root"][type];
rhs->name = n["name"].as<std::string>();
rhs->type = n["type"].as<int>();
rhs->setVelocity(n["velocity"].as<Velocity>());
rhs->setPosition(n["position"].as<Point>());
rhs->setRotation(n["rotation"].as<float>());
for(unsigned i = 0; i < n["children"].size(); i++) {
if(n["children"]["type"].as<int>() == SPRITE) {
rhs->addChild(n["children"].as<SpriteNode*>());
} else {
rhs->addChild(n["children"].as<EngineNode*>());
}
}
return true;
}
};
If you want to look at the full source its at github.
The problem is that it segfaults with the following error:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff73e3b5c in std::string::assign(std::string const&) () from /usr/lib/libstdc++.so.6
(gdb) bt
#0 0x00007ffff73e3b5c in std::string::assign(std::string const&) () from /usr/lib/libstdc++.so.6
#1 0x000000000040f590 in YAML::convert<EngineNode*>::decode (node=..., rhs=0x8) at src/yaml_config.cpp:90
#2 0x000000000040ef9f in YAML::as_if<EngineNode*, void>::operator() (this=0x7fffffffe4c0) at /usr/include/yaml-cpp/node/impl.h:119
#3 0x0000000000407a7d in YAML::Node::as<EngineNode*> (this=0x7fffffffe5c8) at /usr/include/yaml-cpp/node/impl.h:143
#4 0x00000000004074f9 in YamlConfig::readNode (this=0x8cf810, yaml_node=...) at src/yaml_config.cpp:172
#5 0x000000000040739a in YamlConfig::read (this=0x8cf810, path=...) at src/yaml_config.cpp:161
#6 0x0000000000404fa5 in GameScene::GameScene (this=0x8d62d0) at game/gamescene.cpp:16
#7 0x0000000000404205 in Main::initGameScene (this=0x61d2b0) at src/main.cpp:75
#8 0x0000000000404480 in main () at src/main.cpp:145
I can't figure out why that happens, it's probably not related to yaml-cpp at all but just my very limited understanding of templates and other stuff that's used here. (I only know very basic c++)
Any help would be appreciated,
Peter
rhspointer was at address0x8whendecodewas called. That's probably not a valid address. Are you surerhswas allocated correctly before passing it to the YAML decoder?newoperator, and that would then need to be passed back to the caller. I would rather have the caller allocate therhslike they do for theencodefunction.