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

Типизированные int'ы (9 стр)

Страницы: 14 5 6 7 8 9
#120
12:09, 16 июля 2019

Went
> Это неконструктивно, бро. Очевидно, что таких примеров - сотни в нормальном проекте. Значит и перегружать придется сотни.
Это теоретически. Пока вот я вижу, что надо из метров2 переводить sqrt в метры.

> Да, если эту фичу почти нигде не применять, то и проблем не будет. Но такие фичи не нужны языку. А в частном случае можно нагородить что-то себе на коленке.
Ну так я и говорю, это личное решение каждого, городить или нет, в этом месте или нет, и так далее. Так-то классы можно тоже не использовать, но мы используем сотни классов в проектах и ничего страшного не происходит. Если к этим классам ещё добавить десяток, особо ничего не поменяется. У меня вот при переходе с нод на классы... ничего не добавилось, классы и раньше были, просто теперь в некоторых местах передаются сами объекты. Короче, всё зависит от задачи, как всегда.

> Да я говорю, что где-то в недрах шаблона будет срезаться метрика и на выходе будет голый инт.
Не, она не будет срезаться, шаблон просто будет применять на своём параметре те же операции, что на инте, просто шаблону пофиг же, поддерживает параметр эти операции или нет. Поэтому всякая арифметика, если нужна, должна быть реализована в классе индекса, да.

> То есть эта фича только для очень узких границ применения, поэтому, она и отловит 1 из 1000 подобных ошибок (ведь везде кроме индексов будут голые инты), а, значит, вводить такие вещи на уровень языка или хотя бы на уровень стиля кодирования отдельного проекта - ошибочно.
Ну не то чтобы ошибочно, иногда это было бы удобно. И сам язык оно не меняет, что раньше работало, будет работать точно так же.

#121
12:26, 16 июля 2019

StepEver
> Мало того, что можно порядок перепутать, можно ещё и не те ноды подсунуть.
Кому подсунуть? Вы их чё там, через дебагер подсовываете?

Примеры кода приведите, не надо придумывать по декларации функции, как она будет использоваться. В нодах будут типизированные инты? Откуда эти инты будут прилетать? В сотый раз спрашиваю.

А если корабль вне дальности атаки? А если корабль свой? А если корабль уже умер? Уже есть механизмы, которые всё это должны решать (спавн и пул юнитов, единый AI). Чуть кто на входе данных из сети перепутает каст к нужному типу, эта типизация будет молча сидеть.

Ассемблер тут ваще ни при чём. Я про то, что у вас есть игровой цикл, а не фантастическая среда, где объекты друг с другом общаются, заводят детей и сами пишут код. У вас должно быть целостное состояние мира, эти точки синхронизации и разруливают все ваши id, если вам не надо в Юнити (или что там у вас) обеспечивать целостный рендеринг, это не значит, что и логика у вас целостная.

Suslik
> суть в том, что вот такой код вообще не должен компилироваться:
Вот это отличный пример кода из блокнота. edge.nodeIndices[0]; - что это? Кто так будет писать? А ноль не надо будет объявлять как `NodeId node_zero = 0;`?
А если кто-то урон юнита помножит на счётчик цикла? Или приклеет к тексту диалога заголовок окна? Тоже типизировать? Это всё баги на час, максимум, решения. Если не на три минуты. И ложный (потому что всё равно надо откуда-то кастовать эти id, где они численные) механизм защиты тут бесполезен.
> кстати, всем иннуэндам и компании, которые никогда в жизни не сталкивались с
> проблемами несовместимых интов:
> https://github.com/KhronosGroup/SPIRV-Cross/blob/master/spirv_cross.hpp
Там даже по комментам к этим полям видно, что это говно какое-то непонятное, за комментариями по которому надо доку штудировать и грабли ломать, тут никакая типизация не поможет. Это юзабилити для хеллоуворлдов.

#122
12:35, 16 июля 2019

Suslik
> указатели не инвариантны при переаллокации. поэтому код вроде #112 работать не
> будет на указателях, равно как не будет работать код на архитектуре без
> указателей вроде шейдеров.
А индексы не инварианты при вставке. Ты вынес вектора ребер и вершин в публичный доступ пользователю класса Graph, он, что ли, сам должен смещать все индексы при каждой вставке и удалении?

