Esempio n. 1
1
/*
 * 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
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
        }
    }


}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
// 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;
		}
	}
}
Esempio n. 8
0
File: yaml.hpp Progetto: k0zmo/kl
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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';
	//}
}
Esempio n. 11
0
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;
    }
Esempio n. 12
0
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());
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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;
}
Esempio n. 19
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
Esempio n. 20
0
File: yaml.hpp Progetto: k0zmo/kl
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;
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
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
Esempio n. 23
0
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()));
	}
}
Esempio n. 24
0
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
Esempio n. 25
0
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;
      }
    }
  }
}
Esempio n. 26
0
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();
	}
}
Esempio n. 27
0
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());
		}
}