/* * This function checks to see if the current YAML::Node contains only keys * that we care about. Unknown keys should cause PLFS to spit out an error * rather than being silently ignored. * This is a bit nasty as it drills through the entire tree recursively * but it will catch any unknowns in one pass * * Returns true if all keys are valid * * Returns false if unknown keys are found and sets bad_key to an error * message that points out what key is invalid */ bool is_valid_node(const YAML::Node node, string** bad_key) { set<string> key_list(Valid_Keys, Valid_Keys + (sizeof(Valid_Keys) / sizeof(Valid_Keys[0])) ); string key; string err = "\nBad key or value in plfsrc: "; if(node.IsMap()) { for(YAML::const_iterator it=node.begin();it!=node.end();it++) { if(!it->first.IsNull()) { key = it->first.as<string>(); if(!is_valid_node(node[key],bad_key)) // recurse return false; if(key_list.find(key) == key_list.end()) { err.append(key); *bad_key = new string (err); return false; // this is an unknown key } } } } else if (node.IsSequence()) { for(unsigned int i = 0; i < node.size(); i++) if(!is_valid_node(node[i],bad_key)) // recurse return false; } else if (node.IsScalar() && node.as<string>().find(" ") != string::npos) { err.append(node.as<string>()); *bad_key = new string (err); return false; // no spaces in values allowed } return true; // all keys are valid }
YAML::Node MergeYaml( const YAML::Node& a, const YAML::Node& b ) { // Short circuit cases if( a.IsNull() ) { return b; } else if( b.IsNull() ) { return a; } if( !a.IsMap() || !b.IsMap() ) { throw std::runtime_error( "Cannot merge non-map nodes." ); } YAML::Node node; CopyYaml( a, node ); YAML::Node::const_iterator iter; // Cycle through b and add all fields to node for( iter = b.begin(); iter != b.end(); iter++ ) { std::string key = iter->first.as<std::string>(); // If both a and b have a key we have to merge them if( node[key] ) { node[key] = MergeYaml( node[key], iter->second ); } // Otherwise we just add it else { node[key] = iter->second; } } return node; }
void Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Exception { foreach ( const QString& path, moduleConfigurationCandidates( Settings::instance()->debugMode(), m_name, configFileName ) ) { QFile configFile( path ); if ( configFile.exists() && configFile.open( QFile::ReadOnly | QFile::Text ) ) { QByteArray ba = configFile.readAll(); YAML::Node doc = YAML::Load( ba.constData() ); if ( doc.IsNull() ) { cDebug() << "Found empty module configuration" << path; // Special case: empty config files are valid, // but aren't a map. return; } if ( !doc.IsMap() ) { cWarning() << "Bad module configuration format" << path; return; } cDebug() << "Loaded module configuration" << path; m_configurationMap = CalamaresUtils::yamlMapToVariant( doc ).toMap(); m_emergency = m_maybe_emergency && m_configurationMap.contains( EMERGENCY ) && m_configurationMap[ EMERGENCY ].toBool(); return; } }
void RotoStrokeItemSerialization::decode(const YAML::Node& node) { if (!node.IsMap()) { throw YAML::InvalidNode(); } KnobTableItemSerialization::decode(node); if (node["SubStrokes"]) { YAML::Node strokesNode = node["SubStrokes"]; for (std::size_t i = 0; i < strokesNode.size(); ++i) { YAML::Node strokeN = strokesNode[i]; PointCurves p; p.x.reset(new CurveSerialization); p.y.reset(new CurveSerialization); p.pressure.reset(new CurveSerialization); p.x->decode(strokeN["x"]); p.y->decode(strokeN["y"]); p.pressure->decode(strokeN["pressure"]); _subStrokes.push_back(p); } } }
bool KnobSerialization::checkForValueNode(const YAML::Node& node, const std::string& nodeType) { if (!node[nodeType]) { return false; } // We need to figure out of the knob is multi-view and if multi-dimensional YAML::Node valueNode = node[nodeType]; _dataType = dataTypeFromString(nodeType); // If the "Value" is a map, this can be either a multi-view knob or a single-view // and single-dimensional knob with animation. // Check to find any of the keys of a single dimension map. If we find it, that means // this is not the multi-view map and that this is a single-dimensional knob if (!valueNode.IsMap()) { decodeValueNode("Main", valueNode); } else { if (valueNode["Curve"] || valueNode["pyMultiExpr"] || valueNode["pyExpr"] || valueNode["exprtk"] || valueNode["N"] || valueNode["T"] || valueNode["K"] || valueNode["D"] || valueNode["V"]) { decodeValueNode("Main", valueNode); } else { // Multi-view for (YAML::const_iterator it = valueNode.begin(); it != valueNode.end(); ++it) { decodeValueNode(it->first.as<std::string>(), it->second); } } } return true; }
bool YamlPath::get(YAML::Node root, YAML::Node& out) { size_t beginToken = 0, endToken = 0, pathSize = codedPath.size(); auto delimiter = MAP_DELIM; // First token must be a map key. while (endToken < pathSize) { if (!root.IsDefined()) { return false; // A node before the end of the path was mising, quit! } beginToken = endToken; endToken = pathSize; endToken = std::min(endToken, codedPath.find(SEQ_DELIM, beginToken)); endToken = std::min(endToken, codedPath.find(MAP_DELIM, beginToken)); if (delimiter == SEQ_DELIM) { int index = std::stoi(&codedPath[beginToken]); if (root.IsSequence()) { root.reset(root[index]); } else { return false; } } else if (delimiter == MAP_DELIM) { auto key = codedPath.substr(beginToken, endToken - beginToken); if (root.IsMap()) { root.reset(root[key]); } else { return false; } } else { return false; // Path is malformed, return null node. } delimiter = codedPath[endToken]; // Get next character as the delimiter. ++endToken; // Move past the delimiter. } // Success! Assign the result. out.reset(root); return true; }
// Incrementally load YAML static NEVER_INLINE void operator +=(YAML::Node& left, const YAML::Node& node) { if (node && !node.IsNull()) { if (node.IsMap()) { for (const auto& pair : node) { if (pair.first.IsScalar()) { auto&& lhs = left[pair.first.Scalar()]; lhs += pair.second; } else { // Exotic case (TODO: probably doesn't work) auto&& lhs = left[YAML::Clone(pair.first)]; lhs += pair.second; } } } else if (node.IsScalar() || node.IsSequence()) { // Scalars and sequences are replaced completely, but this may change in future. // This logic may be overwritten by custom demands of every specific cfg:: node. left = node; } } }
Map from_yaml(type_t<Map>, const YAML::Node& value) { if (!value.IsMap()) throw deserialize_error{"type must be a map but is " + yaml_type_name(value)}; Map ret{}; for (const auto& obj : value) { try { ret.emplace( yaml::deserialize<typename Map::key_type>(obj.first), yaml::deserialize<typename Map::mapped_type>(obj.second)); } catch (deserialize_error& ex) { std::string msg = "error when deserializing field " + obj.first.Scalar(); ex.add(msg.c_str()); throw; } } return ret; }
YAML::Node expandDefaults(const YAML::Node& node) { YAML::Node result = YAML::Clone(node); if (node.IsMap() && node["DEFAULT"]) { const YAML::Node& default_node = result["DEFAULT"]; for (auto field = result.begin(); field != result.end(); ++field) { std::string fieldname = field->first.as<std::string>(); if (fieldname != "DEFAULT") { result[fieldname] = applyDefaults(result[fieldname], default_node); } } } if (result.IsMap() || result.IsSequence()) { for (auto child = result.begin(); child != result.end(); ++child) { std::string child_name = child->first.as<std::string>(); result[child_name] = expandDefaults(child->second); } } return result; }
void Config::parseCommand(const YAML::Node& node, iCommandConfig& config) { //std::cerr << "Under active development!" << '\n'; //return; if(node.size() >= 1 && node.IsMap()) for (YAML::const_iterator iter=node.begin();iter!=node.end();++iter) { std::string key = iter->first.as<std::string>(); YAML::Node value = iter->second; Util::lowercase(key); //std::cout << key << std::endl; if(key == "command") { if(value.IsScalar()) { LOG(logger, DEBUG, "Proc: %s", value.as<std::string>().c_str()); config.command = Util::parseCommand(value.as<std::string>()); #if 0 // TODO: We need to take quotes from the user and send them all as // a single argument instead of multiple arguments. std::string cnfval = value.as<std::string>(); char* cmd = new char[cnfval.size() + 1]; cmd[cnfval.size()] = 0; memcpy(cmd, cnfval.c_str(), cnfval.size()); size_t size = 1; for(size_t i=0; i<cnfval.size(); i++) if(cmd[i] == ' ') size++; config.command = new char*[size+1]; config.command[size] = 0; config.command[0] = cmd; size_t csize = 0; for(size_t i=0; i<cnfval.size(); i++) { if(cmd[i] == ' ') { cmd[i] = 0; if(csize < size && (i + 1) < cnfval.size()) { config.command[++csize] = cmd+(unsigned int)i+1; } } } #endif } } else if( key == "enabled" ) { config.enabled = value.as<bool>(); } } //for(size_t i=0;config.command[i]; i++) //{ // std::cout << "==" << config.command[i] << '\n'; //} }
void Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Exception { QStringList configFilesByPriority; if ( CalamaresUtils::isAppDataDirOverridden() ) { configFilesByPriority.append( CalamaresUtils::appDataDir().absoluteFilePath( QString( "modules/%1" ).arg( configFileName ) ) ); } else { if ( Settings::instance()->debugMode() ) { configFilesByPriority.append( QDir( QDir::currentPath() ).absoluteFilePath( QString( "src/modules/%1/%2" ).arg( m_name ) .arg( configFileName ) ) ); } configFilesByPriority.append( QString( "/etc/calamares/modules/%1" ).arg( configFileName ) ); configFilesByPriority.append( CalamaresUtils::appDataDir().absoluteFilePath( QString( "modules/%2" ).arg( configFileName ) ) ); } foreach ( const QString& path, configFilesByPriority ) { QFile configFile( path ); if ( configFile.exists() && configFile.open( QFile::ReadOnly | QFile::Text ) ) { QByteArray ba = configFile.readAll(); YAML::Node doc = YAML::Load( ba.constData() ); if ( !doc.IsMap() ) { cLog() << Q_FUNC_INFO << "bad module configuration format" << path; return; } m_configurationMap = CalamaresUtils::yamlMapToVariant( doc ).toMap(); return; } else continue; }
static void tryDecodeInputsMap(const YAML::Node& node, const std::string& token, std::map<std::string, std::string>* container) { if (node[token]) { YAML::Node inputsNode = node[token]; if (inputsNode.IsMap()) { for (YAML::const_iterator it = inputsNode.begin(); it!=inputsNode.end(); ++it) { container->insert(std::make_pair(it->first.as<std::string>(), it->second.as<std::string>())); } } else { // When single input, just use the index as key container->insert(std::make_pair("0", inputsNode.as<std::string>())); } } }
TEST_F(OsgSceneryRepresentationTest, SerializationTests) { std::shared_ptr<SceneryRepresentation> scenery = std::make_shared<OsgSceneryRepresentation>("OsgScenery"); std::string fileName("OsgSceneryRepresentationTests/Torus.obj"); scenery->loadModel(fileName); YAML::Node node; ASSERT_NO_THROW(node = scenery->encode()); EXPECT_TRUE(node.IsMap()); std::shared_ptr<SceneryRepresentation> result = std::make_shared<OsgSceneryRepresentation>("OsgScenery"); ASSERT_NO_THROW(result->decode(node)); EXPECT_EQ("SurgSim::Graphics::OsgSceneryRepresentation", result->getClassName()); EXPECT_EQ(fileName, result->getModel()->getFileName()); }
YAML::Node applyDefaults(const YAML::Node& node, const YAML::Node& default_node) { YAML::Node result = YAML::Clone(node); if (!default_node.IsMap()) { std::cerr << default_node << std::endl; throw std::runtime_error("map node expected"); } for (auto field = default_node.begin(); field != default_node.end(); ++field) { std::string fieldname = field->first.as<std::string>(); if (!result[fieldname]) { result[fieldname] = YAML::Clone(field->second); } else if (field->second.IsMap()) { result[fieldname] = applyDefaults(result[fieldname], field->second); } } return result; }
Settings::Settings( const QString& settingsFilePath, bool debugMode, QObject* parent ) : QObject( parent ) , m_debug( debugMode ) , m_doChroot( true ) , m_promptInstall( false ) , m_disableCancel( false ) , m_disableCancelDuringExec( false ) { cDebug() << "Using Calamares settings file at" << settingsFilePath; QFile file( settingsFilePath ); if ( file.exists() && file.open( QFile::ReadOnly | QFile::Text ) ) { QByteArray ba = file.readAll(); try { YAML::Node config = YAML::Load( ba.constData() ); Q_ASSERT( config.IsMap() ); interpretModulesSearch( debugMode, CalamaresUtils::yamlToStringList( config[ "modules-search" ] ), m_modulesSearchPaths ); interpretInstances( config[ "instances" ], m_customModuleInstances ); interpretSequence( config[ "sequence" ], m_modulesSequence ); m_brandingComponentName = requireString( config, "branding" ); m_promptInstall = requireBool( config, "prompt-install", false ); m_doChroot = !requireBool( config, "dont-chroot", false ); m_isSetupMode = requireBool( config, "oem-setup", !m_doChroot ); m_disableCancel = requireBool( config, "disable-cancel", false ); m_disableCancelDuringExec = requireBool( config, "disable-cancel-during-exec", false ); } catch ( YAML::Exception& e ) { CalamaresUtils::explainYamlException( e, ba, file.fileName() ); } } else { cWarning() << "Cannot read settings file" << file.fileName(); } s_instance = this; }
bool BlockLoaderType::nodeToValue(const YAML::Node & node, BlockHandle * const block, schemer::ParseLog * const log) const { if(!node.IsMap() || !node["run"].IsScalar()) { return false; } build::BlockLoader loader; loader.load(node); BlockHandle startBlock, last; Tok tok(node["run"].Scalar(), SEP); for(Tok::const_iterator it = tok.begin(), end = tok.end(); it != end; ++it) { BlockHandle temp = loader.get(*it); if(!temp.get()) { log->logError(schemer::ParseLogErrorCode::REQUIRED_VALUE_MISSING, "Failed to find block " + *it); return false; } if(it == tok.begin()) startBlock = last = temp; else { last->connect(temp); last = temp; } } *block = startBlock; return true; }
XmlRpc::XmlRpcValue YamlToXml( const YAML::Node& node ) { XmlRpc::XmlRpcValue xml; if( node.IsNull() ) { return xml; } else if( node.IsSequence() ) { std::vector< std::string > contents = node.as< std::vector< std::string > >(); xml.setSize( contents.size() ); for( unsigned int i = 0; i < contents.size(); i++ ) { xml[i] = contents[i]; } } else if( node.IsScalar() ) { xml = node.as< std::string >(); } else if( node.IsMap() ) { YAML::Node::const_iterator iter; for( iter = node.begin(); iter != node.end(); iter++ ) { std::string name = iter->first.as<std::string>(); xml[ name ] = YamlToXml( iter->second ); } } else { std::cerr << "Invalid YAML node type." << std::endl; } return xml; }
int main(int argc, char** argv) { bool verbose = false; bool bytes = false; int opt; while ((opt = getopt(argc, argv, "vb")) != -1) { switch (opt) { case 'v': verbose = true; break; case 'b': bytes = true; break; default: /* '?' */ cerr << usage; return 1; } } if ( optind >= argc ) { cerr << usage; return 1; } const char* filename = argv[optind]; try { YAML::Node doc; if ( bytes ) { QFile f( filename ); if ( f.open( QFile::ReadOnly | QFile::Text ) ) doc = YAML::Load( f.readAll().constData() ); } else doc = YAML::LoadFile( filename ); if ( doc.IsNull() ) { // Special case: empty config files are valid, // but aren't a map. For the example configs, // this is still an error. cerr << "WARNING:" << filename << '\n'; cerr << "WARNING: empty YAML\n"; return 1; } if ( !doc.IsMap() ) { cerr << "WARNING:" << filename << '\n'; cerr << "WARNING: not-a-YAML-map (type=" << doc.Type() << ")\n"; return 1; } if ( verbose ) { cerr << "Keys:\n"; for ( auto i = doc.begin(); i != doc.end(); ++i ) cerr << i->first.as<std::string>() << '\n'; } } catch ( YAML::Exception& e ) { cerr << "WARNING:" << filename << '\n'; cerr << "WARNING: YAML parser error " << e.what() << '\n'; return 1; } return 0; }
void NodeSerialization::decode(const YAML::Node& node) { if (!node.IsMap()) { throw YAML::InvalidNode(); } _pluginID = node["PluginID"].as<std::string>(); if (node["PresetName"]) { _encodeType = eNodeSerializationTypePresets; // This is a presets or pyplug _presetsIdentifierLabel = node["PresetName"].as<std::string>(); if (node["PresetIcon"]) { _presetsIconFilePath = node["PresetIcon"].as<std::string>(); } if (node["PresetShortcutKey"]) { _presetShortcutSymbol = node["PresetShortcutKey"].as<int>(); } if (node["PresetShortcutModifiers"]) { _presetShortcutPresetModifiers = node["PresetShortcutModifiers"].as<int>(); } } if (node["Name"]) { _nodeScriptName = node["Name"].as<std::string>(); } if (node["Label"]) { _nodeLabel = node["Label"].as<std::string>(); } else { _nodeLabel = _nodeScriptName; } if (node["Version"]) { YAML::Node versionNode = node["Version"]; if (versionNode.size() != 2) { throw YAML::InvalidNode(); } _pluginMajorVersion = versionNode[0].as<int>(); _pluginMinorVersion = versionNode[1].as<int>(); } tryDecodeInputsMap(node, "Inputs", &_inputs); tryDecodeInputsMap(node, "Masks", &_masks); if (node["Params"]) { YAML::Node paramsNode = node["Params"]; for (std::size_t i = 0; i < paramsNode.size(); ++i) { KnobSerializationPtr s(new KnobSerialization); s->decode(paramsNode[i]); _knobsValues.push_back(s); } } if (node["UserPages"]) { YAML::Node pagesNode = node["UserPages"]; for (std::size_t i = 0; i < pagesNode.size(); ++i) { GroupKnobSerializationPtr s(new GroupKnobSerialization); s->decode(pagesNode[i]); _userPages.push_back(s); } } if (node["PagesOrder"]) { YAML::Node pagesOrder = node["PagesOrder"]; for (std::size_t i = 0; i < pagesOrder.size(); ++i) { _pagesIndexes.push_back(pagesOrder[i].as<std::string>()); } } if (node["Children"]) { YAML::Node childrenNode = node["Children"]; for (std::size_t i = 0; i < childrenNode.size(); ++i) { NodeSerializationPtr s(new NodeSerialization); s->decode(childrenNode[i]); _children.push_back(s); } } if (node["TableItems"]) { _tableModel.reset(new KnobItemsTableSerialization); _tableModel->decode(node["TableItems"]); } if (node["Preset"]) { _presetInstanceLabel = node["Preset"].as<std::string>(); } if (node["NewLayers"]) { YAML::Node layersNode = node["NewLayers"]; for (std::size_t i = 0; i < layersNode.size(); ++i) { ImagePlaneDescSerialization s; s.decode(layersNode[i]); _userComponents.push_back(s); } } if (node["Pos"]) { YAML::Node posNode = node["Pos"]; if (posNode.size() != 2) { throw YAML::InvalidNode(); } _nodePositionCoords[0] = posNode[0].as<double>(); _nodePositionCoords[1] = posNode[1].as<double>(); } if (node["Size"]) { YAML::Node sizeNode = node["Size"]; if (sizeNode.size() != 2) { throw YAML::InvalidNode(); } _nodeSize[0] = sizeNode[0].as<double>(); _nodeSize[1] = sizeNode[1].as<double>(); } if (node["Color"]) { YAML::Node colorNode = node["Color"]; if (colorNode.size() != 3) { throw YAML::InvalidNode(); } _nodeColor[0] = colorNode[0].as<double>(); _nodeColor[1] = colorNode[1].as<double>(); _nodeColor[2] = colorNode[2].as<double>(); } if (node["OverlayColor"]) { YAML::Node colorNode = node["OverlayColor"]; if (colorNode.size() != 3) { throw YAML::InvalidNode(); } _overlayColor[0] = colorNode[0].as<double>(); _overlayColor[1] = colorNode[1].as<double>(); _overlayColor[2] = colorNode[2].as<double>(); } if (node["ViewerParamsOrder"]) { YAML::Node viewerParamsOrderNode = node["ViewerParamsOrder"]; for (std::size_t i = 0; i < viewerParamsOrderNode.size(); ++i) { _viewerUIKnobsOrder.push_back(viewerParamsOrderNode[i].as<std::string>()); } } } // NodeSerialization::decode
Reflectable reflectable_from_yaml(const YAML::Node& value) { Reflectable refl{}; if (value.IsMap()) { ctti::reflect(refl, [&value](auto fi) { using field_type = typename decltype(fi)::type; try { const auto& query = value[fi.name()]; if (query) fi.get() = yaml::deserialize<field_type>(query); else fi.get() = yaml::deserialize<field_type>({}); } catch (deserialize_error& ex) { std::string msg = "error when deserializing field " + std::string(fi.name()); ex.add(msg.c_str()); throw; } }); } else if (value.IsSequence()) { if (value.size() > ctti::total_num_fields<Reflectable>()) { throw deserialize_error{"sequence size is greater than " "declared struct's field " "count"}; } ctti::reflect(refl, [&value, index = 0U](auto fi) mutable { using field_type = typename decltype(fi)::type; try { if (index < value.size()) fi.get() = yaml::deserialize<field_type>(value[index]); else fi.get() = yaml::deserialize<field_type>({}); ++index; } catch (deserialize_error& ex) { std::string msg = "error when deserializing element " + std::to_string(index); ex.add(msg.c_str()); throw; } }); } else { throw deserialize_error{"type must be a sequence or map but is " + yaml_type_name(value)}; } return refl; }
bool Model::Load (const std::string &filename) { #ifdef DEBUG debug.filename = filename; #endif /* DEBUG */ YAML::Node desc; std::ifstream file (MakePath ("models", filename), std::ifstream::in); if (!file.is_open ()) { (*logstream) << "Cannot open " << filename << std::endl; return false; } desc = YAML::Load (file); if (!desc.IsMap ()) { (*logstream) << "The model file " << filename << " has an invalid format." << std::endl; return false; } if (!desc["meshes"].IsSequence ()) { (*logstream) << filename << " has an invalid format." << std::endl; (*logstream) << desc["meshes"].Type () << std::endl; return false; } bbox.min = glm::vec3 (FLT_MAX, FLT_MAX, FLT_MAX); bbox.max = glm::vec3 (-FLT_MAX, -FLT_MAX, -FLT_MAX); GLuint num_meshes = 0; for (const YAML::Node &node : desc["meshes"]) { std::string filename = MakePath ("models", node["filename"].as<std::string> ()); const Material &material = r->geometry.GetMaterial (node["material"].as<std::string> ()); Mesh mesh (*this); mesh.Load (filename, &material, bbox.min, bbox.max, node["shadows"].as<bool> (true)); if (mesh.IsTransparent ()) { if (mesh.IsTessellated ()) { (*logstream) << "Mesh " << filename << " has an invalid type." << std::endl; return false; } else { transparent.emplace_back (std::move (mesh)); num_meshes++; } } else { if (mesh.IsTessellated ()) { patches.emplace_back (std::move (mesh)); num_meshes++; } else { meshes.emplace_back (std::move (mesh)); num_meshes++; } } } if (num_meshes < 1) { (*logstream) << filename << " contains no meshes." << std::endl; return false; } { glm::vec3 bboxvertex[8]; bboxvertex[0] = glm::vec3 (bbox.min.x, bbox.min.y, bbox.min.z); bboxvertex[1] = glm::vec3 (bbox.max.x, bbox.min.y, bbox.min.z); bboxvertex[2] = glm::vec3 (bbox.max.x, bbox.max.y, bbox.min.z); bboxvertex[3] = glm::vec3 (bbox.min.x, bbox.max.y, bbox.min.z); bboxvertex[4] = glm::vec3 (bbox.min.x, bbox.min.y, bbox.max.z); bboxvertex[5] = glm::vec3 (bbox.max.x, bbox.min.y, bbox.max.z); bboxvertex[6] = glm::vec3 (bbox.max.x, bbox.max.y, bbox.max.z); bboxvertex[7] = glm::vec3 (bbox.min.x, bbox.max.y, bbox.max.z); bbox.buffer.Data (8 * sizeof (glm::vec3), &bboxvertex[0], GL_STATIC_DRAW); glm::detail::tvec3<GLubyte> bboxindices[12]; bboxindices[0] = glm::detail::tvec3<GLubyte> (0, 1, 2); bboxindices[1] = glm::detail::tvec3<GLubyte> (2, 3, 0); bboxindices[2] = glm::detail::tvec3<GLubyte> (1, 5, 6); bboxindices[3] = glm::detail::tvec3<GLubyte> (1, 6, 2); bboxindices[4] = glm::detail::tvec3<GLubyte> (5, 4, 6); bboxindices[5] = glm::detail::tvec3<GLubyte> (4, 7, 6); bboxindices[6] = glm::detail::tvec3<GLubyte> (4, 0, 3); bboxindices[7] = glm::detail::tvec3<GLubyte> (4, 3, 7); bboxindices[8] = glm::detail::tvec3<GLubyte> (3, 2, 6); bboxindices[9] = glm::detail::tvec3<GLubyte> (3, 6, 7); bboxindices[10] = glm::detail::tvec3<GLubyte> (0, 4, 1); bboxindices[11] = glm::detail::tvec3<GLubyte> (4, 5, 1); bbox.indices.Data (12 * sizeof (glm::detail::tvec3<GLubyte>), &bboxindices[0], GL_STATIC_DRAW); } bbox.array.VertexAttribOffset (bbox.buffer, 0, 3, GL_FLOAT, GL_FALSE, 0, 0); bbox.array.EnableVertexAttrib (0); // TODO: Calculate a decent bounding sphere. // This is a very rough approximation. { bsphere.center = 0.5f * (bbox.min + bbox.max); bsphere.radius = glm::distance (bbox.min, bsphere.center); } return true; }
void KnobSerialization::decodeValueNode(const std::string& viewName, const YAML::Node& node) { int nDims = 1; bool isMainNodeSequence = node.IsSequence() && _dataType != eSerializationValueVariantTypeTable; if (isMainNodeSequence) { nDims = node.size(); } PerDimensionValueSerializationVec& dimVec = _values[viewName]; initValuesVec(this, &dimVec, nDims); for (int i = 0; i < nDims; ++i) { YAML::Node dimNode = isMainNodeSequence ? node[i] : node; if (!dimNode.IsMap()) { // This is a value decodeValueFromNode(dimNode, dimVec[i]._value, _dataType); dimVec[i]._serializeValue = true; } else { // !isMap // Always look for an animation curve if (dimNode["Curve"]) { // Curve dimVec[i]._animationCurve.decode(dimNode["Curve"]); } // Look for a link or expression if (dimNode["pyMultiExpr"]) { dimVec[i]._expression = dimNode["pyMultiExpr"].as<std::string>(); dimVec[i]._expresionHasReturnVariable = true; dimVec[i]._expressionLanguage = kKnobSerializationExpressionLanguagePython; } else if (dimNode["pyExpr"]) { dimVec[i]._expression = dimNode["pyExpr"].as<std::string>(); dimVec[i]._expressionLanguage = kKnobSerializationExpressionLanguagePython; } else if (dimNode["exprtk"]) { dimVec[i]._expression = dimNode["exprtk"].as<std::string>(); dimVec[i]._expressionLanguage = kKnobSerializationExpressionLanguageExprtk; } else { // This is most likely a regular slavr/master link bool gotLink = false; if (dimNode["N"]) { dimVec[i]._slaveMasterLink.masterNodeName = dimNode["N"].as<std::string>(); gotLink = true; } if (dimNode["T"]) { dimVec[i]._slaveMasterLink.masterTableItemName = dimNode["T"].as<std::string>(); gotLink = true; } if (dimNode["K"]) { dimVec[i]._slaveMasterLink.masterKnobName = dimNode["K"].as<std::string>(); gotLink = true; } if (dimNode["D"]) { dimVec[i]._slaveMasterLink.masterDimensionName = dimNode["D"].as<std::string>(); gotLink = true; } if (dimNode["V"]) { dimVec[i]._slaveMasterLink.masterViewName = dimNode["V"].as<std::string>(); gotLink = true; } dimVec[i]._slaveMasterLink.hasLink = gotLink; } } // isMap } } //decodeValueNode
broker_config::broker_config(const YAML::Node &config) { try { if (!config.IsMap()) { throw config_error("The configuration is not a YAML map"); } // load client address and port if (config["clients"] && config["clients"].IsMap()) { if (config["clients"]["address"] && config["clients"]["address"].IsScalar()) { client_address_ = config["clients"]["address"].as<std::string>(); } // no throw... can be omitted if (config["clients"]["port"] && config["clients"]["port"].IsScalar()) { client_port_ = config["clients"]["port"].as<uint16_t>(); } // no throw... can be omitted } // load worker address and port if (config["workers"] && config["workers"].IsMap()) { if (config["workers"]["address"] && config["workers"]["address"].IsScalar()) { worker_address_ = config["workers"]["address"].as<std::string>(); } // no throw... can be omitted if (config["workers"]["port"] && config["workers"]["port"].IsScalar()) { worker_port_ = config["workers"]["port"].as<uint16_t>(); } // no throw... can be omitted if (config["workers"]["max_liveness"] && config["workers"]["max_liveness"].IsScalar()) { max_worker_liveness_ = config["workers"]["max_liveness"].as<size_t>(); } // no throw... can be omitted if (config["workers"]["max_request_failures"] && config["workers"]["max_request_failures"].IsScalar()) { max_request_failures_ = config["workers"]["max_request_failures"].as<size_t>(); } // no throw... can be omitted if (config["workers"]["ping_interval"] && config["workers"]["ping_interval"].IsScalar()) { worker_ping_interval_ = std::chrono::milliseconds(config["workers"]["ping_interval"].as<size_t>()); } // no throw... can be omitted } // load monitor address and port if (config["monitor"] && config["monitor"].IsMap()) { if (config["monitor"]["address"] && config["monitor"]["address"].IsScalar()) { monitor_address_ = config["monitor"]["address"].as<std::string>(); } // no throw... can be omitted if (config["monitor"]["port"] && config["monitor"]["port"].IsScalar()) { monitor_port_ = config["monitor"]["port"].as<uint16_t>(); } // no throw... can be omitted } // load frontend address and port if (config["notifier"] && config["notifier"].IsMap()) { if (config["notifier"]["address"] && config["notifier"]["address"].IsScalar()) { notifier_config_.address = config["notifier"]["address"].as<std::string>(); } // no throw... can be omitted if (config["notifier"]["port"] && config["notifier"]["port"].IsScalar()) { notifier_config_.port = config["notifier"]["port"].as<uint16_t>(); } // no throw... can be omitted if (config["notifier"]["username"] && config["notifier"]["username"].IsScalar()) { notifier_config_.username = config["notifier"]["username"].as<std::string>(); } // no throw... can be omitted if (config["notifier"]["password"] && config["notifier"]["password"].IsScalar()) { notifier_config_.password = config["notifier"]["password"].as<std::string>(); } // no throw... can be omitted } // no throw... can be omitted // load logger if (config["logger"] && config["logger"].IsMap()) { if (config["logger"]["file"] && config["logger"]["file"].IsScalar()) { fs::path tmp = config["logger"]["file"].as<std::string>(); log_config_.log_basename = tmp.filename().string(); log_config_.log_path = tmp.parent_path().string(); } // no throw... can be omitted if (config["logger"]["level"] && config["logger"]["level"].IsScalar()) { log_config_.log_level = config["logger"]["level"].as<std::string>(); } // no throw... can be omitted if (config["logger"]["max-size"] && config["logger"]["max-size"].IsScalar()) { log_config_.log_file_size = config["logger"]["max-size"].as<size_t>(); } // no throw... can be omitted if (config["logger"]["rotations"] && config["logger"]["rotations"].IsScalar()) { log_config_.log_files_count = config["logger"]["rotations"].as<size_t>(); } // no throw... can be omitted } // no throw... can be omitted } catch (YAML::Exception &ex) { throw config_error("Default broker configuration was not loaded: " + std::string(ex.what())); } }
void KnobSerialization::decode(const YAML::Node& node) { if (!node.IsMap()) { return; } // Set the flag to true if the user use this object directly to encode after _mustSerialize = true; _scriptName = node["Name"].as<std::string>(); // Check for nodes bool dataTypeSet = false; static const std::string typesToCheck[6] = { kKnobSerializationDataTypeKeyBool, kKnobSerializationDataTypeKeyInt, kKnobSerializationDataTypeKeyDouble, kKnobSerializationDataTypeKeyString, kKnobSerializationDataTypeKeyTable, kKnobSerializationDataTypeKeyNone }; for (int i = 0; i < 6; ++i) { if (checkForValueNode(node, typesToCheck[i])) { dataTypeSet = true; break; } } for (int i = 0; i < 6; ++i) { if (checkForDefaultValueNode(node, typesToCheck[i], dataTypeSet)) { break; } } if (node["ParametricCurves"]) { YAML::Node curveNode = node["ParametricCurves"]; ParametricExtraData *data = getOrCreateExtraData<ParametricExtraData>(_extraData); if (curveNode.IsMap()) { for (YAML::const_iterator it = curveNode.begin(); it!=curveNode.end(); ++it) { std::string viewName = it->first.as<std::string>(); YAML::Node curvesViewNode = it->second; std::list<CurveSerialization>& curvesList = data->parametricCurves[viewName]; for (std::size_t i = 0; i < curvesViewNode.size(); ++i) { CurveSerialization s; s.decode(curvesViewNode[i]); curvesList.push_back(s); } } } else { std::list<CurveSerialization>& curvesList = data->parametricCurves["Main"]; for (std::size_t i = 0; i < curveNode.size(); ++i) { CurveSerialization s; s.decode(curveNode[i]); curvesList.push_back(s); } } } if (node["TextAnim"]) { YAML::Node curveNode = node["TextAnim"]; TextExtraData *data = getOrCreateExtraData<TextExtraData>(_extraData); if (curveNode.IsMap()) { // Multi-view for (YAML::const_iterator it = curveNode.begin(); it!=curveNode.end(); ++it) { std::string viewName = it->first.as<std::string>(); YAML::Node keysForViewNode = it->second; std::map<double, std::string>& keysForView = data->keyframes[viewName]; // If type = 0 we expect a int, otherwise a string int type = 0; std::pair<double, std::string> p; for (std::size_t i = 0; i < keysForViewNode.size(); ++i) { if (type == 0) { p.first = keysForViewNode[i].as<double>(); type = 1; } else if (type == 1) { type = 0; p.second = keysForViewNode[i].as<std::string>(); keysForView.insert(p); } } } } else { // If type = 0 we expect a int, otherwise a string std::map<double, std::string>& keysForView = data->keyframes["Main"]; int type = 0; std::pair<double, std::string> p; for (std::size_t i = 0; i < curveNode.size(); ++i) { if (type == 0) { p.first = curveNode[i].as<double>(); type = 1; } else if (type == 1) { type = 0; p.second = curveNode[i].as<std::string>(); keysForView.insert(p); } } } } if (node["FontColor"]) { YAML::Node n = node["FontColor"]; if (n.size() != 3) { throw YAML::InvalidNode(); } TextExtraData *data = getOrCreateExtraData<TextExtraData>(_extraData); data->fontColor[0] = n[0].as<double>(); data->fontColor[1] = n[1].as<double>(); data->fontColor[2] = n[2].as<double>(); } if (node["FontSize"]) { TextExtraData *data = getOrCreateExtraData<TextExtraData>(_extraData); data->fontSize = node["FontSize"].as<int>(); } if (node["Font"]) { TextExtraData *data = getOrCreateExtraData<TextExtraData>(_extraData); data->fontFamily = node["Font"].as<std::string>(); } if (node["NDims"]) { // This is a user knob _isUserKnob = true; _typeName = node["TypeName"].as<std::string>(); _dimension = node["NDims"].as<int>(); if (node["Label"]) { _label = node["Label"].as<std::string>(); } else { _label = _scriptName; } if (node["Hint"]) { _tooltip = node["Hint"].as<std::string>(); } if (node["Persistent"]) { _isPersistent = node["Persistent"].as<bool>(); } else { _isPersistent = true; } if (node["UncheckedIcon"]) { _iconFilePath[0] = node["UncheckedIcon"].as<std::string>(); } if (node["CheckedIcon"]) { _iconFilePath[1] = node["CheckedIcon"].as<std::string>(); } // User specific data if (node["Entries"]) { // This is a choice ChoiceExtraData *data = new ChoiceExtraData; _extraData.reset(data); YAML::Node entriesNode = node["Entries"]; for (std::size_t i = 0; i < entriesNode.size(); ++i) { data->_entries.push_back(entriesNode[i].as<std::string>()); } // Also look for hints... if (node["Hints"]) { YAML::Node hintsNode = node["Hints"]; for (std::size_t i = 0; i < hintsNode.size(); ++i) { data->_helpStrings.push_back(hintsNode[i].as<std::string>()); } } } if (node["Min"]) { ValueExtraData* data = getOrCreateExtraData<ValueExtraData>(_extraData); data->min = node["Min"].as<double>(); } if (node["Max"]) { ValueExtraData* data = getOrCreateExtraData<ValueExtraData>(_extraData); data->max = node["Max"].as<double>(); } if (node["DisplayMin"]) { ValueExtraData* data = getOrCreateExtraData<ValueExtraData>(_extraData); data->dmin = node["DisplayMin"].as<double>(); } if (node["DisplayMax"]) { ValueExtraData* data = getOrCreateExtraData<ValueExtraData>(_extraData); data->dmax = node["DisplayMax"].as<double>(); } if (node["FileTypes"]) { FileExtraData* data = getOrCreateExtraData<FileExtraData>(_extraData); YAML::Node fileTypesNode = node["FileTypes"]; for (std::size_t i = 0; i < fileTypesNode.size(); ++i) { data->filters.push_back(fileTypesNode[i].as<std::string>()); } } } // isUserKnob if (node["InViewerLayout"]) { _inViewerContextItemLayout = node["InViewerLayout"].as<std::string>(); _hasViewerInterface = true; } if (node["InViewerSpacing"]) { _inViewerContextItemSpacing = node["InViewerSpacing"].as<int>(); _hasViewerInterface = true; } if (_isUserKnob) { if (node["InViewerLabel"]) { _inViewerContextLabel = node["InViewerLabel"].as<std::string>(); _hasViewerInterface = true; } if (node["InViewerIconUnchecked"]) { _inViewerContextIconFilePath[0] = node["InViewerIconUnchecked"].as<std::string>(); _hasViewerInterface = true; } if (node["InViewerIconChecked"]) { _inViewerContextIconFilePath[1] = node["InViewerIconChecked"].as<std::string>(); _hasViewerInterface = true; } } if (node["Props"]) { YAML::Node propsNode = node["Props"]; for (std::size_t i = 0; i < propsNode.size(); ++i) { std::string prop = propsNode[i].as<std::string>(); if (prop == "Secret") { _isSecret = true; } else if (prop == "Disabled") { _disabled = true; } else if (prop == "NoNewLine") { _triggerNewLine = false; } else if (prop == "NoEval") { _evaluatesOnChange = false; } else if (prop == "AnimatesChanged") { _animatesChanged = true; } else if (prop == "Volatile") { _isPersistent = false; } else if (prop == "IsLabel") { TextExtraData* data = getOrCreateExtraData<TextExtraData>(_extraData); data->label = true; data->multiLine = false; data->richText = false; } else if (prop == "MultiLine") { TextExtraData* data = getOrCreateExtraData<TextExtraData>(_extraData); data->label = false; data->multiLine = true; data->richText = false; } else if (prop == "RichText") { TextExtraData* data = getOrCreateExtraData<TextExtraData>(_extraData); data->richText = true; } else if (prop == "MultiPath") { PathExtraData* data = getOrCreateExtraData<PathExtraData>(_extraData); data->multiPath = node["MultiPath"].as<bool>(); } else if (prop == "Sequences") { FileExtraData* data = getOrCreateExtraData<FileExtraData>(_extraData); data->useSequences = node["Sequences"].as<bool>(); } else if (prop == "ExistingFiles") { FileExtraData* data = getOrCreateExtraData<FileExtraData>(_extraData); data->useExistingFiles = node["ExistingFiles"].as<bool>(); } else if (prop == "Italic") { TextExtraData *data = getOrCreateExtraData<TextExtraData>(_extraData); data->italicActivated = true; } else if (prop == "Bold") { TextExtraData *data = getOrCreateExtraData<TextExtraData>(_extraData); data->boldActivated = true; } else { std::cerr << "WARNING: Unrecognized parameter property " << prop << std::endl; } } } } // KnobSerialization::decode
void MidiRouter::readFile(QString fileName) { clear(); QFile file(fileName); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { emit(mappingError("cannot open file: " + fileName)); return; } QTextStream in(&file); YAML::Node root = YAML::Load(in.readAll().toStdString()); if (!root.IsMap()) { emit(mappingError("mapping is not a map in " + fileName)); return; } for (auto kv: std::map<QString, int>({{"master", -1}, {"player0", 0}, {"player1", 1}})) { const QString key = kv.first; const int player = kv.second; if (!root[key]) continue; YAML::Node parent = root[key]; if (!parent.IsSequence()) emit(mappingError(key + " is not a sequence in " + fileName)); for (unsigned int i = 0; i < parent.size(); i++) { YAML::Node node = parent[i]; MidiMapPtr mmap = QSharedPointer<MidiMap>::create(); mmap->player_index = player; try { if (node["trigger"]) { mmap->signal_name = node["trigger"].as<QString>(); mmap->mapping_type = TRIGGER; try { if (!find_midi(node, mmap, yamls_trigger_map)) emit(mappingError(key + " could not find trigger mapping in element " + QString::number(i))); } catch (std::runtime_error& e) { emit(mappingError(key + QString::fromStdString(e.what()) + " in element " + QString::number(i))); } } else if (node["continuous"]) { mmap->signal_name = node["continuous"].as<QString>(); mmap->mapping_type = CONTINUOUS; try { if (!find_midi(node, mmap, yamls_cc_map)) emit(mappingError(key + " could not find cc mapping in element " + QString::number(i))); } catch (std::runtime_error& e) { emit(mappingError(key + QString::fromStdString(e.what()) + " in element " + QString::number(i))); } } else if (node["twos_complement"]) { mmap->signal_name = node["twos_complement"].as<QString>(); mmap->mapping_type = TWOS_COMPLEMENT; try { if (!find_midi(node, mmap, yamls_cc_map)) emit(mappingError(key + " could not find trigger mapping in element " + QString::number(i))); } catch (std::runtime_error& e) { emit(mappingError(key + QString::fromStdString(e.what()) + " in element " + QString::number(i))); } } else { emit(mappingError(key + " no supported mapping found in midi mapping element " + QString::number(i))); return; } if (node["mult"]) mmap->multiplier = node["mult"].as<double>(); if (node["offset"]) mmap->offset = node["offset"].as<double>(); //XXX search for conflicting maps and warn mMappings.push_back(mmap); } catch (YAML::Exception& e) { emit(mappingError(key + " exception processing midi mapping element " + QString::number(i) + " " + QString(e.what()))); return; } catch(...) { emit(mappingError(key + " exception processing midi mapping element " + QString::number(i))); return; } } } }
void Emulator::Load(bool add_only) { Stop(); try { Init(); // Load game list (maps ABCD12345 IDs to /dev_bdvd/ locations) YAML::Node games = YAML::Load(fs::file{fs::get_config_dir() + "/games.yml", fs::read + fs::create}.to_string()); if (!games.IsMap()) { games.reset(); } LOG_NOTICE(LOADER, "Path: %s", m_path); const std::string elf_dir = fs::get_parent_dir(m_path); // Load PARAM.SFO (TODO) const auto _psf = psf::load_object([&] { if (fs::file sfov{elf_dir + "/sce_sys/param.sfo"}) { return sfov; } else { return fs::file(elf_dir + "/../PARAM.SFO"); } }()); m_title = psf::get_string(_psf, "TITLE", m_path); m_title_id = psf::get_string(_psf, "TITLE_ID"); const auto _cat = psf::get_string(_psf, "CATEGORY"); LOG_NOTICE(LOADER, "Title: %s", GetTitle()); LOG_NOTICE(LOADER, "Serial: %s", GetTitleID()); // Initialize data/cache directory m_cache_path = fs::get_data_dir(m_title_id, m_path); LOG_NOTICE(LOADER, "Cache: %s", GetCachePath()); // Load custom config-0 if (fs::file cfg_file{m_cache_path + "/config.yml"}) { LOG_NOTICE(LOADER, "Applying custom config: %s/config.yml", m_cache_path); g_cfg.from_string(cfg_file.to_string()); } // Load custom config-1 if (fs::file cfg_file{fs::get_config_dir() + "data/" + m_title_id + "/config.yml"}) { LOG_NOTICE(LOADER, "Applying custom config: data/%s/config.yml", m_title_id); g_cfg.from_string(cfg_file.to_string()); } // Load custom config-2 if (fs::file cfg_file{m_path + ".yml"}) { LOG_NOTICE(LOADER, "Applying custom config: %s.yml", m_path); g_cfg.from_string(cfg_file.to_string()); } LOG_NOTICE(LOADER, "Used configuration:\n%s\n", g_cfg.to_string()); // Load patches from different locations fxm::check_unlocked<patch_engine>()->append(fs::get_config_dir() + "data/" + m_title_id + "/patch.yml"); fxm::check_unlocked<patch_engine>()->append(m_cache_path + "/patch.yml"); // Mount all devices const std::string emu_dir_ = g_cfg.vfs.emulator_dir; const std::string emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_; const std::string home_dir = g_cfg.vfs.app_home; std::string bdvd_dir = g_cfg.vfs.dev_bdvd; vfs::mount("dev_hdd0", fmt::replace_all(g_cfg.vfs.dev_hdd0, "$(EmulatorDir)", emu_dir)); vfs::mount("dev_hdd1", fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", emu_dir)); vfs::mount("dev_flash", fmt::replace_all(g_cfg.vfs.dev_flash, "$(EmulatorDir)", emu_dir)); vfs::mount("dev_usb", fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir)); vfs::mount("dev_usb000", fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir)); vfs::mount("app_home", home_dir.empty() ? elf_dir + '/' : fmt::replace_all(home_dir, "$(EmulatorDir)", emu_dir)); // Detect boot location const std::string hdd0_game = vfs::get("/dev_hdd0/game/"); const std::string hdd0_disc = vfs::get("/dev_hdd0/disc/"); if (_cat == "DG" && m_path.find(hdd0_game + m_title_id + '/') != -1) { // Booting disc game from wrong location LOG_ERROR(LOADER, "Disc game found at invalid location: /dev_hdd0/game/%s/", m_title_id); // Move and retry from correct location if (fs::rename(hdd0_game + m_title_id, hdd0_disc + m_title_id)) { LOG_SUCCESS(LOADER, "Disc game moved to special location: /dev_hdd0/disc/%s/", m_title_id); return SetPath(hdd0_disc + m_path.substr(hdd0_game.size())), Load(); } else { LOG_ERROR(LOADER, "Failed to move disc game to /dev_hdd0/disc/%s/ (%s)", m_title_id, fs::g_tls_error); return; } } // Booting disc game if (_cat == "DG" && bdvd_dir.empty()) { // Mount /dev_bdvd/ if necessary if (auto pos = elf_dir.rfind("/PS3_GAME") + 1) { bdvd_dir = elf_dir.substr(0, pos); } } // Booting patch data if (_cat == "GD" && bdvd_dir.empty()) { // Load /dev_bdvd/ from game list if available if (auto node = games[m_title_id]) { bdvd_dir = node.Scalar(); } else { LOG_FATAL(LOADER, "Disc directory not found. Try to run the game from the actual game disc directory."); } } // Check /dev_bdvd/ if (!bdvd_dir.empty() && fs::is_dir(bdvd_dir)) { fs::file sfb_file; vfs::mount("dev_bdvd", bdvd_dir); LOG_NOTICE(LOADER, "Disc: %s", vfs::get("/dev_bdvd")); if (!sfb_file.open(vfs::get("/dev_bdvd/PS3_DISC.SFB")) || sfb_file.size() < 4 || sfb_file.read<u32>() != ".SFB"_u32) { LOG_ERROR(LOADER, "Invalid disc directory for the disc game %s", m_title_id); return; } const std::string bdvd_title_id = psf::get_string(psf::load_object(fs::file{vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO")}), "TITLE_ID"); if (bdvd_title_id != m_title_id) { LOG_ERROR(LOADER, "Unexpected disc directory for the disc game %s (found %s)", m_title_id, bdvd_title_id); return; } // Store /dev_bdvd/ location games[m_title_id] = bdvd_dir; YAML::Emitter out; out << games; fs::file(fs::get_config_dir() + "/games.yml", fs::rewrite).write(out.c_str(), out.size()); } else if (_cat == "DG" || _cat == "GD") { LOG_ERROR(LOADER, "Failed to mount disc directory for the disc game %s", m_title_id); return; } if (add_only) { LOG_NOTICE(LOADER, "Finished to add data to games.yml by boot for: %s", m_path); return; } // Check game updates const std::string hdd0_boot = hdd0_game + m_title_id + "/USRDIR/EBOOT.BIN"; if (_cat == "DG" && fs::is_file(hdd0_boot)) { // Booting game update LOG_SUCCESS(LOADER, "Updates found at /dev_hdd0/game/%s/!", m_title_id); return SetPath(hdd0_boot), Load(); } // Mount /host_root/ if necessary if (g_cfg.vfs.host_root) { vfs::mount("host_root", {}); } // Open SELF or ELF fs::file elf_file(m_path); if (!elf_file) { LOG_ERROR(LOADER, "Failed to open executable: %s", m_path); return; } // Check SELF header if (elf_file.size() >= 4 && elf_file.read<u32>() == "SCE\0"_u32) { const std::string decrypted_path = m_cache_path + "boot.elf"; fs::stat_t encrypted_stat = elf_file.stat(); fs::stat_t decrypted_stat; // Check modification time and try to load decrypted ELF if (fs::stat(decrypted_path, decrypted_stat) && decrypted_stat.mtime == encrypted_stat.mtime) { elf_file.open(decrypted_path); } else { // Decrypt SELF elf_file = decrypt_self(std::move(elf_file)); if (fs::file elf_out{decrypted_path, fs::rewrite}) { elf_out.write(elf_file.to_vector<u8>()); elf_out.close(); fs::utime(decrypted_path, encrypted_stat.atime, encrypted_stat.mtime); } else { LOG_ERROR(LOADER, "Failed to create boot.elf"); } } } ppu_exec_object ppu_exec; ppu_prx_object ppu_prx; spu_exec_object spu_exec; arm_exec_object arm_exec; if (!elf_file) { LOG_ERROR(LOADER, "Failed to decrypt SELF: %s", m_path); return; } else if (ppu_exec.open(elf_file) == elf_error::ok) { // PS3 executable g_system = system_type::ps3; m_state = system_state::ready; GetCallbacks().on_ready(); vm::ps3::init(); if (m_elf_path.empty()) { if (m_path.find(hdd0_game) != -1) { m_elf_path = "/dev_hdd0/game/" + m_path.substr(hdd0_game.size()); } else if (!bdvd_dir.empty() && fs::is_dir(bdvd_dir)) { //Disc games are on /dev_bdvd/ size_t pos = m_path.rfind("PS3_GAME"); m_elf_path = "/dev_bdvd/" + m_path.substr(pos); } else { //For homebrew m_elf_path = "/host_root/" + m_path; } LOG_NOTICE(LOADER, "Elf path: %s", m_elf_path); } ppu_load_exec(ppu_exec); fxm::import<GSRender>(Emu.GetCallbacks().get_gs_render); // TODO: must be created in appropriate sys_rsx syscall } else if (ppu_prx.open(elf_file) == elf_error::ok) { // PPU PRX (experimental) g_system = system_type::ps3; m_state = system_state::ready; GetCallbacks().on_ready(); vm::ps3::init(); ppu_load_prx(ppu_prx, m_path); } else if (spu_exec.open(elf_file) == elf_error::ok) { // SPU executable (experimental) g_system = system_type::ps3; m_state = system_state::ready; GetCallbacks().on_ready(); vm::ps3::init(); spu_load_exec(spu_exec); } else if (arm_exec.open(elf_file) == elf_error::ok) { // ARMv7 executable g_system = system_type::psv; m_state = system_state::ready; GetCallbacks().on_ready(); vm::psv::init(); if (m_elf_path.empty()) { m_elf_path = "host_root:" + m_path; LOG_NOTICE(LOADER, "Elf path: %s", m_elf_path); } arm_load_exec(arm_exec); } else { LOG_ERROR(LOADER, "Invalid or unsupported file format: %s", m_path); LOG_WARNING(LOADER, "** ppu_exec -> %s", ppu_exec.get_error()); LOG_WARNING(LOADER, "** ppu_prx -> %s", ppu_prx.get_error()); LOG_WARNING(LOADER, "** spu_exec -> %s", spu_exec.get_error()); LOG_WARNING(LOADER, "** arm_exec -> %s", arm_exec.get_error()); return; } if (g_cfg.misc.autostart && IsReady()) { Run(); } else if (IsPaused()) { m_state = system_state::ready; GetCallbacks().on_ready(); } } catch (const std::exception& e) { LOG_FATAL(LOADER, "%s thrown: %s", typeid(e).name(), e.what()); Stop(); } }
void Config::parseWatcher(const YAML::Node& node) { size_t asterisk_count; if(node.size() >= 1 && node.IsMap()) for (YAML::const_iterator iter=node.begin();iter!=node.end();++iter) { std::string key = iter->first.as<std::string>(); YAML::Node value = iter->second; Util::lowercase(key); if(key == "filter") { if(!value.IsSequence()) std::cerr << "ERROR!\n"; for(YAML::const_iterator filter_iter=value.begin(); filter_iter!=value.end(); ++filter_iter) { asterisk_count = 0; std::string val = filter_iter->as<std::string>(); for(size_t i = 0; i < val.length(); i++) if(val[i] == '*') asterisk_count++; LOG(logger, DEBUG, "Filter: %s", val.c_str()); if(asterisk_count > 1) throw std::runtime_error("Could not open file"); mWatch.filters.push_back(val); } } else if(key == "include") { if(!value.IsSequence() && !value.IsScalar()) std::cerr << "ERROR!\n"; if(value.IsSequence()) { for(YAML::const_iterator filter_iter=value.begin(); filter_iter!=value.end(); ++filter_iter) { LOG(logger, DEBUG, "Include: %s", filter_iter->as<std::string>().c_str()); mWatch.include.push_back(filter_iter->as<std::string>()); } } else if(value.IsScalar()) { LOG(logger, DEBUG, "Include: %s", value.as<std::string>().c_str()); mWatch.include.push_back(value.as<std::string>()); } } else if(key == "exclude") { if(!value.IsSequence() && !value.IsScalar()) std::cerr << "ERROR!\n"; if(value.IsSequence()) { for(YAML::const_iterator filter_iter=value.begin(); filter_iter!=value.end(); ++filter_iter) { LOG(logger, DEBUG, "Exclude: %s", filter_iter->as<std::string>().c_str()); mWatch.exclude.push_back(filter_iter->as<std::string>()); } } else if(value.IsScalar()) { LOG(logger, DEBUG, "Exclude: %s", value.as<std::string>().c_str()); mWatch.exclude.push_back(value.as<std::string>()); } } else LOG(logger, DEBUG, "Value: %s\n", value.as<std::string>().c_str()); } }