mirror of
				https://github.com/Atmosphere-NX/Atmosphere.git
				synced 2025-10-31 19:25:46 +01:00 
			
		
		
		
	* Implemented a system updater homebrew (titled Daybreak) * git subrepo pull ./troposphere/daybreak/nanovg subrepo: subdir: "troposphere/daybreak/nanovg" merged: "c197ba2f" upstream: origin: "https://github.com/Adubbz/nanovg-deko.git" branch: "master" commit: "c197ba2f" git-subrepo: version: "0.4.1" origin: "???" commit: "???" (+1 squashed commits) Squashed commits: [232dc943] git subrepo clone https://github.com/Adubbz/nanovg-deko.git troposphere/daybreak/nanovg subrepo: subdir: "troposphere/daybreak/nanovg" merged: "52bb784b" upstream: origin: "https://github.com/Adubbz/nanovg-deko.git" branch: "master" commit: "52bb784b" git-subrepo: version: "0.4.1" origin: "???" commit: "???" * daybreak: switch to using hiddbg for home blocking (+1 squashed commits) Squashed commits: [4bfc7b0d] daybreak: block the home button during installation
		
			
				
	
	
		
			215 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			215 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| ** Sample Framework for deko3d Applications
 | |
| **   CIntrusiveTree.cpp: Intrusive red-black tree helper class
 | |
| */
 | |
| #include "CIntrusiveTree.h"
 | |
| 
 | |
| // This red-black tree implementation is mostly based on mtheall's work,
 | |
| // which can be found here:
 | |
| //   https://github.com/smealum/ctrulib/tree/master/libctru/source/util/rbtree
 | |
| 
 | |
| void CIntrusiveTreeBase::rotate(N* node, N::Leaf leaf)
 | |
| {
 | |
|     N *tmp    = node->child(leaf);
 | |
|     N *parent = node->getParent();
 | |
| 
 | |
|     node->child(leaf) = tmp->child(!leaf);
 | |
|     if (tmp->child(!leaf))
 | |
|         tmp->child(!leaf)->setParent(node);
 | |
| 
 | |
|     tmp->child(!leaf) = node;
 | |
|     tmp->setParent(parent);
 | |
| 
 | |
|     if (parent)
 | |
|     {
 | |
|         if (node == parent->child(!leaf))
 | |
|             parent->child(!leaf) = tmp;
 | |
|         else
 | |
|             parent->child(leaf) = tmp;
 | |
|     }
 | |
|     else
 | |
|         m_root = tmp;
 | |
| 
 | |
|     node->setParent(tmp);
 | |
| }
 | |
| 
 | |
| void CIntrusiveTreeBase::recolor(N* parent, N* node)
 | |
