diff options
author | Andreas Kling <kling@serenityos.org> | 2022-09-07 20:30:31 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-09-07 20:30:31 +0200 |
commit | 9567e211e7c0ae27a65c1f23c4fd9071e8c35e29 (patch) | |
tree | d0de19021f93a4ffa604c9a1e51218dbe3aa2e9d | |
parent | 7e5a8bd4b04963325e219c0cbb4c629a456c6fbc (diff) | |
download | serenity-9567e211e7c0ae27a65c1f23c4fd9071e8c35e29.zip |
LibWeb+WebContent: Add abstraction layer for event loop and timers
Instead of using Core::EventLoop and Core::Timer directly, LibWeb now
goes through a Web::Platform abstraction layer instead.
This will allow us to plug in Qt's event loop (and QTimer) over in
Ladybird, to avoid having to deal with multiple event loops.
28 files changed, 365 insertions, 42 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 0e7dfaa0f0..079311fe98 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -351,6 +351,8 @@ set(SOURCES Painting/ShadowPainting.cpp Painting/StackingContext.cpp Painting/TextPaintable.cpp + Platform/EventLoopPlugin.cpp + Platform/Timer.cpp RequestIdleCallback/IdleDeadline.cpp ResizeObserver/ResizeObserver.cpp SVG/AttributeNames.cpp diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 43a88e19ed..5de2904b39 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -10,7 +10,6 @@ #include <AK/CharacterTypes.h> #include <AK/StringBuilder.h> #include <AK/Utf8View.h> -#include <LibCore/Timer.h> #include <LibJS/Interpreter.h> #include <LibJS/Parser.h> #include <LibJS/Runtime/FunctionObject.h> @@ -67,6 +66,7 @@ #include <LibWeb/Layout/TreeBuilder.h> #include <LibWeb/Namespace.h> #include <LibWeb/Page/Page.h> +#include <LibWeb/Platform/Timer.h> #include <LibWeb/SVG/TagNames.h> #include <LibWeb/UIEvents/EventNames.h> #include <LibWeb/UIEvents/FocusEvent.h> @@ -286,11 +286,11 @@ Document::Document(HTML::Window& window, const AK::URL& url) HTML::main_thread_event_loop().register_document({}, *this); - m_style_update_timer = Core::Timer::create_single_shot(0, [this] { + m_style_update_timer = Platform::Timer::create_single_shot(0, [this] { update_style(); }); - m_layout_update_timer = Core::Timer::create_single_shot(0, [this] { + m_layout_update_timer = Platform::Timer::create_single_shot(0, [this] { force_layout(); }); } diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 894e9011d9..6eda355046 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -386,8 +386,8 @@ private: Optional<Color> m_active_link_color; Optional<Color> m_visited_link_color; - RefPtr<Core::Timer> m_style_update_timer; - RefPtr<Core::Timer> m_layout_update_timer; + RefPtr<Platform::Timer> m_style_update_timer; + RefPtr<Platform::Timer> m_layout_update_timer; RefPtr<HTML::HTMLParser> m_parser; bool m_active_parser_was_aborted { false }; diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 1c7718b722..8b4ec2d74c 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -351,6 +351,10 @@ struct BorderRadiiData; struct LinearGradientData; } +namespace Web::Platform { +class Timer; +} + namespace Web::RequestIdleCallback { class IdleDeadline; } diff --git a/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.h b/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.h index 397ab1f3e6..510b2c449c 100644 --- a/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.h +++ b/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.h @@ -8,8 +8,8 @@ #include <AK/Function.h> #include <AK/IDAllocator.h> -#include <LibCore/Timer.h> #include <LibWeb/HTML/EventLoop/EventLoop.h> +#include <LibWeb/Platform/Timer.h> namespace Web::HTML { @@ -18,7 +18,7 @@ struct AnimationFrameCallbackDriver { AnimationFrameCallbackDriver() { - m_timer = Core::Timer::create_single_shot(16, [] { + m_timer = Platform::Timer::create_single_shot(16, [] { HTML::main_thread_event_loop().schedule(); }); } @@ -57,7 +57,7 @@ struct AnimationFrameCallbackDriver { private: HashMap<i32, Callback> m_callbacks; IDAllocator m_id_allocator; - RefPtr<Core::Timer> m_timer; + RefPtr<Platform::Timer> m_timer; }; } diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index d92e1532e3..28fdb48a01 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -229,7 +229,7 @@ BrowsingContext::BrowsingContext(Page& page, HTML::BrowsingContextContainer* con , m_event_handler({}, *this) , m_container(container) { - m_cursor_blink_timer = Core::Timer::construct(500, [this] { + m_cursor_blink_timer = Platform::Timer::create_repeating(500, [this] { if (!is_focused_context()) return; if (m_cursor_position.node() && m_cursor_position.node()->layout_node()) { diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h index ddcd870ea1..1185caf3a9 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h @@ -10,7 +10,6 @@ #include <AK/Noncopyable.h> #include <AK/RefPtr.h> #include <AK/WeakPtr.h> -#include <LibCore/Timer.h> #include <LibGfx/Bitmap.h> #include <LibGfx/Rect.h> #include <LibGfx/Size.h> @@ -20,6 +19,7 @@ #include <LibWeb/HTML/SessionHistoryEntry.h> #include <LibWeb/Loader/FrameLoader.h> #include <LibWeb/Page/EventHandler.h> +#include <LibWeb/Platform/Timer.h> #include <LibWeb/TreeNode.h> namespace Web::HTML { @@ -148,7 +148,7 @@ private: Gfx::IntPoint m_viewport_scroll_offset; DOM::Position m_cursor_position; - RefPtr<Core::Timer> m_cursor_blink_timer; + RefPtr<Platform::Timer> m_cursor_blink_timer; bool m_cursor_blink_state { false }; HashTable<ViewportClient*> m_viewport_clients; diff --git a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp index 34978bc6c3..5602e5545d 100644 --- a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp +++ b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp @@ -5,8 +5,6 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include <LibCore/EventLoop.h> -#include <LibCore/Timer.h> #include <LibJS/Runtime/VM.h> #include <LibWeb/Bindings/MainThreadVM.h> #include <LibWeb/DOM/Document.h> @@ -15,6 +13,8 @@ #include <LibWeb/HTML/Scripting/Environments.h> #include <LibWeb/HTML/Window.h> #include <LibWeb/HighResolutionTime/Performance.h> +#include <LibWeb/Platform/EventLoopPlugin.h> +#include <LibWeb/Platform/Timer.h> namespace Web::HTML { @@ -29,7 +29,7 @@ EventLoop::~EventLoop() = default; void EventLoop::schedule() { if (!m_system_event_loop_timer) { - m_system_event_loop_timer = Core::Timer::create_single_shot(0, [this] { + m_system_event_loop_timer = Platform::Timer::create_single_shot(0, [this] { process(); }); } @@ -74,13 +74,7 @@ void EventLoop::spin_until(Function<bool()> goal_condition) // NOTE: This is achieved by returning from the function. // 1. Wait until the condition goal is met. - Core::EventLoop loop; - loop.spin_until([&]() -> bool { - if (goal_condition()) - return true; - - return goal_condition(); - }); + Platform::EventLoopPlugin::the().spin_until(move(goal_condition)); // 7. Stop task, allowing whatever algorithm that invoked it to resume. // NOTE: This is achieved by returning from the function. diff --git a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.h b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.h index 61685ae6d6..024666b992 100644 --- a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.h +++ b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.h @@ -84,7 +84,7 @@ private: JS::VM* m_vm { nullptr }; - RefPtr<Core::Timer> m_system_event_loop_timer; + RefPtr<Platform::Timer> m_system_event_loop_timer; // https://html.spec.whatwg.org/#performing-a-microtask-checkpoint bool m_performing_a_microtask_checkpoint { false }; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLBlinkElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLBlinkElement.cpp index c28d574fad..6bfa7806fd 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLBlinkElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLBlinkElement.cpp @@ -4,14 +4,14 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include <LibCore/Timer.h> #include <LibWeb/HTML/HTMLBlinkElement.h> +#include <LibWeb/Platform/Timer.h> namespace Web::HTML { HTMLBlinkElement::HTMLBlinkElement(DOM::Document& document, DOM::QualifiedName qualified_name) : HTMLElement(document, move(qualified_name)) - , m_timer(Core::Timer::construct()) + , m_timer(Platform::Timer::create()) { m_timer->set_interval(500); m_timer->on_timeout = [this] { blink(); }; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLBlinkElement.h b/Userland/Libraries/LibWeb/HTML/HTMLBlinkElement.h index 39bb55d611..43097c9cad 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLBlinkElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLBlinkElement.h @@ -22,7 +22,7 @@ private: void blink(); - NonnullRefPtr<Core::Timer> m_timer; + NonnullRefPtr<Platform::Timer> m_timer; }; } diff --git a/Userland/Libraries/LibWeb/HTML/Timer.cpp b/Userland/Libraries/LibWeb/HTML/Timer.cpp index b2e75fbdbc..228b514481 100644 --- a/Userland/Libraries/LibWeb/HTML/Timer.cpp +++ b/Userland/Libraries/LibWeb/HTML/Timer.cpp @@ -4,9 +4,9 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include <LibCore/Timer.h> #include <LibWeb/HTML/Timer.h> #include <LibWeb/HTML/Window.h> +#include <LibWeb/Platform/Timer.h> namespace Web::HTML { @@ -20,7 +20,7 @@ Timer::Timer(Window& window, i32 milliseconds, Function<void()> callback, i32 id , m_callback(move(callback)) , m_id(id) { - m_timer = Core::Timer::create_single_shot(milliseconds, [this] { + m_timer = Platform::Timer::create_single_shot(milliseconds, [this] { m_callback(); }); } diff --git a/Userland/Libraries/LibWeb/HTML/Timer.h b/Userland/Libraries/LibWeb/HTML/Timer.h index aa2edfb3f5..2f1aab762e 100644 --- a/Userland/Libraries/LibWeb/HTML/Timer.h +++ b/Userland/Libraries/LibWeb/HTML/Timer.h @@ -30,7 +30,7 @@ private: virtual void visit_edges(Cell::Visitor&) override; - RefPtr<Core::Timer> m_timer; + RefPtr<Platform::Timer> m_timer; JS::NonnullGCPtr<Window> m_window; Function<void()> m_callback; i32 m_id { 0 }; diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h index e1ce9e953b..587cc8616f 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.h +++ b/Userland/Libraries/LibWeb/HTML/Window.h @@ -8,7 +8,9 @@ #include <AK/Badge.h> #include <AK/IDAllocator.h> +#include <AK/NonnullRefPtrVector.h> #include <AK/RefPtr.h> +#include <AK/TypeCasts.h> #include <AK/URL.h> #include <LibJS/Heap/Heap.h> #include <LibWeb/Bindings/CrossOriginAbstractOperations.h> diff --git a/Userland/Libraries/LibWeb/Loader/ImageLoader.cpp b/Userland/Libraries/LibWeb/Loader/ImageLoader.cpp index dc4e3f3544..ecbe258b40 100644 --- a/Userland/Libraries/LibWeb/Loader/ImageLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/ImageLoader.cpp @@ -5,18 +5,18 @@ */ #include <AK/Debug.h> -#include <LibCore/Timer.h> #include <LibGfx/Bitmap.h> #include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Element.h> #include <LibWeb/Loader/ImageLoader.h> #include <LibWeb/Loader/ResourceLoader.h> +#include <LibWeb/Platform/Timer.h> namespace Web { ImageLoader::ImageLoader(DOM::Element& owner_element) : m_owner_element(owner_element) - , m_timer(Core::Timer::construct()) + , m_timer(Platform::Timer::create()) { } diff --git a/Userland/Libraries/LibWeb/Loader/ImageLoader.h b/Userland/Libraries/LibWeb/Loader/ImageLoader.h index 23c5344b1f..03a00cd682 100644 --- a/Userland/Libraries/LibWeb/Loader/ImageLoader.h +++ b/Userland/Libraries/LibWeb/Loader/ImageLoader.h @@ -7,8 +7,8 @@ #pragma once #include <AK/Function.h> -#include <LibCore/Timer.h> #include <LibWeb/Loader/ImageResource.h> +#include <LibWeb/Platform/Timer.h> namespace Web { @@ -60,7 +60,7 @@ private: size_t m_current_frame_index { 0 }; size_t m_loops_completed { 0 }; LoadingState m_loading_state { LoadingState::Loading }; - NonnullRefPtr<Core::Timer> m_timer; + NonnullRefPtr<Platform::Timer> m_timer; size_t m_redirects_count { 0 }; }; diff --git a/Userland/Libraries/LibWeb/Loader/Resource.cpp b/Userland/Libraries/LibWeb/Loader/Resource.cpp index e5ac447050..79c54edcfa 100644 --- a/Userland/Libraries/LibWeb/Loader/Resource.cpp +++ b/Userland/Libraries/LibWeb/Loader/Resource.cpp @@ -6,12 +6,12 @@ #include <AK/Debug.h> #include <AK/Function.h> -#include <LibCore/EventLoop.h> #include <LibCore/MimeData.h> #include <LibTextCodec/Decoder.h> #include <LibWeb/HTML/HTMLImageElement.h> #include <LibWeb/Loader/Resource.h> #include <LibWeb/Loader/ResourceLoader.h> +#include <LibWeb/Platform/EventLoopPlugin.h> namespace Web { @@ -168,7 +168,7 @@ void ResourceClient::set_resource(Resource* resource) // This ensures that these callbacks always happen in a consistent way, instead of being invoked // synchronously in some cases, and asynchronously in others. if (resource->is_loaded() || resource->is_failed()) { - Core::deferred_invoke([this, strong_resource = NonnullRefPtr { *m_resource }] { + Platform::EventLoopPlugin::the().deferred_invoke([this, strong_resource = NonnullRefPtr { *m_resource }] { if (m_resource != strong_resource.ptr()) return; diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp index 98101888d8..d562506ac6 100644 --- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp @@ -9,14 +9,14 @@ #include <AK/Debug.h> #include <AK/JsonObject.h> #include <LibCore/ElapsedTimer.h> -#include <LibCore/EventLoop.h> #include <LibCore/File.h> -#include <LibCore/Timer.h> #include <LibWeb/Loader/ContentFilter.h> #include <LibWeb/Loader/LoadRequest.h> #include <LibWeb/Loader/ProxyMappings.h> #include <LibWeb/Loader/Resource.h> #include <LibWeb/Loader/ResourceLoader.h> +#include <LibWeb/Platform/EventLoopPlugin.h> +#include <LibWeb/Platform/Timer.h> #ifdef __serenity__ # include <serenity.h> @@ -179,7 +179,7 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has HashMap<String, String, CaseInsensitiveStringTraits> response_headers; response_headers.set("Content-Type", "text/html; charset=UTF-8"); - deferred_invoke([success_callback = move(success_callback), response_headers = move(response_headers)] { + Platform::EventLoopPlugin::the().deferred_invoke([success_callback = move(success_callback), response_headers = move(response_headers)] { success_callback(String::empty().to_byte_buffer(), response_headers, {}); }); return; @@ -206,7 +206,7 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has } log_success(request); - deferred_invoke([data = move(data), success_callback = move(success_callback)] { + Platform::EventLoopPlugin::the().deferred_invoke([data = move(data), success_callback = move(success_callback)] { success_callback(data, {}, {}); }); return; @@ -284,7 +284,7 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has } if (timeout.has_value() && timeout.value() > 0) { - auto timer = Core::Timer::create_single_shot(timeout.value(), nullptr); + auto timer = Platform::Timer::create_single_shot(timeout.value(), nullptr); timer->on_timeout = [timer, protocol_request, timeout_callback = move(timeout_callback)]() mutable { protocol_request->stop(); if (timeout_callback) @@ -312,7 +312,7 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has } log_success(request); success_callback(payload, response_headers, status_code); - deferred_invoke([this, &protocol_request] { + Platform::EventLoopPlugin::the().deferred_invoke([this, &protocol_request] { m_active_requests.remove(protocol_request); }); }; diff --git a/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.cpp b/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.cpp new file mode 100644 index 0000000000..dcd9b01b26 --- /dev/null +++ b/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/Function.h> +#include <LibWeb/Platform/EventLoopPlugin.h> + +namespace Web::Platform { + +EventLoopPlugin* s_the; + +EventLoopPlugin& EventLoopPlugin::the() +{ + VERIFY(s_the); + return *s_the; +} + +void EventLoopPlugin::install(EventLoopPlugin& plugin) +{ + VERIFY(!s_the); + s_the = &plugin; +} + +EventLoopPlugin::~EventLoopPlugin() = default; + +} diff --git a/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.h b/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.h new file mode 100644 index 0000000000..de08e14fb9 --- /dev/null +++ b/Userland/Libraries/LibWeb/Platform/EventLoopPlugin.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Forward.h> +#include <LibWeb/Forward.h> + +namespace Web::Platform { + +class EventLoopPlugin { +public: + static EventLoopPlugin& the(); + static void install(EventLoopPlugin&); + + virtual ~EventLoopPlugin(); + + virtual void spin_until(Function<bool()> goal_condition) = 0; + virtual void deferred_invoke(Function<void()>) = 0; + virtual NonnullRefPtr<Timer> create_timer() = 0; +}; + +} diff --git a/Userland/Libraries/LibWeb/Platform/Timer.cpp b/Userland/Libraries/LibWeb/Platform/Timer.cpp new file mode 100644 index 0000000000..d3de49a958 --- /dev/null +++ b/Userland/Libraries/LibWeb/Platform/Timer.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/NonnullRefPtr.h> +#include <LibWeb/Platform/EventLoopPlugin.h> +#include <LibWeb/Platform/Timer.h> + +namespace Web::Platform { + +Timer::~Timer() = default; + +NonnullRefPtr<Timer> Timer::create() +{ + return EventLoopPlugin::the().create_timer(); +} + +NonnullRefPtr<Timer> Timer::create_repeating(int interval_ms, Function<void()>&& timeout_handler) +{ + auto timer = EventLoopPlugin::the().create_timer(); + timer->set_single_shot(false); + timer->set_interval(interval_ms); + timer->on_timeout = move(timeout_handler); + return timer; +} + +NonnullRefPtr<Timer> Timer::create_single_shot(int interval_ms, Function<void()>&& timeout_handler) +{ + auto timer = EventLoopPlugin::the().create_timer(); + timer->set_single_shot(true); + timer->set_interval(interval_ms); + timer->on_timeout = move(timeout_handler); + return timer; +} + +} diff --git a/Userland/Libraries/LibWeb/Platform/Timer.h b/Userland/Libraries/LibWeb/Platform/Timer.h new file mode 100644 index 0000000000..bde3ca3f3a --- /dev/null +++ b/Userland/Libraries/LibWeb/Platform/Timer.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Function.h> +#include <AK/RefCounted.h> + +namespace Web::Platform { + +class Timer : public RefCounted<Timer> { +public: + static NonnullRefPtr<Timer> create(); + static NonnullRefPtr<Timer> create_repeating(int interval_ms, Function<void()>&& timeout_handler); + static NonnullRefPtr<Timer> create_single_shot(int interval_ms, Function<void()>&& timeout_handler); + + virtual ~Timer(); + + virtual void start() = 0; + virtual void start(int interval_ms) = 0; + virtual void restart() = 0; + virtual void restart(int interval_ms) = 0; + virtual void stop() = 0; + + virtual void set_active(bool) = 0; + + virtual bool is_active() const = 0; + virtual int interval() const = 0; + virtual void set_interval(int interval_ms) = 0; + + virtual bool is_single_shot() const = 0; + virtual void set_single_shot(bool) = 0; + + Function<void()> on_timeout; +}; + +} diff --git a/Userland/Services/WebContent/CMakeLists.txt b/Userland/Services/WebContent/CMakeLists.txt index 3ec41acdb5..8327b15562 100644 --- a/Userland/Services/WebContent/CMakeLists.txt +++ b/Userland/Services/WebContent/CMakeLists.txt @@ -10,11 +10,13 @@ compile_ipc(WebContentClient.ipc WebContentClientEndpoint.h) set(SOURCES ConnectionFromClient.cpp ConsoleGlobalObject.cpp - main.cpp + EventLoopPluginSerenity.cpp PageHost.cpp + TimerSerenity.cpp + WebContentClientEndpoint.h WebContentConsoleClient.cpp WebContentServerEndpoint.h - WebContentClientEndpoint.h + main.cpp ) serenity_bin(WebContent) diff --git a/Userland/Services/WebContent/EventLoopPluginSerenity.cpp b/Userland/Services/WebContent/EventLoopPluginSerenity.cpp new file mode 100644 index 0000000000..15a6c17dd1 --- /dev/null +++ b/Userland/Services/WebContent/EventLoopPluginSerenity.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "EventLoopPluginSerenity.h" +#include "TimerSerenity.h" +#include <AK/Function.h> +#include <AK/NonnullRefPtr.h> +#include <LibCore/EventLoop.h> + +namespace WebContent { + +EventLoopPluginSerenity::EventLoopPluginSerenity() = default; +EventLoopPluginSerenity::~EventLoopPluginSerenity() = default; + +void EventLoopPluginSerenity::spin_until(Function<bool()> goal_condition) +{ + Core::EventLoop::current().spin_until(move(goal_condition)); +} + +void EventLoopPluginSerenity::deferred_invoke(Function<void()> function) +{ + VERIFY(function); + Core::deferred_invoke(move(function)); +} + +NonnullRefPtr<Web::Platform::Timer> EventLoopPluginSerenity::create_timer() +{ + return TimerSerenity::create(); +} + +} diff --git a/Userland/Services/WebContent/EventLoopPluginSerenity.h b/Userland/Services/WebContent/EventLoopPluginSerenity.h new file mode 100644 index 0000000000..0493ac7ab1 --- /dev/null +++ b/Userland/Services/WebContent/EventLoopPluginSerenity.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibWeb/Platform/EventLoopPlugin.h> + +namespace WebContent { + +class EventLoopPluginSerenity final : public Web::Platform::EventLoopPlugin { +public: + EventLoopPluginSerenity(); + virtual ~EventLoopPluginSerenity() override; + + virtual void spin_until(Function<bool()> goal_condition) override; + virtual void deferred_invoke(Function<void()>) override; + virtual NonnullRefPtr<Web::Platform::Timer> create_timer() override; +}; + +} diff --git a/Userland/Services/WebContent/TimerSerenity.cpp b/Userland/Services/WebContent/TimerSerenity.cpp new file mode 100644 index 0000000000..a702ba2eca --- /dev/null +++ b/Userland/Services/WebContent/TimerSerenity.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "TimerSerenity.h" +#include <AK/NonnullRefPtr.h> +#include <LibCore/Timer.h> + +namespace WebContent { + +NonnullRefPtr<TimerSerenity> TimerSerenity::create() +{ + return adopt_ref(*new TimerSerenity); +} + +TimerSerenity::TimerSerenity() + : m_timer(Core::Timer::construct()) +{ + m_timer->on_timeout = [this] { + if (on_timeout) + on_timeout(); + }; +} + +TimerSerenity::~TimerSerenity() = default; + +void TimerSerenity::start() +{ + m_timer->start(); +} + +void TimerSerenity::start(int interval_ms) +{ + m_timer->start(interval_ms); +} + +void TimerSerenity::restart() +{ + m_timer->restart(); +} + +void TimerSerenity::restart(int interval_ms) +{ + m_timer->restart(interval_ms); +} + +void TimerSerenity::stop() +{ + m_timer->stop(); +} + +void TimerSerenity::set_active(bool active) +{ + m_timer->set_active(active); +} + +bool TimerSerenity::is_active() const +{ + return m_timer->is_active(); +} + +int TimerSerenity::interval() const +{ + return m_timer->interval(); +} + +void TimerSerenity::set_interval(int interval_ms) +{ + m_timer->set_interval(interval_ms); +} + +bool TimerSerenity::is_single_shot() const +{ + return m_timer->is_single_shot(); +} + +void TimerSerenity::set_single_shot(bool single_shot) +{ + m_timer->set_single_shot(single_shot); +} + +} diff --git a/Userland/Services/WebContent/TimerSerenity.h b/Userland/Services/WebContent/TimerSerenity.h new file mode 100644 index 0000000000..d0f9200839 --- /dev/null +++ b/Userland/Services/WebContent/TimerSerenity.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/NonnullRefPtr.h> +#include <LibCore/Forward.h> +#include <LibWeb/Platform/Timer.h> + +namespace WebContent { + +class TimerSerenity final : public Web::Platform::Timer { +public: + static NonnullRefPtr<TimerSerenity> create(); + + virtual ~TimerSerenity(); + + virtual void start() override; + virtual void start(int interval_ms) override; + virtual void restart() override; + virtual void restart(int interval_ms) override; + virtual void stop() override; + + virtual void set_active(bool) override; + + virtual bool is_active() const override; + virtual int interval() const override; + virtual void set_interval(int interval_ms) override; + + virtual bool is_single_shot() const override; + virtual void set_single_shot(bool) override; + +private: + TimerSerenity(); + + NonnullRefPtr<Core::Timer> m_timer; +}; + +} diff --git a/Userland/Services/WebContent/main.cpp b/Userland/Services/WebContent/main.cpp index 9db9c3ed40..5a06e6e00c 100644 --- a/Userland/Services/WebContent/main.cpp +++ b/Userland/Services/WebContent/main.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include "EventLoopPluginSerenity.h" #include <LibCore/EventLoop.h> #include <LibCore/LocalServer.h> #include <LibCore/System.h> @@ -11,6 +12,7 @@ #include <LibMain/Main.h> #include <LibWeb/ImageDecoding.h> #include <LibWeb/Loader/ResourceLoader.h> +#include <LibWeb/Platform/EventLoopPlugin.h> #include <LibWeb/WebSockets/WebSocket.h> #include <LibWebView/ImageDecoderClientAdapter.h> #include <LibWebView/RequestServerAdapter.h> @@ -28,6 +30,8 @@ ErrorOr<int> serenity_main(Main::Arguments) TRY(Core::System::unveil("/tmp/user/%uid/portal/websocket", "rw")); TRY(Core::System::unveil(nullptr, nullptr)); + Web::Platform::EventLoopPlugin::install(*new WebContent::EventLoopPluginSerenity); + Web::ImageDecoding::Decoder::initialize(WebView::ImageDecoderClientAdapter::create()); Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create())); Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create())); |