0

Context : I'm developing my own graphic engine. I'm trying to follow the SOLID principles and rely on polymorphism and virtual inheritance as much as I can to get a generic interface for different modules of my engine (window, user configuration, input).

Goal : I want my program to be able to display a window in a generic way and returning me a pointer to a window, regardless of the library used, a pointer that I can then use in the rest of my program. So far I have tried working with GLFW, SFML and SDL and have managed to successfully display a window with an interface like this :

// Prototypes
// IWindow.h
class IWindow
{
  protected:
    void* pWindow;
    bool isOpen;
  public:
    IWindow() : pWindow(nullptr), isOpen(true) {}
    virtual void getEvent() = 0;
    virtual void create(int,int) = 0;
    virtual bool windowShouldClose() {return this->isOpen;};
    virtual ~IWindow(){};
};

// GLFWindow.h
#include "IWindow.h"
class GLFWindow : public IWindow
{
  public:
    GLFWindow();
    void create(int,int) override final;
    void getEvent() override final;
    ~GLFWindow(){};
};

// Implementations
// GLFWindow.cpp

#include "GLFWindow.h"
#include <GLFW/glfw3.h>

void GLFWindow::create(int height,int width)
{
    glfwInit();
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
    pWindow = static_cast<void*>(glfwCreateWindow(height, width, "Vulkan", nullptr, nullptr));

};

void GLFWindow::getEvent()
{
    glfwPollEvents();
    this->isOpen = !glfwWindowShouldClose(static_cast<GLFWwindow*>(pWindow));
}

// Implementations for SDL and SFML quite similar....

// main.cpp

    //[...] creation of windowManager which is a pointer of type IWindow

    windowManager->create(config->window_w,config->window_h); // width and height of window

    while (windowManager->windowShouldClose()) //loopEvent
    {
        windowManager->getEvent();
    }

The library is chosed through a string in a YAML file, among GLFW, SDL and SFML.

Problem : I chose to rely on a void pointer for the window pointer to not depend on any of the library implementations (GLFWindow*, SDL_Window* for instance). The downside of that is I have to cast the window pointer to a void pointer each time I want to work with the libraries. Ultimately, what I want is my create method to be able to return me a generic window pointer

auto window {windowManager->create(config->window_w,config->window_h)};

because right now I don't have access to the window pointer directly in my main.

What I've tried :

And then I got lost. I'm looking for guidance on how to tackle this problem regarding the path I've explored.

Coriolis
  • 396
  • 3
  • 10
  • 1
    A windows pointer will be an implementation specific detail, hide into a specific implementation of one of your windows classes (implementing the window interface). So if it is still "poking" out then your design isn't SOLID enough yet. – Pepijn Kramer Aug 13 '22 at 11:08
  • 1
    "let me access the original window pointer" That's the idea. You shouldn't be able to. Everything you do, you do via the Pimpl. – n. m. could be an AI Aug 13 '22 at 11:55
  • 1
    Shouldn't be obvious that each subclass naturally needs to define whatever window pointer is native to the subclass, and store it in the subclass itself, instead of everyone having to pile on the `void *` in the parent class? No more void pointers. No more ugly casts. – Sam Varshavchik Aug 13 '22 at 11:56
  • I understand your points. For sure, there is a better design. Even if I do that, how can I retrieve the pointer using the virtual method create that currently returns a void but I want it to return a GLFW pointer or a SDL pointer ? Do I need to rely on templates ? – Coriolis Aug 13 '22 at 16:21
  • No, the only (sane?) way to return a native window handle is to return a `void*` (or perhaps a wide enough integer). This is how it's done in multiplatform GUI toolkits that ride on top of X11 or WinAPI or whatever is in fashion this week for Mac OS X. – n. m. could be an AI Aug 13 '22 at 16:58

0 Answers0