[ Главная · Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 3 из 3
  • «
  • 1
  • 2
  • 3
Форум » СИМУЛЯТОР ПУЛЬТА ДИСПЕТЧЕРСКОЙ ЦЕНТРАЛИЗАЦИИ "НЕВА" » Эксперименты в симуляторе » Пытаюсь замутить свой симулятор.
Пытаюсь замутить свой симулятор.
isaewvlad2016Дата: Понедельник, 05.06.2023, 17:37 | Сообщение # 41
Составитель поездов
Группа: Пользователи
Сообщений: 9
Награды: 0
Репутация: 0
Статус: Offline
Привет!
Подскажи, пожалуйста, суть этих ламп. И я так понимаю, что это уже не первоначальная задумка, а дополнение к действующему симулятору, так? Сейчас идея все та же или уже нет? Хотелось поподробнее объяснений)
Какие еще идеи планируется реализовать? Смотрю, что-то движется! Успехов!
 
V9Дата: Понедельник, 05.06.2023, 18:49 | Сообщение # 42
Начальник станции
Группа: Пользователи
Сообщений: 198
Награды: 3
Репутация: 0
Статус: Offline
Цитата isaewvlad2016 ()
Подскажи, пожалуйста, суть этих ламп.

Игра проектируется под то, что люди сами смогут делать свои полигоны движения. Внутри не будет никаких "скрытых" кодов, которые жестко привязывают игру к полигону. К примеру, сейчас ты не можешь модифицировать data.dat, чтобы сделать выход с Сургута двухпутным, игра тебя "не поймет". Я же продумываю так, что игроки смогут делать вообще любой полигон какой захотят, игра сама должна будет разобраться как с ним работать. И игрокам может захотеться сделать "нетиповые" лампы на каких-то сложных станциях при недостатке места на Пульте. Это и было задачей: уметь работать с лампами любых конфигуаций на территории станции. Кроме того, это может позволить делать некие другие лампы. Скажем, сделать все лампы круглыми, как это типово сделано на станциях на пультах.

Добавлено (05.06.2023, 18:55)
---------------------------------------------
Кроме того, сразу проектирую под то, что:
1. Игра может оперировать сразу двумя и более полигонами, между которыми будет происходить передача поездов. Т.е. в теории, можно будет переключаться между участками Тобольск - Демьянка, Демьянка - Куть-Ях, Куть-ях - Сургут, Сургут - НВ1 и тащить поезд с Тобольска до Лангепаса под выгрузку.
2. Игра должна позволять подключаться одному игроку к одному или нескольким полигонам, равно как и нескольким игрокам к одному полигону. 
3. Игра должна позволять делать частичные отцепки/прицепки по пути следования сборного поезда.

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

Добавлено (06.06.2023, 22:28)
---------------------------------------------
Оффтоп. Есть серьезное такое правило: "Нельзя озвучивать свои планы!" Работает, по видимому из того, что озвученные планы как бы дают неправильную инфу подсознанию, что 2задача сделала". А раз задача сделана, зачем ею заниматься? Подсознание сильно этому противится. В частном случае я с трудом заставляю себя дальше делать. Но обязан справиться со своим посознанием =)

Добавлено (07.06.2023, 09:04)
---------------------------------------------
Оффтоп 2. Так как проект планируется большой, а предыдущая попытка окончилась неудачей, то я решил посмотреть, как делают большие проекты. А большие проекты, в том числе, по технологии TDD - https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5

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

После первого, неудачного, прогона теста, прог должен написать сам код, который (А) успешно скомпилируется; (Б) пройдет тесты. И далее на новый цикл.

Я почти не писал тесты, сейчас решил покрыть тестами метод загрузки BMP файлов - LoadBMP. Он сделан так, что в ошибочных случаях "крашится", вызывая исключение {try...catch...finally}, а в сообщении описывает причину краха. Причину видно в момент краха, но видно только в отладочном режиме.
Однако, родной код языка, который грузит другие картинки, не крашится.Он не грузит и сообщает об этом. Но НЕ сообщает о причинах невозможности загрузки.

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

А еще тест должен проверять все строки тестируемого кода, проходя по всем возможным комбинациям сбоев. Если у нас нет возможности загрузить картинку по 10 причинам, значит должно быть 10 тестов, которые проверяют эти 10 причин и, заодно, еще и проверяют строки, которые возвращает LoadBMP. Строки должны совпадать с причинами.

Но это значит, что строка должна дублироваться - в коде LoadBMP и в тестовом коде. А это некорретно, так как меняя строку в LoadBMP (что НЕ меняет код), нам надо поменять еще и в тесте, иначе тест "упадет".

