Spiiin's blog

Трюки с сериализацией на clang от Valve

Пара докладов с GDC ~2012
Robustification Through Introspection and Analysis Tools (Avoiding Developer Taxes)
Physics for Game Programmers: Debugging Physics

“Налоги” — это то, что непосредственно не приносит пользу продукту, но упрощает жизнь. Примеры для геймдева — сериализация, статистика памяти, привязка к скриптам, версионирование

Примеры того, что сделали, распарсив код с помощью Clang:

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

struct A0 {float x; byte y;}
char* A0_type[] = {"FB"}; //подставляется из сгенерированного типа
void save_any(void* obj, char* type) {
while (*type) { switch (*type++) {
case 'F': //write(); obj += sizeof(float);
case 'B': //write(); obj += sizeof(byte);
...
case 0: return;
}}
}

Можно отследить по диффам изменения форматов и генерировать код сериализации/десериализации для разных версий структуры + отслеживать перемещение полей между структурами

Slim bindings

“Трамплины” для обвязок функций для скриптого языка

typedef int (*func_int__int_charptr)(int i, char* c) //для каждого типа сигнатур
void trampoline(void** buf, func_int__int_charptr) {
int& ret = *(int*)buf[0];
int& arg0 = *(int*)buf[1];
char* arg1 = *(char*)buf[2];
ret = (*funcptr)(arg0,arg1);
}
// и потом:
//call_in_lua() -> lua_bridge-> (на разные трамплины) trampoline_int__int_charptr->native(int, char*)

В трамплин передаётся структура, описывающая сигнатуру функции. Делается ради экономии места в бинарнике на сгенерированных скриптовых lua-привязках — вместо создания кода привязки для каждой отдельной функции создаётся трамплин для каждой функции и описания данных для трамплина. Требует одной дополнительной индирекции на каждый вызов функции. Можно даже шарить трамплины между разными привязками к языкам (lua_bridge/python_bridge)

Подсчёт используемой памяти в рантайме

Если для каждого типа знаем его структуру и размер, то можем просуммировать и вывести отчёт с визуализацией

Внешние тулзы для просмотра типов

  • можно просмотреть, какие типы POD и хорошо сериализуются, а какие требуют runtime-цикла с сериализацией отдельных членов
  • по json с описанием типов можно восстановить padding в структурах, визуально

А также дифф этого из vcs

Передача blob-а и десериализация в другом процессе
Данные из игры выдёргиваются и передаются в программу отладки физики