| 
									
										
										
										
											2021-09-08 23:09:18 +02:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2024-10-04 13:19:50 +02:00
										 |  |  |  * Copyright (c) 2021-2024, Andreas Kling <andreas@ladybird.org> | 
					
						
							| 
									
										
										
										
											2021-09-08 23:09:18 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-04 12:06:50 +02:00
										 |  |  | #include <LibJS/Heap/MarkedVector.h>
 | 
					
						
							| 
									
										
										
										
											2021-09-09 00:38:43 +02:00
										 |  |  | #include <LibWeb/HTML/EventLoop/EventLoop.h>
 | 
					
						
							| 
									
										
										
										
											2021-09-08 23:09:18 +02:00
										 |  |  | #include <LibWeb/HTML/EventLoop/TaskQueue.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Web::HTML { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-06 10:16:04 -07:00
										 |  |  | JS_DEFINE_ALLOCATOR(TaskQueue); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 00:38:43 +02:00
										 |  |  | TaskQueue::TaskQueue(HTML::EventLoop& event_loop) | 
					
						
							|  |  |  |     : m_event_loop(event_loop) | 
					
						
							| 
									
										
										
										
											2021-09-08 23:09:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 13:21:51 -06:00
										 |  |  | TaskQueue::~TaskQueue() = default; | 
					
						
							| 
									
										
										
										
											2021-09-08 23:09:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-04 12:06:50 +02:00
										 |  |  | void TaskQueue::visit_edges(Visitor& visitor) | 
					
						
							| 
									
										
										
										
											2021-09-08 23:09:18 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-04 12:06:50 +02:00
										 |  |  |     Base::visit_edges(visitor); | 
					
						
							|  |  |  |     visitor.visit(m_event_loop); | 
					
						
							| 
									
										
										
										
											2024-04-15 13:58:21 +02:00
										 |  |  |     visitor.visit(m_tasks); | 
					
						
							| 
									
										
										
										
											2021-09-08 23:09:18 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-04 12:06:50 +02:00
										 |  |  | void TaskQueue::add(JS::NonnullGCPtr<Task> task) | 
					
						
							| 
									
										
										
										
											2021-10-03 15:38:11 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-04 12:06:50 +02:00
										 |  |  |     m_tasks.append(task); | 
					
						
							|  |  |  |     m_event_loop->schedule(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | JS::GCPtr<Task> TaskQueue::take_first_runnable() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_event_loop->execution_paused()) | 
					
						
							| 
									
										
										
										
											2022-11-15 15:27:58 -05:00
										 |  |  |         return nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-03 15:38:11 +02:00
										 |  |  |     for (size_t i = 0; i < m_tasks.size(); ++i) { | 
					
						
							| 
									
										
										
										
											2024-04-13 06:09:34 +02:00
										 |  |  |         if (m_tasks[i]->is_runnable()) | 
					
						
							| 
									
										
										
										
											2021-10-03 15:38:11 +02:00
										 |  |  |             return m_tasks.take(i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-03 18:23:25 +02:00
										 |  |  | bool TaskQueue::has_runnable_tasks() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-04 12:06:50 +02:00
										 |  |  |     if (m_event_loop->execution_paused()) | 
					
						
							| 
									
										
										
										
											2022-11-15 15:27:58 -05:00
										 |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-03 18:23:25 +02:00
										 |  |  |     for (auto& task : m_tasks) { | 
					
						
							|  |  |  |         if (task->is_runnable()) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 17:46:34 +02:00
										 |  |  | void TaskQueue::remove_tasks_matching(Function<bool(HTML::Task const&)> filter) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_tasks.remove_all_matching([&](auto& task) { | 
					
						
							|  |  |  |         return filter(*task); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-04 12:06:50 +02:00
										 |  |  | JS::MarkedVector<JS::NonnullGCPtr<Task>> TaskQueue::take_tasks_matching(Function<bool(HTML::Task const&)> filter) | 
					
						
							| 
									
										
										
										
											2023-04-04 09:06:10 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-04 12:06:50 +02:00
										 |  |  |     JS::MarkedVector<JS::NonnullGCPtr<Task>> matching_tasks(heap()); | 
					
						
							| 
									
										
										
										
											2023-04-04 09:06:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (size_t i = 0; i < m_tasks.size();) { | 
					
						
							|  |  |  |         auto& task = m_tasks.at(i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (filter(*task)) { | 
					
						
							| 
									
										
										
										
											2024-04-04 12:06:50 +02:00
										 |  |  |             matching_tasks.append(task); | 
					
						
							| 
									
										
										
										
											2023-04-04 09:06:10 -04:00
										 |  |  |             m_tasks.remove(i); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             ++i; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return matching_tasks; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-18 16:24:08 +01:00
										 |  |  | Task const* TaskQueue::last_added_task() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_tasks.is_empty()) | 
					
						
							|  |  |  |         return nullptr; | 
					
						
							|  |  |  |     return m_tasks.last(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-06 15:16:35 +02:00
										 |  |  | bool TaskQueue::has_rendering_tasks() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (auto const& task : m_tasks) { | 
					
						
							|  |  |  |         if (task->source() == Task::Source::Rendering) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-08 23:09:18 +02:00
										 |  |  | } |