Files
Xenia-Canary/src/xenia/ui/loop_gtk.cc
gibbed 5bf0b34445 C++17ification.
C++17ification!

- Filesystem interaction now uses std::filesystem::path.
- Usage of const char*, std::string have been changed to
  std::string_view where appropriate.
- Usage of printf-style functions changed to use fmt.
2020-04-07 16:09:41 -05:00

82 lines
2.1 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/loop_gtk.h"
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include "xenia/base/assert.h"
namespace xe {
namespace ui {
class PostedFn {
public:
explicit PostedFn(std::function<void()> fn) : fn_(std::move(fn)) {}
void Call() { fn_(); }
private:
std::function<void()> fn_;
};
std::unique_ptr<Loop> Loop::Create() { return std::make_unique<GTKLoop>(); }
GTKLoop::GTKLoop() : thread_id_() {
gtk_init(nullptr, nullptr);
xe::threading::Fence init_fence;
thread_ = std::thread([&init_fence, this]() {
xe::threading::set_name("GTK Loop");
thread_id_ = std::this_thread::get_id();
init_fence.Signal();
ThreadMain();
quit_fence_.Signal();
});
init_fence.Wait();
}
GTKLoop::~GTKLoop() {
Quit();
thread_.join();
}
void GTKLoop::ThreadMain() { gtk_main(); }
bool GTKLoop::is_on_loop_thread() {
return thread_id_ == std::this_thread::get_id();
}
gboolean _posted_fn_thunk(gpointer posted_fn) {
PostedFn* Fn = reinterpret_cast<PostedFn*>(posted_fn);
Fn->Call();
return G_SOURCE_REMOVE;
}
void GTKLoop::Post(std::function<void()> fn) {
assert_true(thread_id_ != std::thread::id());
gdk_threads_add_idle(_posted_fn_thunk,
reinterpret_cast<gpointer>(new PostedFn(std::move(fn))));
}
void GTKLoop::PostDelayed(std::function<void()> fn, uint64_t delay_millis) {
gdk_threads_add_timeout(
delay_millis, _posted_fn_thunk,
reinterpret_cast<gpointer>(new PostedFn(std::move(fn))));
}
void GTKLoop::Quit() { assert_true(thread_id_ != std::thread::id()); }
void GTKLoop::AwaitQuit() { quit_fence_.Wait(); }
} // namespace ui
} // namespace xe