> итераторы хранят указатель на контейнер, что автоматически делает их
> непригодными для любого time-critical кода и не являются достаточно общим
> решением, так как решают только проблему индексации.
Это какие итераторы хранят указатели на контейнер, дебажные, что ли? У вектора итератор - это указатель на элемент, у листа - указатель на ноду. Расскажи как мне из итератора стандартного контейнера вытащить указатель на сам контейнер.

> какими такими хендлами? если что, суть как раз в том, чтобы автоматизировать
> создание таких хендлов и максимально разгрузить синтаксис для их определения.
Как в MFC сделано. Синтаксически, хендл - это просто указатель на некую пустую, неопределенную для пользователя структуру. А все операции над ним делает сам контейнер. Что он делает внутри - пользователю не важно.

> полноценно это реализовать без strong typedef'ов нельзя, можно только
> костылить. в этом и отстой.
Strong typedefs too strong for this. Но даже они не решили бы проблему целиком. Потому что не защитят от использования индекса на один массив в качестве индекса на другой, хотя и однотипный. У итераторов такая проблема решается хотя бы в дебаге, у указателей и хэндлов такой проблемы в принципе нет.

#123
12:58, 16 июля 2019

NyakNyakProduction
> Примеры кода приведите, не надо придумывать по декларации функции, как она будет использоваться. В нодах будут типизированные инты? Откуда эти инты будут прилетать? В сотый раз спрашиваю.
Это была аналогия с int-ами.
Функция, примерно, такая:

void Attack(Node* nodeAttacker, Node* nodeDefender)
Так как формально, все объекты живут в дереве из нод, то это по сути:
void Attack(int idxAttacker, int idxDefender)
Откуда прилетают: в классе карты есть Node* nodeSelected - это текущий, выделенным мышкой корабль, он передаётся в качестве nodeAttacker. Сама функция вызывается по событию клика мышкой, по клику делается Ray Trace и получается вторая нода, которая передаётся как nodeDefender.

NyakNyakProduction
> У вас должно быть целостное состояние мира, эти точки синхронизации и разруливают все ваши id, если вам не надо в Юнити (или что там у вас) обеспечивать целостный рендеринг, это не значит, что и логика у вас целостная.
Да там проблема в человеке-программисте, а не системе. Это как есть const-функции - зачем?

#124
(Правка: 13:14) 13:10, 16 июля 2019

StepEver
> Откуда прилетают: в классе карты есть Node* nodeSelected - это текущий,
> выделенным мышкой корабль, он передаётся в качестве nodeAttacker. Сама функция
> вызывается по событию клика мышкой, по клику делается Ray Trace и получается
> вторая нода, которая передаётся как nodeDefender.
Уже хорошо. Ну кликнули вы мышкой - дальше как будет типизированный инт рассчитываться?

Что мы получаем с мышки? Позицию, чтобы по ней потом искать объект? Под мышкой либо корабль (нельзя атаковать), либо астероид (можно). Откуда берём сам объект? Из пула с кораблями и астероидами? Как там эти id хранятся, как надмножество над ShipId и AsteroidId?

Как функция получения объекта под мышкой будет разруливать, какой тип id возвращать? Где гарантия, что вы там не перепутаете? Как быстро обнаружится баг, что мы нажали на корабль, без всякой типизации? Это один обработчик мышки.

Вы понимаете, что вы одной проблемой приведения теперь этих int'ов в один контейнер, из которых вы можете их ошибочно получить, уже огребли геморроя?

#125
13:23, 16 июля 2019

NyakNyakProduction
> Под мышкой либо корабль (нельзя атаковать), либо астероид (можно). Откуда берём сам объект? Из пула с кораблями и астероидами? Как там эти id хранятся, как надмножество над ShipId и AsteroidId?
По позиции мышки и положению камеры делается рейкаст, который возвращает (или нет) ноду. С ноды получается компонент корабля. Все объекты (видимые или логические) хранятся на дереве нод.

> Как функция получения объекта под мышкой будет разруливать, какой тип id возвращать?
Она всегда возвращает ноду. Движок ничего не знает про пользовательские классы (которые в качестве компонентов подвешиваются на ноды). Если имеется ввиду, как из ноды получается объект: есть функция получения компонента из ноды. Если она вернула nullptr - нет объектов такого класса на этой ноде.