Теперь у нас мысль, что строки ошибок, по одной на ошибку, должны лежать отдельно, а оба метода LoadBMP и TestLoadBMP должны их читать из одного файла.

И тут мы нарываемся на другую проблему. Файл со строками, строго говоря, должен быть в двух экземплярах. 

  • Один экземпляр должен лежать в дереве исходного кода программы, чтобы его мог "подхватить и запомнить" обработчик  distributed software configuration management system, в моем случае - это Fossil: https://fossil-scm.org/home/doc/trunk/www/index.wiki Использование его позволяет "откатиться"  на нужную версию кода, если в разработке что-то уж совсем поломал. Кроме того, он же позвляет разрабатывать отдельные ветки кода (branch) независимо друг от друга, потом их объединяя при  необходимости (merge) когда разработка части кода завершена. По требованиям Fossil, файл строк должен иметь кодировку UTF-8.
  • Второй экземпляр должен лежать в дереве компилированного кода, так как именно дерево комплированного кода потом будет рассылаться пользователям. А его кодировка должна быть ASCII.


То есть, при компиляции надо посмотреть образец в дереве исходников, взять его время модификации, сравнить с файлом в дереве компилированного кода. Если время не совпадает (мы поменяли файл в дереве исходников) скопировать образец из дерева исходников в дерево  компилированного кода, по пути изменив с кодировки UTF-8 на ASCII. А этот перекопировщик мы должны (А) написать; (Б) написать к нему тестер. Причем, мы же TDD, поэтому сначала пишем тесты самому копиру-транслятору, потом его сам.

Но и тут проблема. В файле строк мы сохраняем обычные строки, типа "Выходной буфер слишком мал!" Но в коде есть сложные строки, типа такого:
  • "По метаданным буфер должен быть " + ХХХ + " байт, но подан буфер " + YYY + " байт".


То есть у нас три строки, которые "склеиваются" в одну, подставляя вместо переменных величин XXX и  YYY их строковые представления. Получается типа "По метаданным буфер должен быть123456 байт, но подан буфер 11111 байт".

Пока мы дублировали строки в тестируемом коде и в коде тестировщика, это была рабочая схема. Но теперь у нас должна быть _одна_ строка на проблему. Как решается эта проблема в промышленном софте? Решение называется "форматная строка", как это, для примера, в Питоне: https://skillbox.ru/media/base/formatirovannye-stroki-v-python-primery-ispolzovaniya/
Предыдущий вариант должен выглядеть примерно так: format("По метаданным буфер должен быть {} байт, но подан буфер {} байт", XXX, YYY). Теперь у нас строка одна, но появился "форматтер", который должен "разобрать" строку и подставить вместо "{}" соответствующие параметры).

Но там, где я пишу, такого механизма, форматтера, нет! Его тоже надо написать. И, бинго, тоже покрыть тестами!

И все это в сумме ни  на грамм не приближает к продвижению разработки симулятора.

Добавлено (10.06.2023, 05:24)
---------------------------------------------
Пока встал на проблеме декодера, который должен utf-8 превратить в ASCII. Там проблема в том, что нужно заиметь два файла одного текста: UTF-8 и UTF-16. А из UTF-16 ASCII делается элементарно. Но чтобы получить корректные символы нужных диапазонов для теста, я пишу файл-образец UTF-32. По замыслу, из него получаю UTF-8, из него - UTF-16, а потом при тестовом декодировании сверяю корректность UTF-8 и UTF-16.

Ок? Ок! Проблема в том, что я не смог найти тулз, чтобы из UTF-32 получиить UTF-8. Онлайн-трансляторы работать не хотят, в Notepad++ поддержки UTF-32 нет. Пока тупик.

 
V9Дата: Суббота, 10.06.2023, 18:01 | Сообщение # 43
Начальник станции
Группа: Пользователи
Сообщений: 198
Награды: 3
Репутация: 0
Статус: Offline
Нашел выход в том, что ... просто взял контрольные цифры с википедии! =)
https://en.wikipedia.org/wiki/UTF-8#Encoding_process имеет табличку со значением и байтов UTF-8, и значений UTF-32. То есть, я взял и написал декодер UTF-8  в UTF-32 пользуясь этими значениями как опорным данными.

Ок, сделал конвертер UTF-8  в UTF-32. Далее по плану у нас конвертирование UTF-32 в UTF-16. Тут проблема в том, что максимальное значение UTF букв = 0x10ffff, а максимальное значение, которое хранится в utf-16 - 0xffff.

