В wwise есть прикольная штука, там вместе с саунд банками генерится хидер с проименованными ресурсами типа:
namespace WwiseEvents { const int My_shootgun_shoot = 1; const int My_pistol_shoot = 2; const int enemy_die = 3; }
Мне кажется надо копать куда то в эту сторону - нагенерили паков с ресурсами, нагенерили к ним хидеры - в игре используем эти хидеры. Нет коллизий, требуется мало памяти. На момент генерации можно понять, хватит 16 бит или надо 32.
А ну и в дебажной сборке можно нормально проименованные ресурсы рядом держать, чтобы в студии через natvis нормально в дебагере отображались, а в ретейле выкинуть эту инфу, если память надо сберечь.
HolyDel
> В wwise есть прикольная штука, там вместе с саунд банками генерится хидер с
> проименованными ресурсами типа:
Добавил новый спрайт и надо перекомпилить весь код. Чёт решение не очень.
у нас все идентификаторы из кода вызываются через enum'ы, а если нужно к ним обратиться через внешний код или через строку, то https://github.com/Neargye/magic_enum
смысл в том, что если список индентификаторов известен на этапе компиляции, то этим нужно пользоваться, потому что работать с уникальными айдишниками будет в любом случае быстрее, чем со строками. однако, в случаях, когда идентификатор необходимо получить именно по строке, есть magic enum (например, при десериализации).
Suslik
> смысл в том, что если список индентификаторов известен на этапе компиляции
Это путь EName из анреала.
Его главная проблема в том, что для добавления нового значения в енам нужно перекомпиливать код. Для тех-же имён текстурок это неприемлимо так как получится, что для добавления новой текстурки в игру прийдётся перекомпилить весь код.
Что примечательно в анреале EName и FName совместили, для получения плюсов от компайл тайм решения, как я понимаю там пулл строк по дефолту не пустой а заполнен сотней захардкоженных строк.
samrrr
> Его главная проблема в том, что для добавления нового значения в енам нужно
> перекомпиливать код.
ясное дело, инклудить такие файлы нужно только там, где используются эти идентификаторы. если у тебя при добавлении нового идентификатора текстуры перекомпилируется весь проект, это значит, что у тебя слишком много лишних зависимостей.
напомню, что для enum class'ов С++ умеет в forward declaration, то есть во всяких хедерах вообще не нужно включать реализации enum'ов.
Suslik
> напомню, что для enum class'ов С++ умеет в forward declaration, то есть во
> всяких хедерах вообще не нужно включать реализации enum'ов.
Это не особо поможет, так как все цпп где используется такой енам всеравно нужно перекомпилить.
Обычно в движке просто добавдяешь текстурку, и все. А не добавляешь 5 мин перекомпиливаешь все двигло, и смотришь результат. Артовики от подобного будут очень недовольны, а единственный плюс в отличие от моего варианта 4 это создание switch по строке который чуть быстрее, чем выборка из мапы.
samrrr
У меня сделан 4й вариант, но чуть иначе:
template <usize Size, uint UID, bool Optimize, uint Seed = UMax> struct NamedID { HashVal32 _hash; }; template <usize Size, uint UID, uint Seed> struct NamedID< Size, UID, false, Seed > { HashVal32 _hash; FixedString<Size> _name; // чтобы было POD типом, иначе можно std::string }; // пример использования file = GetVFS().OpenAsStream( VFS::FileName{"canvas2d.atlas"} );
ID в коде - это компайл тайм хэш от строки. Но большая часть ресурсов упаковывается заранее, поэтому там используются строки + проверка на хэш коллизии.
samrrr
> Обычно в движке просто добавдяешь текстурку, и все
все строки, которые не адресуются из кода, а приходят извне (например, из метаданных, из ресурсов), сразу при получении хендла ковертятся во внутренний uint32_t (или подобный) id. далее все операции сравнения выполняются для этих id, а сами строки используются только для сериализации и десериализации.
Suslik
> сразу при получении хендла ковертятся во внутренний uint32_t
Это какраз вариант 4.
/A\
> Но большая часть ресурсов упаковывается заранее, поэтому там используются
> строки + проверка на хэш коллизии.
В этом и фокус, не всегда можно заранее проверить все ресурсы. Конечно можно прям на старте грузить всё, только вот у того-же унижайна это получилось плохо.
samrrr
> не всегда можно заранее проверить все ресурсы
Только если у тебя пользователь создает ресурсы, иначе ты всегда заранее знаешь все ресурсы.
/A\
> иначе ты всегда заранее знаешь все ресурсы.
Ну ежели ты соло пилишь, то да.
samrrr
> Ну ежели ты соло пилишь, то да.
А в чем разница? У тебя есть архив с ресурсами, который ты распространяешь с программой. Даже если докачиваешь ресурсы по сети, то все равно знаешь все их названия.
/A\
> А в чем разница?
Когда пилишь в команде, у тебя есть например артовик, один, у него стоит что угодно, кроме visual studio. И вот он наделал в субстансе новый камешек на уровень. И вдруг опа, он не добавляется. Точнее добавляется но вместо текстурки чушь. В логе пусто, и разгребай как хочешь)
Рано или поздно ты выяснишь что произошла коллизия твоего 32 битного хеша. Только вот зачем плодить проблемы на ровном месте? Просто берёшь и делаешь вариант 2, 3 или 4 и такой проблемы не будет в принципе никогда. Да и тот-же вариант 3 в дебагере тебе покажет что за строка, и ты не будешь гадать чтож значит сообщение из лога: Ресурса с хешем 42 нет на диске.
samrrr
У меня давно выводится деьажная инфа, даже в движке
/A\
> У меня давно выводится деьажная инфа, даже в движке
И каким образом?
Тема в архиве.