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

Архитектура движка, как правильно спроектировать интерфейсы

Страницы: 1 2 3 Следующая »
#0
12:52, 5 июня 2016

Доброго времени суток. Накидал примерную архитектуру апи движка

Изображение

Но есть непонятные моменты, не знаю как лучше спроектировать дабы была расширяемость в будущем и достаточная инкапсуляция компонентов апи. Идея такая: Core наследуется закрыто от Sound, Framework, Graphics, etc, которые в свою очередь являются граф. движком, звуковым и т.д. и предоставляют общие интерфейсы. Допустим, если нужно изменить звуковую подсистему, то надо править Sound внутри, но интерфейс остается прежним. Core сам по себе является синглтоном. Но проблема в том, что для запроса, например, граф движка, нужно использовать core: Core->QueryInterface()->Graphics()-> ... Слишком громоздко, но в тоже время, не хотелось бы давать прямой доступ клиентам апи к компонентам этого апи. Можно, конечно, каждую подсистему реализовать синглтоном, но тогда клиенту апи надо самостоятельно заботиться о инициализации движка, например (да и при освобождении), вместо вызова Core->Init(). Подскажите как правильно построить архитектуру апи и каким образом получать интерфейсы на подсистемы, чтобы они были доступны везде в коде самой игры. Как вариант, сделать в ядре некоторые классы вроде SceneManager, SoundManager и т.д., которые имеют открытый интерфейс для клиента, а внутри как им нужно используют подсистемы апи..., но изначально была идея все эти Manager-ы реализовывать в коде игры.

#1
13:31, 5 июня 2016

Синглтоны (и глобальность вообще) не нужны и наследованием не стоит злоупотреблять. Пусть все классы содержат ссылки на нужные им подсистемы. И надо стараться разделять обязанности, делая классы так, чтобы минимизировать количество необходимых им подсистем.

#2
13:34, 5 июня 2016

phoenix76
> не знаю как лучше спроектировать дабы была расширяемость
мну делал так:

двигатель - это просто коробка для подсистем.
он их хранит.
шлет им какие то обще-системные сообщения, по типу: "подготовились! внимание! марш!".
ну или "закрываем лавочку", и тд.
и крутит вечный цикл, обеспечивая тайм-машину.

ну а чем является сама подсистема - пофигу.
всем, чем угодно:

int main()
{
    engine::add<graphic>(params1);
    engine::add<gui>(params2);
    engine::add<sound>(params3);
    engine::add<logick>(params4);
    ...
    engine::add<net>(paramsN);

    engine::start();
}

порядок добавления важен.
например, гую нужна графика для работы.
значит, графика должна идти первой.
что бы гую было у кого попросить окошко,
или чего ему там нужно.

если подсистемам нужно взаимодействовать друг с другом - только через систему сообщений,
и обязательно в автономном режиме.
то бишь одна подсистема не должна опираться
на факт существования другой.
и как то от неё зависеть.

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

потому что пока данные приходят через сообщения,
пофигу, кто именно их посылает.

phoenix76
> каким образом получать интерфейсы на подсистемы, чтобы они были доступны везде
> в коде самой игры.
отовсюду доступен двигатель.
потому что он - сингелтон.
а через него можно получать доступ к его подсистемам.
а через них - к их компонентам.

#3
17:59, 5 июня 2016

Kartonagnick
>
> порядок добавления важен.
> например, гую нужна графика для работы.
> значит, графика должна идти первой.
> что бы гую было у кого попросить окошко,
> или чего ему там нужно.
Почему не делать трехэтапное construct-link-use?
Создаем, потом сохраняем все связи (указатели), потом используем друг-друга.
Уничтожение в обратном порядке.

#4
18:09, 5 июня 2016

gammaker
> Синглтоны не нужны
А как тогда работать с менеджерами ресурсов/памяти?

(Я тоже считаю что синглтоны - зло, просто не везде от них меньшими усилиями можно избавиться)

#5
18:41, 5 июня 2016

-Eugene-
> Почему не делать трехэтапное construct-link-use?
мне не понятно зачем это нужно именно в плане развертывания подсистем.

ну вот создали.
теперь делаем всем init.
вопрос: как?

если вручную, тогда не понятно,
в чем профит.

если они сами, тогда опять возникает вопрос:
в каком порядке?

вот такой вариант мне видится практичным.

во-первых он наглядный:
сразу видно кто там первый строится, кто второй.
и кто в каком порядке будет подыхать.

а во-вторых - простой, в плане просто реализуется.
не нужно ни о чем заморачиваться.

-Eugene-
> Уничтожение в обратном порядке.
ну значит ваша идея не упраздняет важность порядка создания.
тогда совсем не понятно, нафига нужен этап link.

я их просто создаю.
все, они уже готовые.
свои связки сделали.

далее "подготовиться" - они переходят в активное состояние.
ресурсы там захватывают, если кому нужно.
а потом - "старт"
ну и в конце "стоп"

#6
18:41, 5 июня 2016

Laynos
> Я тоже считаю что синглтоны - зло
ет почему ж зло?

#7
18:48, 5 июня 2016

Kartonagnick
Чтобы две системы могли использовать друг друга.
Можно сколь угодно долго обсуждать архитектурно-эстетическую часть вопроса, но на практике такая связь может быть полезна.

#8
18:51, 5 июня 2016

-Eugene-
> Чтобы две системы могли использовать друг друга.
как то не очевидно, как их тогда потом развязывать.
я на самом деле с такой необходимостью
не сталкивался ни разу.

#9
18:52, 5 июня 2016

Kartonagnick
> ет почему ж зло?
Код запутывается, превращается в спагетти: взяли синглтон там-то, теперь тут, а ещё вот тут... Причём по заголовочным файлам это не отслеживается

#10
18:54, 5 июня 2016

Kartonagnick
> как то не очевидно, как их тогда потом развязывать.
> я на самом деле с такой необходимостью
> не сталкивался ни разу.
При удалении, не?

Каким образом одна система получает для использования другую систему? Через какой-нибудь engine::get<system>??

#11
18:54, 5 июня 2016

Laynos
> Код запутывается, превращается в спагетти: взяли синглтон там-то, теперь тут, а
> ещё вот тут... Причём по заголовочным файлам это не отслеживается
ну вот я беру std::cout.
чет ничего у меня вроде не запутывается.

#12
18:58, 5 июня 2016

-Eugene-
> Каким образом одна система получает для использования другую систему?

как то вот так:

int main()
{
    auto& g = engine::add<graphic>(params1);

    engine::add<gui>(g.getWindow(), params2);

    engine::add<sound>(params3);
    engine::add<logick>(params4);
    ...
    engine::add<net>(paramsN);

    engine::start();
}
#13
19:00, 5 июня 2016

Kartonagnick
Я сначала так делал, но чет мне надоело указатели пробрасывать через конструкторы...

#14
19:03, 5 июня 2016

-Eugene-
> Я сначала так делал, но чет мне надоело указатели пробрасывать через
> конструкторы...
вы хотите сказать, что вот это:

engine::get<system>

у вас дергается изнутри соседней подсистемы???

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.