Разработчики сделали так: Если буква > 0xffff, то есть в пределах 0x10000 ..  0x10ffff, то мы вычитаем из буквы 0x10000. Получили значение в диапазоне 0x00000 .. 0xfffff. То есть - 20 бит. Далее эти двадцать бит драконим по 10 и пакуем в две шестнадцатеричные буквы. И обзываем эти буквы "суррогатами" (surrogate). Старшие 10 складываем с 0xD800 и получаем диапазон 0xD800..0xDB00. Младшие  складываем с 0xDC00 и получаем диапазон от 0xDC00 по 0xDFFF.

К чему все эти описалова? Т.к. я кодировал разбор UTF-8, то далее я просто сохранил UTF-8 представление в файл, файл открыл в Notepad++, там рекодировал в UTF-16 и записал.

Потом открываю его в hexed.it и вижу бинарные данные. Интересный момент выделил синим. Переношу внутрь тестера в массив. 

Пишу код кодера, все хорошо, отрабатывает прям идеально. Сохраняю код в fossil и смотрю на сохраненнку. И тут глаз цепляется за явную ошибку:


Я должен был число сдвинуть на 10 бит, потом оставить только сдвинутые биты, очистив лишнее (& 0x3ff) и сложить с 0xd800. Но палец слишком задержался на нуле и получилось два нуля. И сдвиг делается на 100 бит. А это означает что любой аргумент будет обнулен так как общая длина аргумента не более 32 бит вообще. Чтобы там ни было передано, на выходе получится ноль плюс 0xd800 = 0xd800.

Начал разбираться, почему не сработал тест?

Что получилось? А то, что в разделе википедии в  UTF-8 в длинный параметр взяли слишком низкое значение. После вычитания 0x10000 (на скрине в двоичных данных), старшие 10 бит равны нулю (подчеркнуто фиолетовой линией). Как ни двигай ноль, в результате - ноль. Ноль плюс 0xD800 = 0xD800. Что и получилось выше по скринам. Т.е. ошибка точно "легла" на ошибочный аргумент и прога считала неправильно, но изза ошибочного аргумента эта ошибка была не видна! Тест прошел, оно бы все осталось в проге и где и когда бы вылезло в виде ошибки - Бог знает!

Добавлено (10.06.2023, 18:07)
---------------------------------------------
1. Сделать форматтер
2. Сделать раскодирование utf-8 в utf-32
3. Сделать перекодирование utf-32 в utf-16
---- мы находимся тут -----
4. Сделать перкодирование utf-16 в ASCII
5. Сделать файлы строк в utf-8 (изза Fossil) в дереве исходников
6. Сделать помощник комплитора, которые берет файл из дерева исходников и копирует их в выходное дерево попутно перекодируя по пути utf-8 ->  utf-32 -> utf-16 -> ASCII.
7. Сделать загрузку ASCII файла из выходного дерева.
8. Обвязать тестами LoadBMP сделав привязку строк из загруженного файла.

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

Добавлено (11.06.2023, 19:45)
---------------------------------------------
1. Сделать форматтер
2. Сделать раскодирование utf-8 в utf-32
3. Сделать перекодирование utf-32 в utf-16
4. Сделать перкодирование utf-16 в ASCII
5. Сделать файлы строк в utf-8 (изза Fossil) в дереве исходников
6. Сделать помощник комплитора, которые берет файл из дерева исходников и копирует их в выходное дерево попутно перекодируя по пути utf-8 ->  utf-32 -> utf-16 -> ASCII.
---- мы находимся тут -----
7. Сделать загрузку ASCII файла из выходного дерева.
8. Обвязать тестами LoadBMP сделав привязку строк из загруженного файла.

Добавлено (11.06.2023, 23:02)
---------------------------------------------
Спустя 7 часов 40 минут и 761 строку кода вышеприведенная задача закончена. Было несколько прикольных глюков на которых убил много времени.
1. Есть тестовая функция, которая вызывает тестируемую. Тестовая вызвает, тестируемая отрабатывает, возвращается в тестируущию. Отрабатывает с ошибкой. Не смотря на то, что ошибку в тестируемой я исправил. Ошибка не уходит. И так и эдак - не уходит. Уже начинаются приколы типа "вывести строку в консоль, что мы вошли в тестируемую функцию!" Вывода нет! Чую, что медленно схожу с ума. Куда-то уходит, где-то работает, работает с ошибкой, но не там, где я сижу. Причина в том, что тестируемая функция перемещелась в процессе работу в другое место в дереве каталогов. И создала выходной бинарный файл тоже в другом месте. А старый бинарник остался. И тестировщик уходил и проходил со старым бинарником, в кортом была ошибка. А новый бинарник тестировщик не видел.
2. Тестовая функция вызывает тестируемую. Тестируемая сообщает, отработала она с успехом или нет. А далее я в тестировщике я делаю глупую ошибку типа такого


