- Started setting up a thread safe window manager

- Created thread & atomic structures
This commit is contained in:
2025-12-17 01:11:28 -05:00
parent 520a0e1363
commit aee4e340dd
41 changed files with 2179 additions and 428 deletions

View File

@@ -94,10 +94,7 @@ enum feature_ : uint32_t {
using featureset_t = bitfield<feature_count>;
using window_id = uint32_t;
using window_pool = object_pool<window*>;
struct config {
};
using window_pool = object_pool<unique_ptr<window>>;
// Public Members ======================================================================================================
@@ -115,11 +112,7 @@ enum feature_ : uint32_t {
return features.test(feature);
}
virtual window* create_window(const window::config& conf) = 0;
window* get_window(size_t id) {
return id == window::nullid ? nullptr : windows[id];
}
virtual window* create_window(const window::config&, window* = nullptr) = 0;
virtual void connect() = 0;
virtual void disconnect() = 0;
@@ -135,7 +128,6 @@ enum feature_ : uint32_t {
protected:
featureset_t features;
window_pool windows;
unique_ptr<gfxcontext> gfx_context;
FENNEC_RTTI_CLASS_ENABLE() {

View File

@@ -19,9 +19,10 @@
#ifndef FENNEC_PLATFORM_INTERFACE_PLATFORM_H
#define FENNEC_PLATFORM_INTERFACE_PLATFORM_H
#include <fennec/platform/interface/display_server.h>
#include <fennec/string/cstring.h>
#include <fennec/platform/window_manager.h>
#include <fennec/rtti/enable.h>
#include <fennec/rtti/singleton.h>
#include <fennec/rtti/detail/_this_t.h>
@@ -79,10 +80,8 @@ public:
virtual void initialize(); // Initialize Drivers and Contexts
virtual void shutdown(); // Close Drivers and Contexts
display_server* get_display_server() { return display.get(); }
protected:
unique_ptr<display_server> display;
unique_ptr<window_manager> wmanager;
FENNEC_RTTI_CLASS_ENABLE() {
}

View File

@@ -39,6 +39,7 @@
#include <fennec/containers/bitfield.h>
#include <fennec/containers/optional.h>
#include <fennec/memory/pointers.h>
namespace fennec
{
@@ -112,20 +113,14 @@ public:
double_t fractional_scaling;
};
window(display_server* server, size_t id, const config& conf)
: server(server), id(id)
, cfg(conf), state(), root(nullptr) {
state.mode = conf.mode;
}
window(display_server* server, const config& conf, window* parent);
virtual ~window() = default;
size_t get_id() const { return id; }
size_t get_parent_id() const { return cfg.parent; }
virtual ~window();
const config& get_config() const { return cfg; }
window* get_parent() const;
window* get_parent() const { return parent; }
window* get_root() const { return root; }
const ivec2& get_size() const { return state.rect.size; }
const ivec2& get_position() const { return state.rect.position; }
@@ -135,7 +130,6 @@ public:
int get_pos_x() const { return state.rect.position.x; }
int get_pos_y() const { return state.rect.position.y; }
bool is_visible() const { return state.flags.test(state_visible); }
bool is_child() const { return state.flags.test(state_child); }
bool is_running() const { return state.flags.test(state_running); }
@@ -173,19 +167,19 @@ public:
virtual void* get_native_handle() = 0;
protected:
display_server* const server;
const size_t id;
config cfg;
state state;
window* root;
gfxsurface* gfx_surface;
display_server* const server;
window* const parent;
config cfg;
state state;
window* root;
unique_ptr<gfxsurface> gfx_surface;
};
template<typename DisplayT>
class window_base : public window {
public:
window_base(display_server* display, size_t id, const config& conf)
: window(display, id, conf) {
window_base(display_server* display, const config& conf, window* parent)
: window(display, conf, parent) {
}
using display_t = DisplayT;

View File

@@ -64,7 +64,7 @@ public:
void dispatch() override;
window* create_window(const window::config& conf) override;
window* create_window(const window::config& conf, window* parent) override;
void* get_native_handle() override { return display; }

View File

@@ -50,7 +50,7 @@ namespace fennec
class wayland_window : public window_base<wayland_server> {
public:
wayland_window(display_server* server, uint32_t id, const config& cfg);
wayland_window(display_server* server, const config& cfg, window* parent);
~wayland_window();
void initialize() override;

View File

@@ -0,0 +1,91 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/platform/window_manager.h>
#include <fennec/core/logger.h>
#include <fennec/platform/interface/platform.h>
#include <fennec/platform/interface/display_server.h>
#include <fennec/platform/interface/window.h>
namespace fennec {
window_manager::window_manager(platform* platform)
: _platform(platform) {
}
window_manager::~window_manager() {
shutdown();
}
void window_manager::initialize() {
if (_display) {
return;
}
// Get the list of registered display servers
display_server::entrylist_t display_servers = display_server::get_type_list();
// Find first valid server
while (not display_servers.empty()) {
display_server::entry it = display_servers.front();
display_servers.pop();
unique_ptr<display_server> server = unique_ptr(it.ctor(_platform));
server->connect();
if (server->connected()) {
logger::log(format("Selected {} for the display server.", server->get_type().name()));
_display = move(server);
break;
}
}
assertf(_display, "Failed to select a display server!");
_thread = thread::current();
logger::log(format("Initializing Window Manager on thread: {:#016x}.", _thread));
}
void window_manager::shutdown() {
if (not _display) {
return;
}
assertf(_thread == thread::current(), "Attempted to shutdown Window Manager on a different thread!");
// Cleanup Windows
for (auto& window : _windows) {
window->shutdown();
window.reset();
}
_windows.clear();
// Cleanup Display Server
_display->disconnect();
_display.reset();
}
void window_manager::dispatch() {
assertf(_thread == thread::current(), "Attempted to shutdown Window Manager on a different thread!");
_display->dispatch();
}
} // fennec

View File

@@ -29,20 +29,52 @@
///
#ifndef FENNEC_PLATFORM_WINDOW_MANAGER_H
#define FENNEC_PLATFORM_WINDOW_MANAGER_H
#ifndef FENNEC_PLATFORM_WINDOWMANAGER_H
#define FENNEC_PLATFORM_WINDOWMANAGER_H
#include <fennec/platform/interface/fwd.h>
#include <fennec/memory/pointers.h>
#include <fennec/containers/object_pool.h>
#include <fennec/threading/thread.h>
namespace fennec
{
///
/// \brief Thread-Safe wrapper for `display_server` and `window`
class window_manager {
// Definitions =========================================================================================================
private:
using server_t = unique_ptr<display_server>;
using window_t = unique_ptr<window>;
using window_pool_t = object_pool<window_t>;
// Constructors & Destructor ===========================================================================================
public:
window_manager(platform* platform);
~window_manager();
window_manager(const window_manager&) = delete;
// Thread-Specific Functions ===========================================================================================
void initialize();
void shutdown();
void dispatch();
// Thread-Safe Functions ===============================================================================================
private:
thread::id _thread;
platform* _platform;
server_t _display;
window_pool_t _windows;
};
}
} // fennec
#endif // FENNEC_PLATFORM_WINDOW_MANAGER_H
#endif // FENNEC_PLATFORM_WINDOWMANAGER_H