Serenity Operating System
at hosted 302 lines 9.6 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#pragma once 28 29#include <AK/Assertions.h> 30#include <AK/NonnullRefPtr.h> 31#include <AK/Weakable.h> 32 33namespace Web { 34 35// FIXME: I wish I didn't have to forward declare these, but I can't seem to avoid 36// it if I still want to have for_each_in_subtree_of_type<U> inline here. 37class Node; 38class LayoutNode; 39template<typename T> 40bool is(const Node&); 41template<typename T> 42bool is(const LayoutNode&); 43 44template<typename T> 45class TreeNode : public Weakable<T> { 46public: 47 void ref() 48 { 49 ASSERT(m_ref_count); 50 ++m_ref_count; 51 } 52 53 void unref() 54 { 55 ASSERT(m_ref_count); 56 if (!--m_ref_count) { 57 if (m_next_sibling) 58 m_next_sibling->m_previous_sibling = m_previous_sibling; 59 if (m_previous_sibling) 60 m_previous_sibling->m_next_sibling = m_next_sibling; 61 T* next_child; 62 for (auto* child = m_first_child; child; child = next_child) { 63 next_child = child->m_next_sibling; 64 child->m_parent = nullptr; 65 child->unref(); 66 } 67 delete static_cast<T*>(this); 68 } 69 } 70 int ref_count() const { return m_ref_count; } 71 72 T* parent() { return m_parent; } 73 const T* parent() const { return m_parent; } 74 75 bool has_children() const { return m_first_child; } 76 T* next_sibling() { return m_next_sibling; } 77 T* previous_sibling() { return m_previous_sibling; } 78 T* first_child() { return m_first_child; } 79 T* last_child() { return m_last_child; } 80 const T* next_sibling() const { return m_next_sibling; } 81 const T* previous_sibling() const { return m_previous_sibling; } 82 const T* first_child() const { return m_first_child; } 83 const T* last_child() const { return m_last_child; } 84 85 int child_count() const 86 { 87 int count = 0; 88 for (auto* child = first_child(); child; child = child->next_sibling()) 89 ++count; 90 return count; 91 } 92 93 T* child_at_index(int index) 94 { 95 int count = 0; 96 for (auto* child = first_child(); child; child = child->next_sibling()) { 97 if (count == index) 98 return child; 99 ++count; 100 } 101 return nullptr; 102 } 103 104 const T* child_at_index(int index) const 105 { 106 return const_cast<TreeNode*>(this)->child_at_index(index); 107 } 108 109 bool is_ancestor_of(const TreeNode&) const; 110 111 void prepend_child(NonnullRefPtr<T> node); 112 void append_child(NonnullRefPtr<T> node); 113 NonnullRefPtr<T> remove_child(NonnullRefPtr<T> node); 114 void donate_all_children_to(T& node); 115 116 bool is_child_allowed(const T&) const { return true; } 117 118 T* next_in_pre_order() 119 { 120 if (first_child()) 121 return first_child(); 122 T* node; 123 if (!(node = next_sibling())) { 124 node = parent(); 125 while (node && !node->next_sibling()) 126 node = node->parent(); 127 if (node) 128 node = node->next_sibling(); 129 } 130 return node; 131 } 132 133 const T* next_in_pre_order() const 134 { 135 return const_cast<TreeNode*>(this)->next_in_pre_order(); 136 } 137 138 template<typename Callback> 139 IterationDecision for_each_in_subtree(Callback callback) const 140 { 141 if (callback(static_cast<const T&>(*this)) == IterationDecision::Break) 142 return IterationDecision::Break; 143 for (auto* child = first_child(); child; child = child->next_sibling()) { 144 if (child->for_each_in_subtree(callback) == IterationDecision::Break) 145 return IterationDecision::Break; 146 } 147 return IterationDecision::Continue; 148 } 149 150 template<typename Callback> 151 IterationDecision for_each_in_subtree(Callback callback) 152 { 153 if (callback(static_cast<T&>(*this)) == IterationDecision::Break) 154 return IterationDecision::Break; 155 for (auto* child = first_child(); child; child = child->next_sibling()) { 156 if (child->for_each_in_subtree(callback) == IterationDecision::Break) 157 return IterationDecision::Break; 158 } 159 return IterationDecision::Continue; 160 } 161 162 template<typename U, typename Callback> 163 IterationDecision for_each_in_subtree_of_type(Callback callback) 164 { 165 if (is<U>(static_cast<const T&>(*this))) { 166 if (callback(static_cast<U&>(*this)) == IterationDecision::Break) 167 return IterationDecision::Break; 168 } 169 for (auto* child = first_child(); child; child = child->next_sibling()) { 170 if (child->template for_each_in_subtree_of_type<U>(callback) == IterationDecision::Break) 171 return IterationDecision::Break; 172 } 173 return IterationDecision::Continue; 174 } 175 176 template<typename U, typename Callback> 177 IterationDecision for_each_in_subtree_of_type(Callback callback) const 178 { 179 if (is<U>(static_cast<const T&>(*this))) { 180 if (callback(static_cast<const U&>(*this)) == IterationDecision::Break) 181 return IterationDecision::Break; 182 } 183 for (auto* child = first_child(); child; child = child->next_sibling()) { 184 if (child->template for_each_in_subtree_of_type<U>(callback) == IterationDecision::Break) 185 return IterationDecision::Break; 186 } 187 return IterationDecision::Continue; 188 } 189 190protected: 191 TreeNode() {} 192 193private: 194 int m_ref_count { 1 }; 195 T* m_parent { nullptr }; 196 T* m_first_child { nullptr }; 197 T* m_last_child { nullptr }; 198 T* m_next_sibling { nullptr }; 199 T* m_previous_sibling { nullptr }; 200}; 201 202template<typename T> 203inline NonnullRefPtr<T> TreeNode<T>::remove_child(NonnullRefPtr<T> node) 204{ 205 ASSERT(node->m_parent == this); 206 207 if (m_first_child == node) 208 m_first_child = node->m_next_sibling; 209 210 if (m_last_child == node) 211 m_last_child = node->m_previous_sibling; 212 213 if (node->m_next_sibling) 214 node->m_next_sibling->m_previous_sibling = node->m_previous_sibling; 215 216 if (node->m_previous_sibling) 217 node->m_previous_sibling->m_next_sibling = node->m_next_sibling; 218 219 node->m_next_sibling = nullptr; 220 node->m_previous_sibling = nullptr; 221 node->m_parent = nullptr; 222 223 node->removed_from(static_cast<T&>(*this)); 224 225 node->unref(); 226 227 static_cast<T*>(this)->children_changed(); 228 229 return node; 230} 231 232template<typename T> 233inline void TreeNode<T>::append_child(NonnullRefPtr<T> node) 234{ 235 ASSERT(!node->m_parent); 236 237 if (!static_cast<T*>(this)->is_child_allowed(*node)) 238 return; 239 240 if (m_last_child) 241 m_last_child->m_next_sibling = node.ptr(); 242 node->m_previous_sibling = m_last_child; 243 node->m_parent = static_cast<T*>(this); 244 m_last_child = node.ptr(); 245 if (!m_first_child) 246 m_first_child = m_last_child; 247 node->inserted_into(static_cast<T&>(*this)); 248 (void)node.leak_ref(); 249 250 static_cast<T*>(this)->children_changed(); 251} 252 253template<typename T> 254inline void TreeNode<T>::prepend_child(NonnullRefPtr<T> node) 255{ 256 ASSERT(!node->m_parent); 257 258 if (!static_cast<T*>(this)->is_child_allowed(*node)) 259 return; 260 261 if (m_first_child) 262 m_first_child->m_previous_sibling = node.ptr(); 263 node->m_next_sibling = m_first_child; 264 node->m_parent = static_cast<T*>(this); 265 m_first_child = node.ptr(); 266 if (!m_last_child) 267 m_last_child = m_first_child; 268 node->inserted_into(static_cast<T&>(*this)); 269 (void)node.leak_ref(); 270 271 static_cast<T*>(this)->children_changed(); 272} 273 274template<typename T> 275inline void TreeNode<T>::donate_all_children_to(T& node) 276{ 277 for (T* child = m_first_child; child != nullptr;) { 278 T* next_child = child->m_next_sibling; 279 280 child->m_parent = nullptr; 281 child->m_next_sibling = nullptr; 282 child->m_previous_sibling = nullptr; 283 284 node.append_child(adopt(*child)); 285 child = next_child; 286 } 287 288 m_first_child = nullptr; 289 m_last_child = nullptr; 290} 291 292template<typename T> 293inline bool TreeNode<T>::is_ancestor_of(const TreeNode<T>& other) const 294{ 295 for (auto* ancestor = other.parent(); ancestor; ancestor = ancestor->parent()) { 296 if (ancestor == this) 297 return true; 298 } 299 return false; 300} 301 302}