Обновить
6
20.1
Иван@Adler3D

Автор

Отправить сообщение

Оператор typeinfo обеспечивает инспекцию типов

Простого typeinfo из Ü/С++ пока недостаточно, т.к они например не захватывают информацию о выражении которым инициализируются поля структур/классов.

Вот если бы Ü был дружелюбен для разработки достойной системы сериализации/RTTI/толковых_умных_указателей/генерации_парсеров и на нём можно было повторить например разработку такой истории как тут, то тогда было бы понятно как переманивать программистов с других языков программирования.

Сделал статью "что-то вроде минимального примера" как вы просили: https://habr.com/ru/articles/978216/

Пойдёт?

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

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

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

наверно потому что тот кто ответственен за повальную автоматизацию пока не видит в этом смысла/профита. да и зачем спешить? можно дать всем шанс автоматизировать всё самостоятельно, а не насильно. если интересно вот чуть больше инфы по теме(там два сообщения от меня и два от ИИ): https://chat.deepseek.com/share/hexvsm55d4xueez6mh

ИИ подсказывает что вы хотите узнать зачем вам вообще мигрировать типы, если можно описывать всё через таблицы и каждый раз собирать сцену заново? То есть вы предлагаете перейти на декларативную сборку сцены тому кто занимается задачей "миграцией долгоживущего состояния сцены + эволюции типов"? Если так то спасибо за идею, но мне мой подход больше нравится. почему/зачем я так делаю/сделал? - потому что раньше мне казалось что это путь к идеальной архитектуре программ, а перестирать сцену каждый раз - это слишком простой/слабый/тупиковый путь. сейчас я менее категоричен и вижу плюсы обоих подходов и думаю что будущее за гибридным решением.

попросил ИИ перевести на понятный мне язык, вот его цитата:

«Я понял, что вы не сериализуете стек и выполнение.
Тогда, если уж есть описание состояния, его можно:

  1. представить как байткод

  2. патчить

  3. при желании транслировать в нативный код

Но для этого придётся сделать язык + VM + транслятор,
то есть фактически DSL, а не просто сериализацию данных.
Это сложно, похоже на изобретение велосипеда,
но в итоге можно получить мощный комплекс отладки и патчинга.»

интерпретация от ИИ:

Он согласился с тобой, но:

  • не может выйти из парадигмы «всё = код»

  • поэтому постоянно тянет разговор к VM / DSL / байткоду

Ты же работаешь в другой оси:

  • данные эволюционируют

  • код остаётся нативным

Он этого ментально не различает.

вот что я думаю читая это:

что бы я сделал если бы нашёл кого-то кто про финансирует open-source разработку? - свой язык программирования который сразу без танцев с макросами и шаблонами понимает мою систему RTTI/STTI/указатели и при миграции между форматами генерирует настоящий нативный код для сохранения и загрузки состояния в этом новом формате, плюс ещё если к этому добавить safe_eval+unsafe_eval, то вообще было бы шикарно.

мы здесь не сериализуем некоторые вещи связанные с выполнением программы, а именно:
не сохраняем стек вызовов
не сохраняем PC / позицию выполнения
не трогаем низкоуровневые детали вроде сетевых или GPU-состояний

мы тут сериализуем почти всё состояние данных, включая ссылки и типы, чтобы:
обновлять бинарь
мигрировать структуры
продолжать работу без VM

VM/JIT решают другую задачу - управление кодом, а не миграцию данных между версиями типов.

для этого придумали скриптование. делаете какой-нибудь ctrl+r и триггерите переинициализацию скрипта. hotreload никогда не требовал сериализации графа.

Ну чистая правда, даже придраться не к чему. Хотя есть: скрипты - это иногда медленно; структуры данных внутри скриптов также может меняться и ломать миграцию молча и противно. Можно попробовать парировать отсылкой к JSON-based системам миграции, но это опять же медленно и не лишено кучи недостатков.

заводите класс реестра ресурсов и просто ссылаетесь на ресурс по некоторому составному id - resource id + offset id. В качестве resource id можно взять например djb2 хэш от пути к ресурсу. Offset id зависит от того как вы получаете конкретный элемент в ресурсе. Пару широких интов определённо проще сериализовать чем возиться со ссылочными типами, которым ещё некоторую персистентность надо навести.

