Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / C++ Взаимодействие интерфейсов на уровне реализаций.

C++ Взаимодействие интерфейсов на уровне реализаций.

Поделиться

Страницы: 1 2 3 4 5 6 Следующая

-Eugene-Постоялецwww10 ноя. 20171:25#0
Иногда возникают случаи, когда реализовать взаимодействие двух иерархий можно только на уровне реализаций.
Например, алгоритмы определения коллизий в физических движках.
Есть иерархия типа AShape<-ASphere, ACapsule, AConvex и функция findCollision(AShape, AShape), а реализации в шести классах типа SphereSphereCollision и т.д.
Есть какой-то паттерн для реализации этого дела?
ZeroCool++Постоялецwww10 ноя. 20171:58#1
Множественная диспетчеризация. На плюсах вполне можно более или менее элегантно реализовать
SuslikМодераторwww10 ноя. 20172:00#2
-Eugene-
> Есть какой-то паттерн для реализации этого дела?
double dispatching, но реально коллижн детекшн так никто не делает.
FordPerfectПостоялецwww10 ноя. 20172:13#3
Suslik
Забавно что Мейерс именно определение столкновений (скорее игровая логика, чем физика: у него астероиды) приводил в качестве примера для использования двойной диспетчеризации.
И да - ИМХО у него востребованность получилась неубедительной.

А кстати - как делают?
В моих астероидах тупо квадратная таблица указателей на функции.

-Eugene-Постоялецwww10 ноя. 20172:13#4
ZeroCool++
Suslik
Спасибо! Не знал этого слова.
SuslikМодераторwww10 ноя. 20173:00#5
FordPerfect
> В моих астероидах тупо квадратная таблица указателей на функции.
обычно так и делают.
-Eugene-Постоялецwww10 ноя. 20173:01#6
Окей, я почитал и понял, что нафиг не надо.
SuslikМодераторwww10 ноя. 20173:07#7
вообще я эту проблему считаю принципиальной. в случае коллижнов ещё более-менее ясно, потому что количество типов взаимодействующих геометрий обычно ограничено. а как быть со случаями, которые by design подразумевают взаимодействие объектов одной системы на уровне интерфейсов? один из классических примеров — мультирендер. вызов, например, такой:
void IShader::BindTexture(std::string samplerName, ITexture *tex);
и если у нас мультирендер, то теоретически на этапе компиляции корректным будет код с созданием D3D::Shader и установкой ему OpenGL::Texture в качестве юниформа и что-то внутри где-то должно будет взорваться без вариантов, потому что с практической точки зрения установка OpenGL текстуры в D3D шейдер — нонсенс. разумеется, любое решение с dynamic_cast считается костылём и не рассматривается.

кто-то вместо интерфейсов использует просто интовые айдишники, кто-то — лёгкие обёртки с этими айдишниками, но всё это всегда плохо ложится на стандартный ооп-подход, потому что BindTexture() внутри себя обязан каким-то образом залезть внутрь реализации ITexture, что уже само противоречит ооп. ранние версии огра, которые позиционировали себя как тру-ооп мультирендер, для таких случаев вообще отказывались от передачи интерфейсов и использовали строковые именя для всего. то есть при создании каждой текстуры ей назначется строковое имя, а при байндинге в шейдер она также байндится не по указателю, а по этому имени. но и это, очевидно, решением проблемы не является, а является, скорее, её откладыванием.

Правка: 10 ноя. 2017 3:13

skalogryzПостоялецwww10 ноя. 20174:43#8
Suslik
> разумеется, любое решение с dynamic_cast считается костылём и не рассматривается
почему костыль и не рассматривается?

при таком api, это единственный способ убедиться, что перед тобой свой объект

альтернатива - не делать никакой санитарии, и пусть падает. Фиг ли - программист сам дурак, если пытался в DX BindTexture скормить что-нить из OpenGL.

+ Показать

Правка: 10 ноя. 2017 4:49

loysoПостоялецwww10 ноя. 20174:55#9
Suslik
> а как быть со случаями, которые by design подразумевают взаимодействие объектов
> одной системы на уровне интерфейсов?
Меня всегда умилял вот этот вот design подход, когда "код готов" на лету между OpenGL/DirectX переключаться (что неправда естественно).

> BindTexture() внутри себя обязан каким-то образом залезть внутрь реализации
> ITexture, что уже само противоречит ооп
Ты прямо в суть компромисса между cohesion и decoupling фиганул. ООП тут не особо причина.

В идеальном мире OGL/DX система должна быть "сплоченная внутри" без downcasts всяких и отцепляться от остального мира стабильным
интерфейсом в котором не будет текстур и шейдеров (другой уровень абстракции)