Цитата
success = CompilerSupport(...)
if (success) {
// проверяем, что он отработал хорошо, сверяя данные
} else {
}
То есть, я чет решил, что всегда получу "success"(успешно) и сделаю пост проверку. И если на пост проверке будет что-то криво, пост-проверка мне все сообщит.

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

Добавлено (18.06.2023, 15:43)
---------------------------------------------
Сделал автогенератор. В некоторых ситуациях, файл с сообщениями об ошибках будет не доступен программе, поэтому нужно в момент компиляции подставить нужные строки ошибок прямо в исходных код программы. Эти строки будут использоваться если невозможно загрузить внешний файл. Автогенератор наблюдает, что поменялся файл с сообщениями ошибок и делает две вещи:

  • Копирует в дерево бибилотек, конвертируя из UTF-8 в Latin-1
  • Имплементриует кодированные данные в Latin-1 прямо в исходный код (текст) библиотеки.

А исходный код после комплируется компилятором и попадает в библиотеку.

Добавлено (20.06.2023, 17:48)
---------------------------------------------
Полностью закончена задача, которую зачал 07.06 (две недели назад): полностью покрыт тестами LoadBMP и сделана система сообщений об ошибках. Эта задача сдается в архив и теперь в планах возвращаться уже к самому симулятору.

Добавлено (20.06.2023, 18:04)
---------------------------------------------
в проекте щаз 3700 строк кода

Прикрепления: 6813230.png (12.4 Kb) · 8028950.png (1.6 Kb) · 1842577.png (7.8 Kb) · 4076615.png (12.2 Kb)
 
V9Дата: Среда, 21.06.2023, 12:09 | Сообщение # 44
Начальник станции
Группа: Пользователи
Сообщений: 198
Награды: 3
Репутация: 0
Статус: Offline
Ощущение трясины никак не пропадает. Вся инфа об участке хранится в Territory\1\data.dat (Territory\2\data.dat).

Этот файл читает подсистема "Модель"(Model, отсылка на "модель мира"). Именно в ней должны обсчитываться поезда, сигналы, положение стрелок и т.п. Модель сообщает об изменениях Представителю("Presenter"), который, в свою очередь, управляет Демонстратором("View"). Или, другими словами, у меня реализуется паттерн программирования Model-View-Presenter (MVP).

В начале разработки я разрабатывал без тестирования. С 07.06 я перешел на режим TDD(гуглить Test Drive Development). У меня грузилась модель частично, только инфа по станциям. Сейчас начинаю добавлять перегоны. Ну и встреваю сходу двумя ногами в трясину. В файле data.dat перегоны лежат в разделе Data_Graph_Peregon


Прога ловит начало раздела и... И что надо сделать первым делом? Скинуть пустые строки. Вот эти все строки с ";"(точками запятыми) считаются "пустыми строками". Не-пустая строка начнется там где 1,  2,...

Но! Файл может быть бракованным и при "скидывании" пустых строк мы можем "дойти" до конца. Это ошибка, и там есть и проверка на ошибку и сообщение. Ок! Но у меня же TDD, да? А значит в тестах я обязательно должен зайти в эту возможность чтобы проверить что загрузка Модели отлавливает эту ошибку. А значит, файл data.dat надо "портить". Буквально, отрезать все, что там идет дальше, после заголовка секции. И рестартануть разбор.

Но если так сделать и произойдет где-то ошибка, файл НЕ вернется в нормальное положение, он останется обрезанным. Значит, что? Надо научить Модель грузить файлы с другими именами. Тогда мы берем родной data.dat, режем его и сохраняем как копию. И копию посылаем в Модель. И смотрим как себя ведет Модель. Значит надо переписать модель на возможность загрузки других файлов. Но раз уж взялись переписаться на возможнсоть загрузки, то сходу надо предусматривать, что так-то у нас глобальные идеи. Возможные режимы игры:
1. Игра на компе пользователя. Читаем родные файлы.
2. Игра на компе пользователя, но модель на другом компе. Т.е. "онлайн-игра по сети". Модель читает/пишет как файлы, так и данные в базу данных, находясь на сервере. Возможно, по соображениям безопасности вообще не будет доступа к файлам и надо будет читать/писать в базу данных.
3. Игра на компе пользователя, модель на компе пользователя, но файлы находятся на другом компе,  на некоем сервер. "Одиночная кастом-игра".

