SearchResult<Node> AIManager::GetPath(vec3f from, vec3f to) { // we want the path backward because we want the // pathfinder to retain cache for multiple queries // towards the same target (robots chasing player). auto end = GetNodeAt(from); auto start = GetNodeAt(to); auto result = mPathFinder.FindPath(start, end); return result; }
nsresult inDOMView::RowToNode(PRInt32 aRow, inDOMViewNode** aNode) { if (aRow < 0 || aRow >= GetRowCount()) return NS_ERROR_FAILURE; *aNode = GetNodeAt(aRow); return NS_OK; }
void inDOMView::ReplaceNode(inDOMViewNode* aNode, PRInt32 aRow) { if (RowOutOfBounds(aRow, 1)) return; delete GetNodeAt(aRow); mNodes.ElementAt(aRow) = aNode; }
void inDOMView::RemoveNode(PRInt32 aRow) { if (RowOutOfBounds(aRow, 1)) return; delete GetNodeAt(aRow); mNodes.RemoveElementAt(aRow); }
void inDOMView::RemoveAllNodes() { PRInt32 rowCount = GetRowCount(); for (PRInt32 i = 0; i < rowCount; ++i) { delete GetNodeAt(i); } mNodes.Clear(); }
nsresult inDOMView::GetLastDescendantOf(inDOMViewNode* aNode, PRInt32 aRow, PRInt32* aResult) { // get the last node that is a descendant of the previous sibling PRInt32 row = 0; for (row = aRow+1; row < GetRowCount(); ++row) { if (GetNodeAt(row)->level <= aNode->level) break; } *aResult = row-1; return NS_OK; }
NS_IMETHODIMP nsContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn) { nsINode* node = GetNodeAt(aIndex); if (node) { return CallQueryInterface(node, aReturn); } *aReturn = nsnull; return NS_OK; }
void inDOMView::RemoveNodes(PRInt32 aRow, PRInt32 aCount) { if (aRow < 0) return; PRInt32 rowCount = GetRowCount(); for (PRInt32 i = aRow; i < aRow+aCount && i < rowCount; ++i) { delete GetNodeAt(i); } mNodes.RemoveElementsAt(aRow, aCount); }
NS_IMETHODIMP nsBaseContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn) { nsISupports *tmp = GetNodeAt(aIndex); if (!tmp) { *aReturn = nsnull; return NS_OK; } return CallQueryInterface(tmp, aReturn); }
nsresult inDOMView::NodeToRow(nsIDOMNode* aNode, PRInt32* aRow) { PRInt32 rowCount = GetRowCount(); for (PRInt32 i = 0; i < rowCount; ++i) { if (GetNodeAt(i)->node == aNode) { *aRow = i; return NS_OK; } } *aRow = -1; return NS_ERROR_FAILURE; }
nsresult inDOMView::GetFirstDescendantOf(inDOMViewNode* aNode, PRInt32 aRow, PRInt32* aResult) { // get the first node that is a descendant of the previous sibling PRInt32 row = 0; inDOMViewNode* node; for (row = aRow+1; row < GetRowCount(); ++row) { node = GetNodeAt(row); if (node->parent == aNode) { *aResult = row; return NS_OK; } if (node->level <= aNode->level) break; } return NS_ERROR_FAILURE; }
void AIManager::ResetGridData() { //Populate nodes for (int i = 0; i < mNumRows; i++) { for (int j = 0; j < mNumCols; j++) { vec3f nodePos = vec3f(mLeft + (mNodeRadius * 2) * j + mNodeRadius, mTop - (mNodeRadius * 2) * i + mNodeRadius, 0); mGrid(i, j).x = i; mGrid(i, j).y = j; mGrid(i, j).weight = -10; mGrid(i, j).worldPos = vec3f(nodePos, 0); } } for each(auto &e in Factory<Explorer>()) { if (!e.mIsDead) { GetNodeAt(e.mTransform->GetPosition())->weight = 0; } } }
void nsHTMLFieldSetElement::NotifyElementsForFirstLegendChange(bool aNotify) { /** * NOTE: this could be optimized if only call when the fieldset is currently * disabled. * This should also make sure that mElements is set when we happen to be here. * However, this method shouldn't be called very often in normal use cases. */ if (!mElements) { mElements = new nsContentList(this, MatchListedElements, nsnull, nsnull, true); } PRUint32 length = mElements->Length(true); for (PRUint32 i = 0; i < length; ++i) { static_cast<nsGenericHTMLFormElement*>(mElements->GetNodeAt(i)) ->FieldSetFirstLegendChanged(aNotify); } }
nsresult nsHTMLFieldSetElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled && nsINode::GetFirstChild()) { if (!mElements) { mElements = new nsContentList(this, MatchListedElements, nsnull, nsnull, true); } PRUint32 length = mElements->Length(true); for (PRUint32 i=0; i<length; ++i) { static_cast<nsGenericHTMLFormElement*>(mElements->GetNodeAt(i)) ->FieldSetDisabledChanged(aNotify); } } return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName, aValue, aNotify); }
// //--- Check, if the tiles are placed diagonally, to see if they don't have // bool CAStar::CheckForDiagonalBlocker(const CPathNode * in_n1, const CPathNode * in_n2) { //--- Top left if (in_n2->m_x + in_n2->m_sizeX == in_n1->m_x && in_n2->m_y - in_n2->m_sizeY == in_n1->m_y) { if (GetNodeAt(in_n1->m_x - 1, in_n2->m_y - 1)->m_value == 0 && GetNodeAt(in_n1->m_x, in_n2->m_y)->m_value == 0) return true; } //--- Bottom left if (in_n2->m_x + in_n2->m_sizeX == in_n1->m_x && in_n2->m_y + in_n2->m_sizeY == in_n1->m_y) { if (GetNodeAt(in_n1->m_x - 1, in_n1->m_y)->m_value == 0 && GetNodeAt(in_n1->m_x, in_n1->m_y - 1)->m_value == 0) return true; } //--- Top right if (in_n2->m_x - in_n2->m_sizeX == in_n1->m_x && in_n2->m_y - in_n2->m_sizeY == in_n1->m_y) { if (GetNodeAt(in_n2->m_x - 1, in_n2->m_y)->m_value == 0 && GetNodeAt(in_n2->m_x, in_n2->m_y - 1)->m_value == 0) return true; } //--- Bottom right if (in_n2->m_x - in_n2->m_sizeX == in_n1->m_x && in_n2->m_y + in_n2->m_sizeY == in_n1->m_y) { if (GetNodeAt(in_n2->m_x, in_n1->m_y)->m_value == 0 && GetNodeAt(in_n2->m_x - 1, in_n1->m_y - 1)->m_value == 0) return true; } return false; }
// //--- To build it. // int CAStar::Build(const unsigned char * in_mapArray, const int in_sizeX, const int in_sizeY) { //--- We clean to be sure Clean(); //--- Copy the array if (!in_mapArray) return 0; m_sizeX = in_sizeX; m_sizeY = in_sizeY; m_mapArray = new unsigned char [m_sizeX * m_sizeY]; memcpy(m_mapArray, in_mapArray, m_sizeX * m_sizeY); m_mapNodesRef = new CPathNode *[m_sizeX * m_sizeY]; //--- Alright, create the nodes recursively int x,y; for (y=0;y<m_sizeY;y+=m_maxPathSize) { for (x=0;x<m_sizeX;x+=m_maxPathSize) { CreateNodes(x, y, m_maxPathSize); } } //--- Ok, now create the neighborhood list. CPathNode* p; CPathNode* n; int lastSize; for (p = m_lstNodes[0]; p; p = p->next) { //--- Top y = p->m_y - 1; lastSize = 1; for (x = p->m_x - 1; x <= p->m_x + p->m_sizeX; x += 1) { n = GetNodeAt(x, y); if (n) { lastSize = n->m_sizeX; if (p->m_value == n->m_value && !CheckForDiagonalBlocker(p, n)) p->AddNeighbor(n); } else { lastSize = 1; // useless } } //--- Down y = p->m_y + p->m_sizeY; lastSize = 1; for (x = p->m_x - 1; x <= p->m_x + p->m_sizeX; x += 1) { n = GetNodeAt(x, y); if (n) { lastSize = n->m_sizeX; if (p->m_value == n->m_value && !CheckForDiagonalBlocker(p, n)) p->AddNeighbor(n); } else { lastSize = 1; // useless } } //--- Left x = p->m_x - 1; lastSize = 1; for (y = p->m_y - 1; y <= p->m_y + p->m_sizeY; y += 1) { n = GetNodeAt(x, y); if (n) { lastSize = n->m_sizeY; if (p->m_value == n->m_value && !CheckForDiagonalBlocker(p, n)) p->AddNeighbor(n); } else { lastSize = 1; // useless } } //--- Right x = p->m_x + p->m_sizeX; lastSize = 1; for (y = p->m_y - 1; y <= p->m_y + p->m_sizeY; y += 1) { n = GetNodeAt(x, y); if (n) { lastSize = n->m_sizeY; if (p->m_value == n->m_value && !CheckForDiagonalBlocker(p, n)) p->AddNeighbor(n); } else { lastSize = 1; // useless } } } //--- Successful return 1; }
/// <summary> /// The purpose of this test is to load the "matchingtest.data" data file and run the tests laid out /// in that file, checking for failures. The "matchingtest.data" file contains a series of /// predefined selectors and html to test the selectors against. /// /// Run this test as well as GQ in debug mode to get an extreme amount of information about the /// internals of the parser, selector construction, etc. To get this additional information, ensure /// that while compiling GQ in debug mode, you add "GQ_VERBOSE_DEBUG_NFO" to the preprocessor /// definitions. The verbose output can help gain much insight when debugging selectors and /// the internals of GQ. /// </summary> int main() { std::string matchingTestDataFilePath(u8"../../matchingtest.data"); std::ifstream in(matchingTestDataFilePath, std::ios::binary | std::ios::in); if (in.fail()) { std::cout << u8"Failed to load \"../../matchingtest.data\" test file." << std::endl; return -1; } std::vector<int> testNumbers; std::vector<std::string> testSelectors; std::vector< std::pair<bool, int> > testExpectedMatches; std::vector<std::string> testHtmlSamples; std::string testContents; in.seekg(0, std::ios::end); auto fsize = in.tellg(); if (fsize < 0 || static_cast<unsigned long long>(fsize) > static_cast<unsigned long long>(std::numeric_limits<size_t>::max())) { std::cout << u8"When loading the test file, ifstream::tellg() returned either less than zero or a number greater than this program can correctly handle." << std::endl; return -1; } testContents.resize(static_cast<size_t>(fsize)); in.seekg(0, std::ios::beg); in.read(&testContents[0], testContents.size()); in.close(); std::istringstream tests(testContents); std::string test; while (std::getline(tests, test)) { if (test.length() == 0 || test[0] == '!') { // Skip empty lines and comments continue; } std::istringstream isstest(test); std::string testPart; while (std::getline(isstest, testPart, '%')) { auto splitPos = testPart.find('@'); auto testVariable = testPart.substr(0, splitPos); auto testVariableValue = testPart.substr(splitPos + 1); if (testVariable.length() == 0 || testVariableValue.length() == 0) { std::cout << u8"Empty test variable or value encountered. Test file is improperly formatted. Aborting." << std::endl; return -1; } if (testVariable.compare(u8"TestNumber") == 0) { testNumbers.push_back(std::stoi(testVariableValue)); } else if (testVariable.compare(u8"TestSelector") == 0) { testSelectors.push_back(testVariableValue); } else if (testVariable.compare(u8"TestExpectedMatches") == 0) { testExpectedMatches.push_back({ true, std::stoi(testVariableValue) }); } else if (testVariable.compare(u8"TestExpectedUncheckedMatches") == 0) { testExpectedMatches.push_back({ false, std::stoi(testVariableValue) }); } else if (testVariable.compare(u8"TestHtml") == 0) { testHtmlSamples.push_back(testVariableValue); } } } size_t testsPassed = 0; size_t testsFailed = 0; gq::Parser parser; if (testNumbers.size() == testSelectors.size() && testExpectedMatches.size() == testNumbers.size() && testHtmlSamples.size() == testExpectedMatches.size()) { for (size_t i = 0; i < testNumbers.size(); ++i) { for (size_t b = 0; b < 72; ++b) { std::cout << '-'; } std::cout << std::endl << u8"\t\t\t\tTest #" << testNumbers[i] << std::endl; for (size_t b = 0; b < 72; ++b) { std::cout << '-'; } std::cout << std::endl << std::endl; auto document = gq::Document::Create(); std::cout << u8"Input HTML:" << std::endl; std::cout << testHtmlSamples[i] << std::endl << std::endl; document->Parse(testHtmlSamples[i]); std::cout << u8"Parsed Output HTML:" << std::endl; std::cout << document->GetOuterHtml(); try { std::cout << std::endl; auto selector = parser.CreateSelector(testSelectors[i], true); auto result = document->Find(selector); std::cout << u8"Original Selector String: " << selector->GetOriginalSelectorString() << std::endl << std::endl; if (result.GetNodeCount() != testExpectedMatches[i].second) { std::cout << u8"Test Number " << testNumbers[i] << u8" failed using selector " << testSelectors[i] << u8" because " << testExpectedMatches[i].second << u8" matches were expected, received " << result.GetNodeCount() << std::endl << std::endl; ++testsFailed; for (size_t ri = 0; ri < result.GetNodeCount(); ++ri) { auto* node = result.GetNodeAt(ri); std::cout << gq::Serializer::Serialize(node) << std::endl; } continue; } else { // If the test pair bool is true, that means that we're not just counting results, but that we're // also validating the results. We'll check the results to see if they contain the test "FAIL". If // they do, that means that an element that should not have been selected by the selector was indeed // selected. If "FAIL" is not matched, "PASS" is assumed. if (testExpectedMatches[i].first == true) { bool foundInvalidData = false; for (size_t ri = 0; ri < result.GetNodeCount(); ++ri) { auto* node = result.GetNodeAt(ri); if (node->GetOwnText().compare("FAIL") == 0) { foundInvalidData = true; break; } std::cout << gq::Serializer::Serialize(node) << std::endl; } if (foundInvalidData) { std::cout << u8"Test Number " << testNumbers[i] << u8" failed using selector " << testSelectors[i] << u8" because although the number of expected matches was accurate, the selector matched a node it should not have." << std::endl; ++testsFailed; } else { std::cout << u8"Test Number " << testNumbers[i] << u8" passed using selector " << testSelectors[i] << u8" because the correct number of expected matches were returned the match data was confirmed." << std::endl; ++testsPassed; } } else { std::cout << u8"Test Number " << testNumbers[i] << u8" passed using selector " << testSelectors[i] << u8" because " << testExpectedMatches[i].second << u8" matches were expected, received " << result.GetNodeCount() << u8". Test does not verify results, only quantity." << std::endl; ++testsPassed; } } } catch (std::runtime_error& e) { std::cout << u8"Got runtime_error: " << e.what() << std::endl; } catch (std::exception& e) { std::cout << u8"Got exception: " << e.what() << std::endl; } } } else { std::cout << u8"An unequal number of test variables were parsed. Test file is improperly formatted. Aborting." << std::endl; return -1; } std::cout << testsPassed << u8" Tests Passed and " << testsFailed << u8" Tests Failed." << std::endl; return 0; }
void inDOMView::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType) { if (!mTree) { return; } if (!(mWhatToShow & nsIDOMNodeFilter::SHOW_ATTRIBUTE)) { return; } nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this); // get the dom attribute node, if there is any nsCOMPtr<nsIDOMNode> content(do_QueryInterface(aElement)); nsCOMPtr<nsIDOMElement> el(do_QueryInterface(aElement)); nsCOMPtr<nsIDOMAttr> domAttr; nsDependentAtomString attrStr(aAttribute); if (aNameSpaceID) { nsCOMPtr<nsINameSpaceManager> nsm = do_GetService(NS_NAMESPACEMANAGER_CONTRACTID); if (!nsm) { // we can't find out which attribute we want :( return; } nsString attrNS; nsresult rv = nsm->GetNameSpaceURI(aNameSpaceID, attrNS); if (NS_FAILED(rv)) { return; } (void)el->GetAttributeNodeNS(attrNS, attrStr, getter_AddRefs(domAttr)); } else { (void)el->GetAttributeNode(attrStr, getter_AddRefs(domAttr)); } if (aModType == nsIDOMMutationEvent::MODIFICATION) { // No fancy stuff here, just invalidate the changed row if (!domAttr) { return; } PRInt32 row = 0; NodeToRow(domAttr, &row); mTree->InvalidateRange(row, row); } else if (aModType == nsIDOMMutationEvent::ADDITION) { if (!domAttr) { return; } // get the number of attributes on this content node nsCOMPtr<nsIDOMNamedNodeMap> attrs; content->GetAttributes(getter_AddRefs(attrs)); PRUint32 attrCount; attrs->GetLength(&attrCount); inDOMViewNode* contentNode = nsnull; PRInt32 contentRow; PRInt32 attrRow; if (mRootNode == content && !(mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT)) { // if this view has a root node but is not displaying it, // it is ok to act as if the changed attribute is on the root. attrRow = attrCount - 1; } else { if (NS_FAILED(NodeToRow(content, &contentRow))) { return; } RowToNode(contentRow, &contentNode); if (!contentNode->isOpen) { return; } attrRow = contentRow + attrCount; } inDOMViewNode* newNode = CreateNode(domAttr, contentNode); inDOMViewNode* insertNode = nsnull; RowToNode(attrRow, &insertNode); if (insertNode) { if (contentNode && insertNode->level <= contentNode->level) { RowToNode(attrRow-1, &insertNode); InsertLinkAfter(newNode, insertNode); } else InsertLinkBefore(newNode, insertNode); } InsertNode(newNode, attrRow); mTree->RowCountChanged(attrRow, 1); } else if (aModType == nsIDOMMutationEvent::REMOVAL) { // At this point, the attribute is already gone from the DOM, but is still represented // in our mRows array. Search through the content node's children for the corresponding // node and remove it. // get the row of the content node inDOMViewNode* contentNode = nsnull; PRInt32 contentRow; PRInt32 baseLevel; if (NS_SUCCEEDED(NodeToRow(content, &contentRow))) { RowToNode(contentRow, &contentNode); baseLevel = contentNode->level; } else { if (mRootNode == content) { contentRow = -1; baseLevel = -1; } else return; } // search for the attribute node that was removed inDOMViewNode* checkNode = nsnull; PRInt32 row = 0; for (row = contentRow+1; row < GetRowCount(); ++row) { checkNode = GetNodeAt(row); if (checkNode->level == baseLevel+1) { domAttr = do_QueryInterface(checkNode->node); if (domAttr) { nsAutoString attrName; domAttr->GetNodeName(attrName); if (attrName.Equals(attrStr)) { // we have found the row for the attribute that was removed RemoveLink(checkNode); RemoveNode(row); mTree->RowCountChanged(row, -1); break; } } } if (checkNode->level <= baseLevel) break; } } }