100% правда. я так поступил из-за своего неумения проектировать программы. я даже не могу возразить что у меня есть плюс - типа мои ссылки быстрее работают, а вот нифига, id+hash рулят и педалят походу. Всё что меня спасает - это отсутствие коллизии хэшей вообще.

Так а используется-то оно как? Выглядит как несколько странный дебаггинг, судя по вашему описанию.

Используется при миграции между форматами.

Ну, вы же решали какую-то свою боль, изобретая вот это вот всё.

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

Сделайте минимально воспроизводимую боль. Пусть без окон и imgui крутилок, но понятную другим.

ИИ подсказывает что можно сделать демонстрацию профита от моей системы на примере системы из publisher-subscriber и их миграции в новый формат. Попробую сделать. Спасибо за то что навели на хорошую идею примера!

Там даже в README прямым текстом:

“Unfortunately POST++ due to its simplicity provides no facilities for automatic object conversion”

POST++ — это persistent object store на mmap, а не сериализация с миграциями.
Он предполагает стабильный layout, адреса и не поддерживает автоматическое изменение типов.
В моей задаче ключевыми были самоописание формата и обновление бинарника без потери данных, поэтому подход принципиально другой.

а зачем это нужно именно в текстовой информации

текстовый формат у меня чисто для отладки

тогда проще написать виртуальную машину, если есть требование такой отладки

виртуальная машина не решает проблемы миграции данных между разными(старой и усовершенствованной) системами типов, но зато позволяет менять код что очень круто, правда, как вы верно заметили, ценой замедления программы в 10-50 раз, что для меня не приемлемо.

Да, я хочу знать всё в своих программах :)

Вы же решали какую-то проблему

Я на основе этой системы сохранял/загружал/мигрировал всё состояние своих программ, а так же делал довольно крутой(как мне тогда казалось) графический отладчик/интроспектор для них. Последний позволял добраться до почти любой хранимой переменной и поменять её.

Уменьшите скоуп проблемы и сделайте из неё пример поменьше.

Проблема было две: "сохранить всё состояние программы" и "менять его в реальном времени не перезапуская программу", как мне уменьшить такой скоуп? Сохранить половину состояния программы? :)

Заодно будет видно зачем понадобилось иметь ссылочные типы и частичную сериализацию структур

Ссылочные типы очень пригодились для описания типов используемых внутри сохраняемого файла, хотя конечно всё можно было заменить на строки и тогда мы бы поменяли производительность на простоту реализации. У меня получилось нифига не просто, но зато компактно и быстро. Ещё ссылочные типы используются для указания на текстуры/шрифты/спрайты_в_атлассе/клавиатур... но всё это можно переделать на строковые идентификаторы и победить в 80% случаев как мне кажется. Вообще я планировал использовать ссылочные типы для того чтобы боты в игре ссылались друг на друга, но как оказалось - это плохой дизайн и лучше иметь локальные числовые идентификаторы, а не глобальные умные следящие указатели.

Накидайте какой-нибудь граф, который вы хотели сериализовать.

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

Simple persistent storage

У меня не простое хранилище, а полноценная система, так что вы направляете меня/читателей скорее всего не туда.

delete rec;

ну и там походу даже своих умных указателей нет.

Как-то вы на примеры сериализации/десериализации поскупились

Спасибо за замечание, хорошо, попробую добавить ещё примеров как только придумаю их. Есть какие-то пожелания что именно вы хотели бы увидеть в них?

Кажется проблема решается несколько проще без необходимости изобретать собственные умные указатели.

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

тут можно посмотреть сколько занимает build на гитхабовский серверах, в среднем в районе 30 секунд

Для почти пустого целевого проекта(тоесть такого который использует ecss) это очень много, на первый взгляд. Хотя наверно для O2 может и норм. Чтобы не было потом неожиданностей с временем компиляции при разработке крупного(например, как стресс тест: 500 компонентов + 20000 архетипов) проекта хочется обширного исследования этой темы. Конечно понадобиться писать простые кодогенераторы, но оно того стоит - можно потом выдать ещё на публику рейтинг компиляторов по скорости компиляции и по производительности.

Про сравнения с классическими подходами: имеете ввиду c обычным вектором структур?

