bool CoreTexture::Rebuild(JSContext* cx) { // First, free any texture we already have (no-op if it's a 0-texture) OVR::FreeTexture(texture); // Get the path string OVR::String pathStr; JS::RootedValue pathVal(cx, *path); if (!GetOVRStringVal(cx, pathVal, &pathStr)) { return false; } // If it's a cube map if (cube) { return RebuildCubemap(cx, pathStr); } else { return RebuildTexture(cx, pathStr); } return true; }
vector<string> binaryTreePaths(TreeNode* root) { vector<string> paths; // If root is NULL, return an empty path vector immediately. if (root == nullptr) { return paths; } // pathVal is a vector of TreeNode values along a path // starting from root. vector<int> pathVal({ root->val }); // st is the stack used for the depth-first search. stack<TreeNode*> st; st.push(root); // visitedNodes keeps all the nodes which have been visited // during the depth-first search. In other words, it keeps // all the nodes which have ever been pushed into the stack. unordered_set<TreeNode*> visitedNodes({ root }); // Do the depth-first search until the stack is empty. while (!st.empty()) { TreeNode *curr = st.top(); if ((curr->left == nullptr) && (curr->right == nullptr)) { // curr is a leaf, so the current path is a path from // root to a leaf and add it to paths. paths.push_back(GetPathStringFromNums(pathVal)); // Remove the leaf node from pathVal which will end at // the parent node of curr. pathVal.pop_back(); st.pop(); } else { // curr is not leaf, so we need to go down at least one // level. // First we try pushing the left child if it hasn't // been visited. if (curr->left != nullptr) { auto itLeft = visitedNodes.find(curr->left); if (itLeft == visitedNodes.end()) { st.push(curr->left); pathVal.push_back(curr->left->val); visitedNodes.insert(curr->left); continue; } } // We reach here because either the left child doesn't // exist or the left child has been visited. Then we try // pushing the right child if it hasn't been visited. if (curr->right != nullptr) { auto itRight = visitedNodes.find(curr->right); if (itRight == visitedNodes.end()) { st.push(curr->right); pathVal.push_back(curr->right->val); visitedNodes.insert(curr->right); continue; } } // The nodes in the subtree below curr have all been // visited, so remove curr from pathVal which will end // at the parent node of curr. pathVal.pop_back(); st.pop(); } } return paths; }
bool CoreTexture_constructor(JSContext* cx, unsigned argc, JS::Value *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); // Check the arguments length if (args.length() != 1) { JS_ReportError(cx, "Wrong number of arguments: %d, was expecting: %d", argc, 1); return false; } // Check to make sure the opts argument is an object if (!args[0].isObject()) { JS_ReportError(cx, "Texture options must be an object"); return false; } JS::RootedObject opts(cx, &args[0].toObject()); // Path JS::RootedValue pathVal(cx); JS_GetProperty(cx, opts, "path", &pathVal); if (!pathVal.isNullOrUndefined() && !pathVal.isString()) { JS_ReportError(cx, "Expected path to be a string"); return false; } // Width JS::RootedValue widthVal(cx); if (!JS_GetProperty(cx, opts, "width", &widthVal) || widthVal.isNullOrUndefined()) { JS_ReportError(cx, "Texture missing required width property"); return false; } if (!widthVal.isInt32()) { JS_ReportError(cx, "Texture width must be an integer"); return false; } // Height JS::RootedValue heightVal(cx); if (!JS_GetProperty(cx, opts, "height", &heightVal) || heightVal.isNullOrUndefined()) { JS_ReportError(cx, "Texture missing required height property"); return false; } if (!heightVal.isInt32()) { JS_ReportError(cx, "Texture height must be an integer"); return false; } // Cube JS::RootedValue cubeVal(cx); if (!JS_GetProperty(cx, opts, "cube", &cubeVal) || cubeVal.isNullOrUndefined() || !cubeVal.isBoolean()) { cubeVal = JS::RootedValue(cx, JS::FalseValue()); } // Create our self object CoreTexture* tex = new CoreTexture(cx, new JS::Heap<JS::Value>(pathVal), widthVal.toInt32(), heightVal.toInt32(), cubeVal.toBoolean()); JS::RootedObject self(cx, NewCoreTexture(cx, tex)); // Return our self object args.rval().set(JS::ObjectOrNullValue(self)); return true; }