> Как быстро обнаружится баг, что мы нажали на корабль, без всякой типизации? Это один обработчик мышки.
сам обработчик ничего не проверяет, он или получает ноду или нет.
баг обнаружится в функции Attack, когда с одной из нод не получится получить объект класса корабля, ну или если нода нулевая - кликнули в никуда. Или в геймплее, когда атака пройдёт в обратную сторону :)

#126
13:27, 16 июля 2019

StepEver
> По позиции мышки и положению камеры делается рейкаст, который возвращает (или
> нет) ноду. С ноды получается компонент корабля. Все объекты (видимые или
> логические) хранятся на дереве нод.
Типизированный инт то где тут? И как он поможет?

#127
13:32, 16 июля 2019

NyakNyakProduction
> Типизированный инт то где тут? И как он поможет?
Типизированный инт: сейчас объекты создаются как объекты класса, складываются в массивы соответствующего класса, в классе игры. По клику так же определяется нода, но потом ищется объект конкретного класса в массивых игры(по кликнутой ноде) и он уже передаётся в функцию Attack, а не абстрактная нода. AI не использует клик, но раньше так же оперировал нодами, теперь он может напрямую оперировать объектами. В функции Attack пропала куча проверок.

#128
13:42, 16 июля 2019

StepEver
> По клику так же определяется нода, но потом ищется объект конкретного класса в
> массивых игры(по кликнутой ноде) и он уже передаётся в функцию Attack, а не
> абстрактная нода.
Я думал, у нас прогресс, но мы там же, где и начали. У вас одна функция клика, у вас разные массивы для астероидов и кораблей.

Допустим, вы в функции клика перепутали местами id астероида и id корабля при передаче в Attack. Собрали билд, запустили. Нажали на атаку.

Теперь вопрос: есть ли вообще ситуация, что вы сразу не увидите баг? С AI чуть дольше у вас времени уйдёт, но не больше пяти минут. И уж точно такое не зарелизить.

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

#129
13:49, 16 июля 2019

NyakNyakProduction
> Теперь вопрос: есть ли вообще ситуация, что вы сразу не увидите баг? С AI чуть дольше у вас времени уйдёт, но не больше пяти минут. И уж точно такое не зарелизить.
Нет, сразу увижу.

> Проблема решается просто - у вас массив интов одного типа, которые вы строите каждый игровой тик, эти инты определяют, кого можно атаковать. Баг у вас может быть только в одном месте - в месте их заполнения.
Ну, допустим, но почему не исключить эту проблему(в compile time) использованием чёткой типизации, чтобы не те инты не попали в массив?

Прошу прощения за невнимательность, я тут параллельно на собрании, и ещё параллельно код пишу :)
#130
(Правка: 14:22) 14:22, 16 июля 2019

StepEver
> Ну, допустим, но почему не исключить эту проблему(в compile time)
> использованием чёткой типизации, чтобы не те инты не попали в массив?
Вы это кодом гарантируете. Заполняете этот сет только из массива астероидов. Зато потом вы не огребёте веслом по шее, когда вам понадобится добавить другие классы к атакуемым. По этому сету вы можете распределять атаки AI и т.п. и т.д.

Ничего, я уже седой :0
#131
11:50, 20 июля 2019

NyakNyakProduction
> Зато потом вы не огребёте веслом по шее, когда вам понадобится добавить другие классы к атакуемым.
Эта проблема точно та же, что с индексами. Если нам понадобится как-то в рамках одного класса уместить разные типы объектов, то это же класс нам гарантирует уникальность своего индекса.

> Ничего, я уже седой :0
:(|
#132
(Правка: 12:09) 12:09, 20 июля 2019

В Аде такая фича есть по умолчанию ... причём 2 разных способа.

1) Если нужен именно новый тип

type Handle is new Integer;
2) Если нужно ограничить инт каким-то значением, но при этом иметь возможноть использовать его как обычный инт (например в вычислениях).
subtype MyIndex is Integer range 0..1000;

Страницы: 14 5 6 7 8 9
ПрограммированиеФорумОбщее