Если же все таки настоять на "изоморфности структуры для кишков и внешних представлений"
то я вижу простой подход: Когда у тебя есть дерево реальных OGL или DX объектов, аннотированное реальными типами.
И есть проекция этого дерева "наружу" с upcast типами (абстрактными).
А методы - они внешние и multiple dispatch/мультиметоды позволяют адекватно гулять по обоим графам
объектов в обоих мирах. Как если бы  С# static extension methods работали с dynamic и через границу dll.
Это чем-то https://en.wikipedia.org/wiki/Algebraic_data_type напоминать должно.
Глядя шире и с точки зрения computer science - это https://en.wikipedia.org/wiki/Expression_problem

В реальном мире кто в лес, кто по дрова и типично адский микс слоев cc/viz/skia
https://cs.chromium.org/chromium/src/components/viz/service/displ… ct_renderer.h
(можно кликать и все xref наследники покажутся и прочее)
Но ключевое: выделяют голые универсальные данные и универсальные языки command buffer.

loysoПостоялецwww10 ноя. 20175:04#10
loyso
> Expression_problem
К счастью проблема проще - нам можно рекомпилить. Но аспекты расширяемости те же.
skalogryzПостоялецwww10 ноя. 20175:11#11
loyso
> Меня всегда умилял вот этот вот design подход, когда "код готов" на лету между
> OpenGL/DirectX переключаться (что неправда естественно)
о! а я знаю одну такую либу, которая это без труда делает. И никаких тормозов.

loyso
> В идеальном мире OGL/DX система должна быть "сплоченная внутри" без downcasts
> всяких и отцепляться от остального мира стабильным
> интерфейсом в котором не будет текстур и шейдеров (другой уровень абстракции)
а не слишком ли высокий уровень этой самой абстракции получится?

Правка: 10 ноя. 2017 5:23

SuslikМодераторwww10 ноя. 20175:27#12
skalogryz
> почему костыль и не рассматривается?
вообще любой downcast считаю last resort костылём. если без него обойтись невозможно, то значит архитектура всё равно уже кривая.

loyso
> Меня всегда умилял вот этот вот design подход, когда "код готов" на лету между OpenGL/DirectX переключаться (что неправда естественно).
переключаться на лету — совершенно законное требование, которое совершенно неиллюзорно используется в продакшене. sharing ресурсов — это уже то, что хотелось бы не запрещать в рантайме, а сделать невозможным архитектурно, но в этом и сложность.

loyso
> А методы - они внешние и multiple dispatch/мультиметоды позволяют адекватно
> гулять по обоим графам
ты это реально где-то видел реализованное? покажи пример.

loyso
> Но ключевое: выделяют голые универсальные данные и универсальные языки command buffer
это понятно. с универсальными raw данными, которые будут одинаковыми для любого GAPI, как раз проблемы нет. проблемы начинаются там, где необходимо взаимодействие специфичных для GAPI объектов. я запасся попкорном и объявляю ежегодный фестиваль "мультирендер архитектурный астронавтинг - 2017" открытым.

Правка: 10 ноя. 2017 5:48

skalogryzПостоялецwww10 ноя. 20175:31#13
Suslik
> вообще любой upcast считаю last resort костылём. если без него обойтись
> невозможно, то значит архитектура всё равно уже кривая.
не понимаю причём тут upcast?
ты же пытаешься получить DXTexture от ITexture, а не наоборот.

...перечитал 7й пост...
не понимаю где здесь upcast.

loysoПостоялецwww10 ноя. 20175:36#14
Suslik
> вообще любой upcast считаю last resort костылём
downcast ты имел ввиду видимо (см boost::polymorphic_downcast к примеру)

Suslik
> переключаться на лету — совершенно законное требование, которое совершенно
> неиллюзорно используется в продакшене
Мы про разное "на лету" видимо. Я про переключение прямо посреди геймплея уровня.
Позднее связывание - такое позднее, да.

Suslik
> ты это реально где-то видел реализованное? покажи пример.
Оно же тупое как дрова - отдельно данные объектов, обьединенные связями.
Отдельно методы подсистем - физики или рендера там. Ну и дубово switch/case или if и своя Object System.
В open source - даже не знаю примера, давно не в лиге.
Посмотри идею спецификаций aruslan - тут была статья (Fighter Ace). Там данные отдельно, а методы и view - отдельно.

Правка: 10 ноя. 2017 5:36

Страницы: 1 2 3 4 5 6 Следующая

/ Форум / Программирование игр / Общее

2001—2017 © GameDev.ru — Разработка игр