Независимость рендера и оконных систем с подключением через оконную ручку - PullRequest
1 голос
/ 30 марта 2012

Допустим, у нас есть интерфейс window_creator, который отвечает за создание окон. Для простоты это выглядит так:

struct window_creator
{
virtual ~window_creator(){}
handle create_window(size_t width, size_t height, bool fullscreen);
};

Также у нас есть интерфейс для системы рендеринга, который отвечает за рендеринг в окне, созданном window_creator. Для простоты он имеет следующий код:

struct render_system
{
virtual ~render_system(){}
void create(handle window_handle);
};

Также у нас есть 2 реализации интерфейса window_creator:

struct windows7_creator : public window_creator
{
handle create_window(size_t width, size_t height, bool fullscreen) override {
//calls CreateWindow and returns HWND
}
};

struct macos_creator : public window_creator
{
handle create_window(size_t width, size_t height, bool fullscreen) override {
//calls createWindow_ and returns WindowRef
}
};

И 2 реализации для интерфейса render_system:

struct dx_render_system : public render_system
{
    void create(handle window_handle) override{
    //calls CreateDevice, etc...
    }
};

struct opengl_render_system : public render_system
{
    void create(handle window_handle) override{
    //calls gl... etc...
    }
};

Теперь на платформе Windows я могу создавать DX или OpenGL рендерер. И на MacOs я могу создать рендерер OpenGL. Вопрос в том, какой тип дескриптора мне следует создать для поддержки независимости интерфейсов window_creator и render_system?

В моей текущей реализации я написал typedef для дескриптора:

typedef void* handle;

Есть ли более элегантное решение этой проблемы?

Ответы [ 2 ]

2 голосов
/ 30 марта 2012

Обычно такого рода действия выполняются по следующей схеме:

#ifdef OS_IS_WINDOWS

    #include "WindowsHandle.h"

    typedef WindowsHandle NativeHandle;

#elif OS_IS_MAC

    #include "MacHandle.h"

    typedef MacHandle NativeHandle;

#elif OS_IS_FOO

    #include "FooHandle.h"

    typedef FooHandle NativeHandle;

#end

Вам не нужно выполнять диспетчеризацию различных NativeHandles во время выполнения - и фактически без ущерба для безопасности типов это практически невозможно - так как определение дескрипторов, специфичных для платформы, доступно не на каждой платформе.

Вы уже знаете статически во время компиляции, в какой операционной системе вы находитесь, так что вы также можете воспользоваться этим.

0 голосов
/ 30 марта 2012

Вы не должны использовать ручки вообще.Дескрипторы (в этом контексте) - это трюк, используемый не-ОО языками для поддержки классов.

Но C ++ поддерживает классы.Поэтому используйте их.

class window {
    // …
    virtual ~window() = 0;
};

class windows_window : window { … };

class cocoa_window : window { … };

Эти классы являются объектами RAII, управляющими необработанными ресурсами дескрипторов и обеспечивающими удобные интерфейсы для соответствующих оконных функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...