То есть, сходу надо выносить чтение/запись в отдельный интерфейс и работать с ним. А значит надо писать:
1. Файл интерфейса;
2. Файл адаптера интерфейса;
3. Файл сообщений ошибок.
4. Файл обработки ошибок.
5. Тест-файл адаптера интерфейса
6. Тест-файл обработки ошибок.

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

Добавлено (23.06.2023, 13:26)
---------------------------------------------
В проекте 4258 строк кода, сидим  в трясине.  cool

Добавлено (25.06.2023, 16:36)
---------------------------------------------
Сделал загрузку перегонов. Решил пока не настраивать отображение пока не загружу все данные вообще. Т.е. далее полная загрузка в планах. 
ps. По прежнему не получается писать тесты ДО того как я сделаю код. Но надо исправится.

Добавлено (26.06.2023, 15:52)
---------------------------------------------
В проекте 4706 строк кода

Добавлено (26.06.2023, 20:54)
---------------------------------------------
Сильно дико не хватает знаний. Сейчас встал на перепутье по вопросу - "Делить ли данные по станции на два объекта - для Модели и для Демонстратора или хранить все данные в одном объекте?" Вопрос возник из-за того, что файл данных data.dat читает модель. Которая формирует, на данном этапе, данные для Демонстратора, как том правильно "отрисовать" станцию. Но теперь я подхожу к разбору секции ламп файла data.dat и возник вышеупомянутый вопрос. То ли расширять структуру данных добавляя сведения о лампах, структуре путей станции, поездах на станции, движении резервных локомотивах по стации. То ли делить это все на разные объекты-структуры: разные для модели и для демонстратора. В модели хранить сведения "окружающего мира", на основе этих сведений модель будет двигать поезда. А сведения как отображать на экране станции хранить в другом объекте, предназначенном для Демонстратора. Но если делить сведения на два объекта, то как их координировать между собою? Вопросы, на которые пока у меня нет ответов...

Добавлено (27.06.2023, 10:55)
---------------------------------------------
Удалось найти описание всех лампочек пульта: https://studfile.net/preview/5412484/page:8/ 
Класс! теперь понятно что и как можно прогать. А то они были для меня серьезной загадкой.

Добавлено (28.06.2023, 14:24)
---------------------------------------------
Еще и Zork сильно помог, скинув инфу по лампам. Живем!

Добавлено (29.06.2023, 21:12)
---------------------------------------------
Изза болезни пока все остановилось. =(

Добавлено (02.07.2023, 06:34)
---------------------------------------------
Столкнулся с резким нарастанием времени тестирования. Каждая "ошибка" в data.dat должна быть обработана, а для этого data.dat модифицируется и рестартится к разбору. А каждый разбор съедает по 0.2 секунды времени (примерно). Десять тестов - минус 2 секунды на тест. 
Планируется:
1. Немного изменить алгоритм загрузки, чтобы загрузка шла в таком порядке:
А) грузятся все фрагменты "вразнобой";
Б) и только после загрузки всех фрагментов начинаем "связывание" т.е. настройку связей между загруженными фрагментами.

2. Тесты проводить "по-фрагментно". Т.е. из оригинального data.dat "вырезать "фрагменты" и их тестировать отдельно. Это позволит резко сократить масштабы обработки на каждом тесте.
3. И только на финальном тесте проводить полную загрузку для проверки контрольных соотношений.

В проекте сейчас 4935 строк кода.

Добавлено (02.07.2023, 14:49)
---------------------------------------------
Потратив ровно два часа программирования и 174 строк доп.кода у меня появилась возможность проводить тесты по-объектно. Теперь тест занимает не 2 (две) секунды(!), а 0.5 секунд(!). Экономия на тесте - 1.5 секунды.  biggrin  За два часа работы.  lol

Добавлено (02.07.2023, 19:00)
---------------------------------------------
За каких-то дополнительных 110 минут у меня добавился файловый интерфейс, работающий с оперативкой. Теперь модель при загрузке загружается из памяти, исключается запись/чтение с/на диск. Что позволило сократить тест на грандиозные 0.2 секунды: вместо 0.55 секунд тест проходит за 0.35 секунд  wacko 
ps. В проекте 5471 строк кода.

