JSValue parseSceneGlobals(JSScope& jsScope, const YAML::Node& node) { switch(node.Type()) { case YAML::NodeType::Scalar: { auto& scalar = node.Scalar(); if (scalar.compare(0, 8, "function") == 0) { return pushYamlScalarAsJsFunctionOrString(jsScope, node); } return pushYamlScalarAsJsPrimitive(jsScope, node); } case YAML::NodeType::Sequence: { auto jsArray = jsScope.newArray(); for (size_t i = 0; i < node.size(); i++) { jsArray.setValueAtIndex(i, parseSceneGlobals(jsScope, node[i])); } return jsArray; } case YAML::NodeType::Map: { auto jsObject = jsScope.newObject(); for (const auto& entry : node) { if (!entry.first.IsScalar()) { continue; // Can't put non-scalar keys in JS objects. } jsObject.setValueForProperty(entry.first.Scalar(), parseSceneGlobals(jsScope, entry.second)); } return jsObject; } default: return jsScope.newNull(); } }
void StyleContext::parseSceneGlobals(const YAML::Node& node, const std::string& key, int seqIndex, duk_idx_t dukObject) { switch(node.Type()) { case YAML::NodeType::Scalar: if (key.size() == 0) { duk_push_string(m_ctx, node.Scalar().c_str()); duk_put_prop_index(m_ctx, dukObject, seqIndex); } else { auto nodeValue = node.Scalar(); if (nodeValue.compare(0, 8, "function") == 0) { duk_push_string(m_ctx, key.c_str()); // push property key duk_push_string(m_ctx, nodeValue.c_str()); // push function string duk_push_string(m_ctx, ""); if (duk_pcompile(m_ctx, DUK_COMPILE_FUNCTION) == 0) { // compile function duk_put_prop(m_ctx, -3); // put {key: function()} } else { LOGW("Compile failed in global function: %s\n%s\n---", duk_safe_to_string(m_ctx, -1), nodeValue.c_str()); duk_pop(m_ctx); //pop error duk_pop(m_ctx); //pop key // push property as a string duk_push_string(m_ctx, nodeValue.c_str()); duk_put_prop_string(m_ctx, dukObject, key.c_str()); } } else { duk_push_string(m_ctx, nodeValue.c_str()); duk_put_prop_string(m_ctx, dukObject, key.c_str()); } } break; case YAML::NodeType::Sequence: { auto seqObj = duk_push_array(m_ctx); for (int i = 0; i < node.size(); i++) { parseSceneGlobals(node[i], "", i, seqObj); } duk_put_prop_string(m_ctx, seqObj-1, key.c_str()); break; } case YAML::NodeType::Map: { //duk_push_string(m_ctx, key.c_str()); auto mapObj = duk_push_object(m_ctx); for (auto& mapNode : node) { auto itemKey = mapNode.first.Scalar(); parseSceneGlobals(mapNode.second, itemKey, 0, mapObj); } duk_put_prop_string(m_ctx, mapObj-1, key.c_str()); } default: break; } return; }
void StyleContext::setSceneGlobals(const YAML::Node& sceneGlobals) { if (!sceneGlobals) { return; } JSScope jsScope(*m_jsContext); auto jsValue = parseSceneGlobals(jsScope, sceneGlobals); m_jsContext->setGlobalValue("global", std::move(jsValue)); }
void StyleContext::setSceneGlobals(const std::unordered_map<std::string, YAML::Node>& sceneGlobals) { if (sceneGlobals.size() == 0) { return; } //[ "ctx" ] auto globalObject = duk_push_object(m_ctx); for (auto& global : sceneGlobals) { auto key = global.first; if (key.find(":") != std::string::npos) { continue; } parseSceneGlobals(global.second, key, 0, globalObject); } duk_put_global_string(m_ctx, "global"); }