| {
 | |
|     N *sibling;
 | |
| 
 | |
|     while ((!node || node->isBlack()) && node != m_root)
 | |
|     {
 | |
|         N::Leaf leaf = node == parent->left() ? N::Right : N::Left;
 | |
|         sibling = parent->child(leaf);
 | |
| 
 | |
|         if (sibling->isRed())
 | |
|         {
 | |
|             sibling->setBlack();
 | |
|             parent->setRed();
 | |
|             rotate(parent, leaf);
 | |
|             sibling = parent->child(leaf);
 | |
|         }
 | |
| 
 | |
|         N::Color clr[2];
 | |
|         clr[N::Left]  = sibling->left()  ? sibling->left()->getColor()  : N::Black;
 | |
|         clr[N::Right] = sibling->right() ? sibling->right()->getColor() : N::Black;
 | |
| 
 | |
|         if (clr[N::Left] == N::Black && clr[N::Right] == N::Black)
 | |
|         {
 | |
|             sibling->setRed();
 | |
|             node = parent;
 | |
|             parent = node->getParent();
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (clr[leaf] == N::Black)
 | |
|             {
 | |
|                 sibling->child(!leaf)->setBlack();
 | |
|                 sibling->setRed();
 | |
|                 rotate(sibling, !leaf);
 | |
|                 sibling = parent->child(leaf);
 | |
|             }
 | |
| 
 | |
|             sibling->setColor(parent->getColor());
 | |
|             parent->setBlack();
 | |
|             sibling->child(leaf)->setBlack();
 | |
|             rotate(parent, leaf);
 | |
| 
 | |
|             node = m_root;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (node)
 | |
|         node->setBlack();
 | |
| }
 | |
| 
 | |
| auto CIntrusiveTreeBase::walk(N* node, N::Leaf leaf) const -> N*
 | |
| {
 | |
|     if (node->child(leaf))
 | |
|     {
 | |
|         node = node->child(leaf);
 | |
|         while (node->child(!leaf))
 | |
|             node = node->child(!leaf);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         N *parent = node->getParent();
 | |
|         while (parent && node == parent->child(leaf))
 | |
|         {
 | |
|             node = parent;
 | |
|             parent = node->getParent();
 | |
|         }
 | |
|         node = parent;
 | |
|     }
 | |
| 
 | |
|     return node;
 | |
| }
 | |
| 
 | |
| void CIntrusiveTreeBase::insert(N* node, N* parent)
 | |
| {
 | |
|     node->left() = node->right() = nullptr;
 | |
|     node->setParent(parent);
 | |
|     node->setRed();
 | |
| 
 | |
|     while ((parent = node->getParent()) && parent->isRed())
 | |
|     {
 | |
|         N *grandparent = parent->getParent();
 | |
|         N::Leaf leaf = parent == grandparent->left() ? N::Right : N::Left;
 | |
|         N *uncle = grandparent->child(leaf);
 | |
| 
 | |
|         if (uncle && uncle->isRed())
 | |
|         {
 | |
|             uncle->setBlack();
 | |
|             parent->setBlack();
 | |
|             grandparent->setRed();
 | |
| 
 | |
|             node = grandparent;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (parent->child(leaf) == node)
 | |
|             {
 | |
|                 rotate(parent, leaf);
 | |
| 
 | |
|                 N* tmp = parent;
 | |
|                 parent = node;
 | |
|                 node = tmp;
 | |
|             }
 | |
| 
 | |
|             parent->setBlack();
 | |
|             grandparent->setRed();
 | |
|             rotate(grandparent, !leaf);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     m_root->setBlack();
 | |
| }
 | |
| 
 | |
| void CIntrusiveTreeBase::remove(N* node)
 | |
| {
 | |
|     N::Color color;
 | |
|     N *child, *parent;
 | |
| 
 | |
|     if (node->left() && node->right())
 | |
|     {
 | |
|         N *old = node;
 | |
| 
 | |
|         node = node->right();
 | |
|         while (node->left())
 | |
|             node = node->left();
 | |
| 
 | |
|         parent = old->getParent();
 | |
|         if (parent)
 | |
|         {
 | |
|             if (parent->left() == old)
 | |
|                 parent->left() = node;
 | |
|             else
 | |
|                 parent->right() = node;
 | |
|         }
 | |
|         else
 | |
|             m_root = node;
 | |
| 
 | |
|         child  = node->right();
 | |
|         parent = node->getParent();
 | |
|         color  = node->getColor();
 | |
| 
 | |
|         if (parent == old)
 | |
|             parent = node;
 | |
|         else
 | |
|         {
 | |
|             if (child)
 | |
|                 child->setParent(parent);
 | |
|             parent->left() = child;
 | |
| 
 | |
|             node->right() = old->right();
 | |
|             old->right()->setParent(node);
 | |
|         }
 | |
| 
 | |
|         node->setParent(old->getParent());
 | |
|         node->setColor(old->getColor());
 | |
|         node->left() = old->left();
 | |
|         old->left()->setParent(node);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         child  = node->left() ? node->right() : node->left();
 | |
|         parent = node->getParent();
 | |
|         color  = node->getColor();
 | |
| 
 | |
|         if (child)
 | |
|             child->setParent(parent);
 | |
|         if (parent)
 | |
|         {
 | |
|             if (parent->left() == node)
 | |
|                 parent->left() = child;
 | |
|             else
 | |
|                 parent->right() = child;
 | |
|         }
 | |
|         else
 | |
|             m_root = child;
 | |
|     }
 | |
| 
 | |
|     if (color == N::Black)
 | |
|         recolor(parent, child);
 | |
| }
 |