Добавлено (03.07.2023, 03:13)
---------------------------------------------
За "каких-то" еще 104 минуты программирования удалось снизить время теста с 0.35 до 0.14. Но самое убойное ждало меня во время последнего забега. Я вспомнил, что Модель при загрузке сначала грузит pult.bmp, а потом начинает грузить data.dat. И потом, в тесте, на data.dat она и "падает" контролируемо. Но на загрузку pult.bmp тратит 0.1 секунды на каждый тест из группы тестов. Перенеся загрузку pult.bmp в конец, я смог сходу улучшить общее время теста с 1.9 секунды до 0.7 секунды. т.е. можно было вообще ничего не делать по тем переписываниям что я тут весь  день делал, просто перенести в конец загрузку pult.bmp. Это весьма сильно меня расстроило.

Прикрепления: 3501828.png (54.9 Kb)
 
d233Дата: Четверг, 06.07.2023, 23:27 | Сообщение # 45
Начальник станции
Группа: Пользователи
Сообщений: 120
Награды: 2
Репутация: 0
Статус: Offline
Цитата V9 ()
Ощущение трясины никак не пропадает.
ПРОСТО ПОДДЕРЖИВАЮ РАБОТУ!!!
 
V9Дата: Пятница, 07.07.2023, 13:13 | Сообщение # 46
Начальник станции
Группа: Пользователи
Сообщений: 198
Награды: 3
Репутация: 0
Статус: Offline
Цитата d233 ()
ПРОСТО ПОДДЕРЖИВАЮ РАБОТУ!!!
Спасибо!

Пока что доделана секция загрузки лампочек. Грузится 210 строк из 2450 строк файла data.dat. В проекте сейчас 5545 строк кода.

Добавлено (07.07.2023, 22:16)
---------------------------------------------
Потрачено 60 минут и 220 строк кода модуля Теста и 102 минут и 98 строк кода загрузилась секция Data_Sekz из файла data.dat.

В этот раз тренировался по другому немного. Сначала поставил себе задачу написать ВСЕ тесты. И только потом писать сам код, который должен успешно тесты отработать. Такая задача произошла из прошлой секции загрузки лампочек: я написал первые тест и начал писать код в модели (загрузчике). И выяснил, что надо написать почти весь код загрузчика, чтобы добраться до первого теста. Т.е. я как бы опередил разработкой написание тестов.

В этот раз я писал тесты, там тоже были некоторые сложности.  Пусть мы пишем первый тест. Его надо запустить, отладить. Он запустит Модель. Модель тест "не пройдет" ибо Модель еще не написана. Ок, переходим ко второму тесту... Но при попытке отладки теста №2, тест №1 просто не дает дойти до теста №2, он туда не пускает. Простейшая задача почему-то заставила почесать репу. В итоге простое решение: просто комментируем строку в тесте №1 которая вызывала останов. Потом делаем тест №2, там проверяем, комментим и так до конца. (upd. Разумеется, как написаны и оттестены до конца сами тесты, все комменты удаляем)

Список тестов (на память, могу пропустить):
1. После тега [Data_Skez]  нет ничего (это ошибка).
2. а Неправильное первое число
2. б Неправильное второе число (там числа парами идут).
3. Непарное число (первое число есть, второго до конца строки нет), после первого числа есть запятая.
4. Непарное число, после первого числа запятой нет.
5. Второе число FFFFh (65535) (это ошибка).
6. Среди первых чисел нет FFFFh (65535) (отсутствует признак останова разбора / признак конца секции).

Пришлось помучиться еще и в том, что я решил, что раз уж число не разобралось, то в ошибке его вывести. В итоге пришлось помучиться так как разборщик у меня не возвращает ошибочную строку. В итоге код задублировался:
1. Я сначала выделяю строку
2. Потом отправляюсь в разборщик номера, который снова выделяет строку и пробует ее разобрать, превратив в число.
3. Если это не получается, я сохраненную в п.1 строку добавляю в текст ошибки.

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

Добавлено (10.07.2023, 08:41)
---------------------------------------------

Цитата V9 ()
За "каких-то" еще 104 минуты программирования удалось снизить время теста с 0.35 до 0.14.

При загрузке грузятся файлы data.dat & pult.bmp. Но если мы "выпадаем" по ошибке то мы гарантированно "выпадем" на моменте загрузки data.dat. В такой ситуации есть замысел отложить загрузку pult.bmp. Однако устройство загрузчика файлов из памяти требовало предварительной загрузки в память с диска в момент запуска тестовой функции Модали так как иначе ошибка будет уже в самой Модели в момент, когда Модель затребует себе pult.bmp.

