#pragma once #include class wl_resource_t { public: wl_resource_t() {}; struct wl_display *display = nullptr; struct wl_client *client = nullptr; struct wl_resource *resource = nullptr; bool is_valid() { return (display != nullptr && client != nullptr && resource != nullptr); }; operator struct wl_resource*() { return resource; }; operator struct wl_client*(){ return client; }; template static void create(struct wl_client *client, uint32_t id) { type* res = new type; res->create(client, id, true); }; void create(struct wl_client *client_, uint32_t id, bool free_on_destroy) { init(); display = wl_client_get_display(client_); client = client_; resource = wl_resource_create(client, interface, version, id); if (resource == nullptr) { wl_client_post_no_memory(client); return; } wl_resource_set_implementation(resource, implementation, this, (free_on_destroy)?annihilate:nullptr); on_create(); }; template static void global_create(struct wl_display *display, void *data) { type i; i.init(); wl_global_create(display, i.interface, i.version, data, bind_global); }; template static void global_create(struct wl_display *display, wl_global_bind_func_t bind, void *data) { type i; i.init(); wl_global_create(display, i.interface, i.version, data, bind); }; void destroy() { if (is_valid()) { static_cast(wl_resource_get_user_data(resource))->on_destroy(); wl_resource_destroy(resource); display = nullptr; resource = nullptr; client = nullptr; } }; virtual void on_create() = 0; virtual void on_destroy() = 0; virtual void init() = 0; static void annihilate(struct wl_resource* resource) { wl_resource_t *res = static_cast(wl_resource_get_user_data(resource)); if (res != nullptr) delete res; }; uint32_t next_serial() { if (display == nullptr) return 0; return wl_display_next_serial(display); }; template static type* from_wl_resource(struct wl_resource *resource) { if (resource == nullptr) return static_cast(nullptr); return static_cast(wl_resource_get_user_data(resource)); }; virtual ~wl_resource_t() {}; private: void non_virtual_init() { init(); }; template static void bind_global(struct wl_client *client, void *data, uint32_t version, uint32_t id) { create(client, id); }; protected: uint32_t version; const void *implementation; const struct wl_interface *interface; }; struct wl_client_t: public wl_listener { public: struct wl_client* operator ()() { return client; }; virtual void on_destroy() = 0; virtual ~wl_client_t(); private: struct wl_client *client = nullptr; static void destroyed_callback(struct wl_listener *listener, void *data) { wl_client_t *c = static_cast(listener); if (c == nullptr) return; c->on_destroy(); delete c; }; };