Skip to content

Commit

Permalink
refactor(application): internals (#43)
Browse files Browse the repository at this point in the history
Signed-off-by: Tony Gorez <[email protected]>
  • Loading branch information
tony-go authored Nov 20, 2024
1 parent 6385b8a commit 0425947
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 55 deletions.
41 changes: 28 additions & 13 deletions src/application/appkit/app_appkit.mm
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,38 @@
#import <AppKit/AppKit.h>
#import <Cocoa/Cocoa.h>

#include <functional>
#include <iostream>

namespace {
sourcemeta::native::Application *instance_{nullptr};
}

namespace sourcemeta::native {

class Application::Internal {
public:
Internal() = default;
~Internal() = default;

auto run_application(std::function<void()> on_start) -> void {
NSApplication *application = [NSApplication sharedApplication];
AppDelegate *delegate = [[AppDelegate alloc] init];
[application setDelegate:delegate];
[application run];

on_start();
}

auto terminate() -> void { [NSApp terminate:nil]; }
};

Application::Application() {
assert(!instance_);
instance_ = this;
}

Application::~Application() {
if (internal_) {
CFBridgingRelease(internal_);
}
instance_ = nullptr;
}
Application::~Application() { instance_ = nullptr; }

Application &Application::instance() {
assert(instance_);
Expand All @@ -33,13 +47,14 @@
assert(!running_);
running_ = true;

on_start();
internal_->run_application([this]() {
try {
on_start();
} catch (...) {
on_error(std::current_exception());
}
});

NSApplication *application = [NSApplication sharedApplication];
AppDelegate *delegate = [[AppDelegate alloc] init];
internal_ = const_cast<void *>(CFBridgingRetain(delegate));
[application setDelegate:delegate];
[application run];
return EXIT_SUCCESS;
}

Expand All @@ -61,7 +76,7 @@
assert(running_);

if (code == 0) {
[NSApp terminate:nil];
internal_->terminate();
}

std::exit(code);
Expand Down
16 changes: 14 additions & 2 deletions src/application/console/app_console.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,23 @@

#include <cassert>

namespace {
sourcemeta::native::Application *instance_{nullptr};
}

namespace sourcemeta::native {

Application::Application() {}
Application::Application() {
assert(!instance_);
instance_ = this;
}

Application::~Application() {}
Application::~Application() { instance_ = nullptr; }

Application &Application::instance() {
assert(instance_);
return *instance_;
}

auto Application::run() noexcept -> int {
assert(!running_);
Expand Down
7 changes: 1 addition & 6 deletions src/application/foundation/app_foundation.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@
instance_ = this;
}

Application::~Application() {
if (internal_) {
CFBridgingRelease(internal_);
}
instance_ = nullptr;
}
Application::~Application() { instance_ = nullptr; }

Application &Application::instance() {
assert(instance_);
Expand Down
4 changes: 2 additions & 2 deletions src/application/include/sourcemeta/native/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ class Application {
// Internal types is used to store the platform-specific instance of the
// application. Each platform will have its own implementation and will
// store the instance in a different way, managing memory and resources.
using Internal = void *;
class Internal;

Internal internal_;
Internal *internal_;

bool running_{false};

Expand Down
48 changes: 33 additions & 15 deletions src/application/win32/app_win32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,41 @@ sourcemeta::native::Application *instance_{nullptr};

namespace sourcemeta::native {

class Application::Internal {
public:
auto setup() -> void {
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
}

auto start_loop() -> int {
MSG msg = {};
BOOL ret = 0;
while ((ret = GetMessage(&msg, NULL, 0, 0) != 0)) {
if (ret == -1) {
// The error is coming from GetMessage().
throw std::runtime_error(
"Failed to retrieve message from the message queue");
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return static_cast<int>(msg.wParam);
}

auto quit(const int code) -> void { PostQuitMessage(code); }
};

Application::Application() {
assert(!instance_);
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
instance_ = this;
internal_->setup();
}

Application::~Application() { instance_ = nullptr; }
Application::~Application() {
internal_ = new Application::Internal();
instance_ = nullptr;
}

Application &Application::instance() {
assert(instance_);
Expand All @@ -38,19 +66,9 @@ auto Application::run() noexcept -> int {
this->on_error(std::current_exception());
}

MSG msg = {};
BOOL ret = 0;
while ((ret = GetMessage(&msg, NULL, 0, 0) != 0)) {
if (ret == -1) {
// The error is coming from GetMessage().
throw std::runtime_error(
"Failed to retrieve message from the message queue");
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
int code = internal_->start_loop();

return static_cast<int>(msg.wParam);
return code;
}

auto Application::on_error(std::exception_ptr error) -> void {
Expand All @@ -69,7 +87,7 @@ auto Application::on_error(std::exception_ptr error) -> void {

auto Application::exit(const int code) const noexcept -> void {
assert(running_);
PostQuitMessage(code);
internal_->quit(code);
}

} // namespace sourcemeta::native
42 changes: 25 additions & 17 deletions src/ui/webview/win32/webview_win32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,29 +68,37 @@ class WebView::Internal {
this->parent_ = static_cast<HWND *>(parent);
}

auto create_controller(ICoreWebView2Environment *env,
std::function<void()> callback) -> void {
env->CreateCoreWebView2Controller(
*this->parent_,
Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
[this, callback](HRESULT result,
ICoreWebView2Controller *controller) -> HRESULT {
assert(result == S_OK);

this->controller = controller;
this->controller->get_CoreWebView2(&this->webview);

// Set internals to ready
this->ready = true;

callback();
return S_OK;
})
.Get());
}

auto create_webview(std::function<void()> callback) -> void {
CreateCoreWebView2EnvironmentWithOptions(
nullptr, nullptr, nullptr,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
[this, callback](HRESULT result,
ICoreWebView2Environment *env) -> HRESULT {
env->CreateCoreWebView2Controller(
*this->parent_,
Callback<
ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
[this, callback](
HRESULT result,
ICoreWebView2Controller *controller) -> HRESULT {
this->controller = controller;
this->controller->get_CoreWebView2(&this->webview);

// Set internals to ready
this->ready = true;

callback();
return S_OK;
})
.Get());
assert(result == S_OK);

this->create_controller(env, callback);

return S_OK;
})
.Get());
Expand Down

0 comments on commit 0425947

Please sign in to comment.