Был переписан загрузчик таким образом, чтобы осуществлять "ленивую загрузку" (lazy-loading). Теперь если мы вываливаемся на ошбке в момент тестирования Модели, мы не грузим pult.bmp. Время тестирования сократилось с 0.14..0.15 до 0.06 секунд (в среднем).

Сейчас гружу секцию Data_Stanz, там какое-то нереальное количество проверок надо сделать. В данный момент в проекте 6498 строк (плюс 900+ строк в сравнении с данными от 07.07.2023)

Добавлено (10.07.2023, 11:57)
---------------------------------------------
В проекте 6769 строк кода. В сравнении с данными от 07.07, добавлено 1224 строки кода (суммарно).

Это окончаниие загрузки секции Data_Sekz и загрузка Data_Stanz. чтобы понять, насколько большая секция Data_Stanz, я просто скопирую с data.dat:
 

Цитата
[Data_Stanz] ; данные о контролируемых станциях участка
               ; 1 - код станции
               ; 2 - пол ДСП (0 - нет ДСП, 1 - женщина, 2 - мужчина)
               ; 3 - количество контролируемых подходов 
               ; 4 - данные по подходам: 1 - номер перегона (1..19)
               ;                         2 - положение подхода: 0 - с четной стороны (юг), 1 - с нечетной (север)
               ; (количество строк должно соответствовать количеству контролируемых ЛП)
  56, 1, 1,    1, 0                   ; Нижневартовск-1
  55, 1, 2,    1, 1,    2, 0          ; Нижневартовск-2
  53, 1, 2,    2, 1,    3, 0          ; Мегион
  51, 0, 2,    3, 1,    4, 0          ; Урьевский
  50, 1, 2,    4, 1,    5, 0          ; Лангепас
  48, 0, 2,    5, 1,    6, 0          ; Чумпас
  46, 1, 3,    6, 1,    7, 0,   12, 1 ; Ульт-Ягун
  45, 0, 2,    7, 1,    8, 0          ; Вач-Ягун
  44, 0, 2,    8, 1,    9, 0          ; Сурмятин
  43, 0, 2,    9, 1,   10, 0          ; Почекуйка
  42, 1, 2,   10, 1,   11, 0          ; Силинский
  41, 1, 2,   11, 1,   14, 1          ; Сургут


На эти двенадцать строчек data.dat было убит 5.5 часов программирования и что-то около 1000 строк кода. В момент загрузки секции Data_Stanz проводится 20 (двадцать!) разного рода проверок на валидность данных. Тесты заняли 533 строки кода, код загрузки - 111 строк, и еще добавки это разного рода оптимизации типа "ленивой загрузки" из предыдущего поста.

Добавлено (13.07.2023, 00:17)
---------------------------------------------
Начал грузить секцию Data_Gorl_Stanz (вроде так). Создаю структуру хранения загруженных данных. Выбираю длину short (короткие числа) для чисел так как не требуется больше.

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

А при чтении мы читаем числа в числа в int из data.dat. А числа int длинней в разрядах. А просканировав и прочтя значения, мы должны проверить сканированные значения на то, что они не превывашают органичения, так как преобразование из int  в short могут привести к самым удивительным результатам. Пример кода:
       

Цитата
int a = 983041;
        int b = 983040;
        int c = 983039;
        
        short aa = (short)a;
        short bb = (short)b;
        short cc = (short)c;

Создаем три переменные a, b, c и присваемвае указанные значения. А потом их присваиваем значениям типа short, без контроля. АА будет равно... 1!
BB =  0.
СС = -1.

Поэтому у нас вторая группа проверок, что int числа могут "влезть" в short. 

И потом будет третья группа проверок когда будет проводится связывание (linking).  

Всё это предельно неэффективно по затратам времени программирования.

В итоге пришлось принять решенеи, что хранить данные сразу в int. Это удлиняет структуры, но сокращаются разные проверки. Вторая группа проверок просто исчезает.

Добавлено (13.07.2023, 17:50)
---------------------------------------------
Смена парадигмы ускорила работу. Затраты времени по написанию кода по загрузке следующей секции Data_Gorl_Stanz затратили 2.8 часа в сравнении с предыщуей секцией - 5.5 часов, это ускорение в два раза.
В проекте ≈7200  строк.

Добавлено (13.07.2023, 18:15)
---------------------------------------------
ах, да! Грузится 275 строк из всего 2542 (т.е. 10.81%). Т.е. 2.8 часа программирования "ушло" на загрузку 34 строк.