// да, что-то в духе вот этого:
struct t_node{vector<t_node> arr;vec3f offset,dir;string name;t_geom geom;};
struct t_tank{vec3f pos,v;float hp=100.0f;bool deaded=false;t_node n;};
struct t_bullet{vec3f pos,v;float dhp=-1.0;};
struct t_link{int a,b;float r=1.0f;};
struct t_network{
  vector<QapColor> points_colors;
  vector<vec3f> points;
  vector<t_link> links;
  QapColor links_color=0xffffffff;
  QapColor points_color=0xffffffff;
  float points_r=1.0f;
};
struct t_world{
  vector<t_tank> tarr,dtarr;
  vector<t_bullet> barr;
  t_network net;
};
// t_node - можно выкинуть в одном из тестов для того чтобы было попроще: без деревьев.
// ещё в недостижимом идеале, чтобы добить все остальные устаревшие подходы
// к построению архитектуры игровых движков можно сравнить производительность 
// например с моими "древовидными системами сущностей"(2011 год):
// https://github.com/adler3d/MarketGame/blob/e8474691c5082c68e62790cfc5ac2440a830ed29/QapEngine/QapEntity.h#L260
struct QapItem:QapObject{
  QapFactory*Factory;
  QapList*Parent;
public:
  #define DEF_PRO_CLASS_INFO(NAME,OWNER)NAME(QapItem)
  #define DEF_PRO_METHOD(F)F(DoReset);
  #define DEF_PRO_VARIABLE()\
  ADDVAR(string,Caption,GetClassName()+"_Boss");\
  ADDVAR(bool,Visible,true);\
  ADDVAR(bool,Moved,true);\
  ADDVAR(int,SaveID,0);\
  ADDVAR(int,Tag,0);
  ...
};
struct QapList:QapItem{    
  vector<QapItem*> Items;
  vector<QapItem*> DeadList;
  ...
};
// - это два базовые сущности от которых потом наследуются все остальные игровые объекты.

PS: И я вам ещё достойного отечественного конкурента для сравнения нашёл/вспомнил.

Выглядит круто. Расскажите как обстоят дела с возможно самой печальной частью крутых проектов на С++ по сравнению с конкурентными подходами - как дела с времен компиляции?

Планируете ли приделывать сериализацию/десериализацию?

Ещё не хватает сравнения с классическими подходами(чисто на основе комбинации структур+векторов), насколько силён прирост в производительности?

PS: Подпишите пожалуйста что на финальной картинке "Lower values mean better performance". Спасибо за вклад в Open Source!

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

Так как я не обладаю экспертизой в данной области решил прибегнуть к помощи ИИ и вот что он пишет: "СССР не был “симуляцией” ни технически, ни методологически." и советует ответить так:

  • СССР не был экспериментом: он не создавался для сравнения социальных структур.

  • Условия непрозрачны, переменных миллионы, нет контроля среды.

  • Невозможно проводить “повторы” или менять один параметр.

  • Нет операциональных определений изобретателя/иерархии/массового процесса.

  • Масса факторов не имеет отношения к эволюции структур (идеология, геополитика, насилие, экономика XX века).

Это как сравнить:

модель искусственной жизни
vs
реальный муравейник, на который падают камни, пожар, наводнение и 3 ребёнка с палками.

То есть реальная страна ≠ лабораторная среда.

И ещё ответить так:

Спасибо за развёрнутый взгляд! Но всё-таки мой фокус был немного другим — не на реальных государствах, а на абстрактных моделях социальных структур в условиях ограниченных ресурсов.

В реальных обществах слишком много неконтролируемых факторов (идеология, внешняя политика, исторический контекст), поэтому они плохие “чистые эксперименты”.

В симуляции можно: — задать фиксированные правила, — варьировать параметры, — сравнивать стратегии “иерархии” и “массовых изобретателей” в одинаковых условиях.

Это всё, что мне хотелось исследовать. Если у вас есть идеи как именно формализовать такие механики, это было бы супер интересно. Например: — какие параметры должны влиять на успех структуры? — как формировать агента-“изобретателя”? — что считать инновацией в симе?

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

Информация

В рейтинге
414-й
Зарегистрирован
Активность

Специализация

Десктоп разработчик, Разработчик игр
От 231 456 ₽
C++
Node.js
JavaScript