Добавлено (13.07.2023, 18:18)
---------------------------------------------
Хотя, если сравнить с пред секцией, это там было хлеще: 5,5 программирования на 19 строк.

ps. В теории, если дописать загрузку еще 4х секций, то можно  уже линковать и начинать писать движение. Далее будут названия станций, графики движения поездов и т.п.

Добавлено (14.07.2023, 08:01)
---------------------------------------------
Посчитал, скок секций data.dat осталось загрузить?

  • [Data_Put]

  • [Data_Str]

  • Data_Gr_Str]
  • [Data_Sl_Sekz]

  • [Data_Man_Svet]

  • [Data_Marsh_P]

  • [Data_Marsh_M]

  • [Data_Spar_Gr_Str]

  • [Data_Ost_Lok]

  • [Data_Peregon]

  • [Data_Graf_Pass_Ch]

  • [Data_Graf_Pass_N] 

  • [Data_Graf_Gruz_Ch]

  • [Data_Graf_Gruz_N]

  • [Data_Podhod_Form]

  • [Data_Num_Poezd]

  • [Data_Plan_Form]

  • [DataS_RP_Name_Mnem] 

  • [DataS_RP_Name_Manip]

  • [DataS_Stanz_Name


20 секций. Если на кажду будет затрачено по времени, скажем, 3 часа, то это 60 часов программирования.


Сообщение отредактировал
V9 - Пятница, 07.07.2023, 22:17
 
V9Дата: Воскресенье, 16.07.2023, 12:52 | Сообщение # 47
Начальник станции
Группа: Пользователи
Сообщений: 198
Награды: 3
Репутация: 0
Статус: Offline
На [Data_Put] потребовалось 4 часа программирования, в проекте 8036 строк кода (+836 строк к данным от 13.07) 

Постоянно проявляются новые моменты, которые требуется учитывать.

ps. Вот такие картинки вырисовываю прямо в коде:

Добавлено (26.07.2023, 20:13)
---------------------------------------------
Разработка была приторможена так как конец второго квартала, много отчетности и т.п.

Сегодня правил утилитную часть и делал то, что называется Incremental Compiler
( https://en.wikipedia.org/wiki/Incremental_compiler = ИК) 

Раньше у меня было три запуска, что заставляло три раза грузиться движок:
1. ComilerSupport проверял смену .properties файлов и делал копировали переделку в исходники если .properties поменялись.
2. Компиляция. Занимало в среднем 1500 мс на каждый запуск.
3. Тест. В зависимости от того, полный это тест или некий субтест, изначально это было 2000 мс на запуск. 

Эпопеей от 02.07..10.07 время тестирования было сокращено до 850 мс (полный тест) и до 60 мс (если у нас тест только успешный некоего фрагмента Модели).

А теперь инкрементальный компилятор(ИК) у меня компилирует за 15 мс. Т.е.полный цикл 1 + 2 + 3 занимает около 75 мс. Запуск теперь тоже из одного места, а не три раза подряд. 

Изза этого были переписаны конфигурационные файлы, а от них пришлось и переписать счетчик строк кода в проекте. Облегчилось дело и в том, что теперь конфигурационные файлы не надо править как это было ранее при добавлении новых сущностей: ИК сам их находит и создает.

В данный момент в проекте 8545 строк кода,а процудера введения инкрементального компилятора затратила 146 минут.

Прикрепления: 9766062.png (12.2 Kb)
 
ArbitrДата: Вторник, 05.09.2023, 13:31 | Сообщение # 48
Составитель поездов
Группа: Пользователи
Сообщений: 9
Награды: 0
Репутация: 0
Статус: Offline
Цитата V9 ()
Игра проектируется под то, что люди сами смогут делать свои полигоны движения.
Прочитал, но мало что понял. Я правильно понимаю что игрок может выбрать любой участок  для создания, например Санкт-Петербург - Новый Петергоф, или это все те же грабли с сургутом без возможности что то поменять, ну разве ч то кроме наверно выхода на другой участок? Простыми словами скажи , что будет ( должно быть ) в итоге, без подробностей в кодах и прочим. Чисто тупо для пользователя вот это можно вот это нет.
 
Форум » СИМУЛЯТОР ПУЛЬТА ДИСПЕТЧЕРСКОЙ ЦЕНТРАЛИЗАЦИИ "НЕВА" » Эксперименты в симуляторе » Пытаюсь замутить свой симулятор.
  • Страница 3 из 3
  • «
  • 1
  • 2
  • 3
Поиск: