LINUX.ORG.RU

Менеджер ресурсов «игровой» поиск реализации/архитектуры

 , , ,


0

2

Продолжаю пилить велосипед.

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

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

При первом варианте думается следующее.

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

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

Разраб далее работает с указателем как с объектом передавая его туда сюда.

А что если:

Переложить на плечи менеджера загрузку, выгрузку, учёт и помимо этого всего и передачу данных подсистемам.

То есть грузим ---> менеджер регистрирует, грузит, создаёт указатель заносит его в базу генерит идентификатор(просто число int) и отдаёт его разрабу.

Разраб будет иметь просто переменную с идентификатором скажем переменная int monstr. Далее передаёт её скажем рендеру render(monstr,-10,0,0); рендер передаёт значение обратно менеджеру тот ведёт поиск по идентификатору указателя на объект и уже реально передаёт настоящему рендеру косвенно или на прямую производя все необходимые операции.

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

Жду пинков по ссылкам, примерам, статьям.

★★★★★

Ответ на: комментарий от AIv

Не верю, что на каждый чих вы пишете свой аллокатор/деаллокатор/сборщик. А если и надо, то в C++ можно и написать, да. Только надо оно не всегда.

Странный Вы... Все равно что ругать болид формулы-1 за ручную коробку передач - вот дескать, моя лада-калина и та с автоматом;-)

Ну с тем же CL C++ можно сравнить в категории «язык на каждый день». Разве нет? С C тут сравнить может и нельзя из-за отчасти «системной» направленности C

amphibrakhij
()
Ответ на: комментарий от amphibrakhij

не с биндиться, пардон

Если бы у королевы были яйца, она была бы королем.

Он не любимый, просто для низкоуровневых вещей самое то, действительно. А вот C++ вроде как претендует и на другие ниши (тот же десктопный софт на Qt), а в сути он ничем от C не поменялся, только OOP добавили.

И шаблоны. Это ИМНО даже важнее, классы на С делаются, а вот шаблоны...

ООП в ЦПП, кстати, тоже ругают. Я более-менее знаю только CLOS, и для меня самое главное, что generic functions там первокласные объекты, а методы в ЦПП - нет.

Я не говорю что он идеален, я говорю что для ряда задач альтернатив нету.

Поэтому ЦЛ и сливает вчистую по производительности;-)

Наглая ложь, кстати )

www.linux.org.ru/wiki/en/User:AIv/LRnLA - а вот Вам пример. На CL такого пока не сделали, хотя если верить лисповодам задача как раз под него;-)))

AIv ★★★★★
()
Ответ на: комментарий от amphibrakhij

Не верю, что на каждый чих вы пишете свой аллокатор/деаллокатор/сборщик. А если и надо, то в C++ можно и написать, да. Только надо оно не всегда.

Как правило я юзаю готовые, их хватает и это удобно. При необходимости допиливаю, важно то что я могу это сделать. В отличии от автоматического управления памятью, где об этом вообще думать не надо, но допилить ничего нельзя.

Кстати, в том же питоне приходится учитывать особенности управления памятью и работу GC, и иногда это сильно мешает.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Если бы у королевы были яйца, она была бы королем.

Для кого-то это может быть реальной задачей.

И шаблоны. Это ИМНО даже важнее, классы на С делаются, а вот шаблоны...

Это костыль, который нужен, потому что ничего другого нет. В в хацкеле каком-нибудь они не нужны.

На CL такого пока не сделали

Тут я не готов что-либо ответить.

amphibrakhij
()
Ответ на: комментарий от AIv

Я не говорю что он идеален, я говорю что для ряда задач альтернатив нету.

Тут разве в производительности дело только. А java сильно отстает от C++ в этом плане?

amphibrakhij
()
Ответ на: комментарий от amphibrakhij

Если бы у королевы были яйца, она была бы королем.

Для кого-то это может быть реальной задачей.

Ахтунг! Транствеститы в треде!;-))))

Это костыль, который нужен, потому что ничего другого нет. В в хацкеле каком-нибудь они не нужны.

Этот костыль позволяет делать очень изящные вещи. Рекурсия на шаблонах, SFINAE... прикол в том, что код получается компактынм и очень быстрым. В отличии от 100500 ЯП, где будет код в два раза компактнее и в 1000 раз медленней.

Тут разве в производительности дело только.

Для некоторых задач производительность является приоритетом. Если что то считается три месяца, толку с этого чего то никакого...

А java сильно отстает от C++ в этом плане?

Для числодробилок, оперирующих большими объемами данных, про яву для выч.ядра говорить довольно смешно. В самомо лучшем случае (для явы) должна сливать в разы.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Рекурсия на шаблонах

А кто-то факториалы на них считает. И кто тут трансвестит? :)

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

А кому-то долгая компиляция не нравится. Мне тоже, так как FreeBSD - source based по большей части

В некоторых языках параметрический полиморфизм был изначально и продуман лучше, и работает всё быстро, так что C++ тут далеко не единственный с такими фичами.

amphibrakhij
()
Ответ на: комментарий от Dron

Ресурсы в 3D играх экономят в основном не за счёт загрузки/выгрузки, потому что NTFS на файловых операциях таки медленнее ext4, порой в несколько раз, и был бы дикий io bound.

Что реально поможет — так это хранение тех же текстур в сжатом виде, с помощью одного из алгоритмов сжатия в OpenGL/GLES. С моделями я проделывал такой трюк: если число вершин меньше MAX_SHORT, то индексы вершин хранятся в типе short unsigned, иначе в unsigned, причём приведение массива индексов к правильному типу производится прямо при рендеринге в зависимости от того, включен или нет флаг «используется short».

Ещё есть такая фишка в Objective-C, как сообщение didReceivedMemoryWarning. Если кратко, каждый класс унаследован от NSObject и может при желании переопределить сообщение didReceivedMemoryWarning, выполнив в нём какие-либо действия. В той же iOS при достижении определённой планки по потреблению памяти система рассылает всем объектам сообщение didReceivedMemoryWarning, и многие объекты из Apple'овских фреймворков в этот момент сбрасывают кеши. При этом планка маленькая, ЕМНИП в 10 раз меньше того лимита, при котором система убъёт приложение.

Стоит также посмотреть на mmap и её возможности.

quiet_readonly ★★★★
()
Ответ на: комментарий от amphibrakhij

А кто-то факториалы на них считает. И кто тут трансвестит? :)

А кто тут на них факториалы считает O_O?

А кому-то долгая компиляция не нравится. Мне тоже, так как FreeBSD - source based по большей части

Никому не нравится. Но если оно перекрывается выигрышем в производительности (и скорости разработки), то оправдано.

В некоторых языках параметрический полиморфизм был изначально и продуман лучше, и работает всё быстро, так что C++ тут далеко не единственный с такими фичами.

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

AIv ★★★★★
()

гдето как ты обрисовал я и делал, синглтон ResourceManager, инкапсулирует std::unordered_map<std::string, std::shared_ptr<YourResource>> для каждого типа ресурсов. отдает ресурсы по имени файла, путь к файлу является ключем в мапе.

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

x0r ★★★★★
()
Последнее исправление: x0r (всего исправлений: 1)
Ответ на: комментарий от annulen

А Вы поглядите как в stl сделан хэш, полюбопытствуйте. Или по Вашему там вектор сидит длиной 2^32?;-)

AIv ★★★★★
()
Ответ на: комментарий от annulen

1) Де факто поиск по хэш-значению экививалентен поиску по rb-tree, занимает O(log2(N)) и основан на половинном делении. Или Вы знаете более шустрые алгоритмы поиска по разреженному целому ключу? В unordered_map поиск оптимизирован с учетом того что ключ int, но яйцы те же, тока в профиль.

2) Да хоть список пар. Я повторю вопрос, Вы знаете алгоритм поиска по разреженному ключу работающий быстрее чем O(log2(N))?

AIv ★★★★★
()
Ответ на: комментарий от AIv

Вдогонку - учтите еще обработку коллизий.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Насколько я знаю, в классической хэш-таблице осуществляется отображение i = f(x) % N, где x - ключ, f - некоторая функция (для инта обычно тождественная), N - размер таблицы (обычно простое число). В результате, разреженный интервал отображается в неперерывный, в котором поиск осуществляется за О(1). В случае коллизий все, конечно же, усложняется, но в простом случае никакого логарифма нет.

annulen ★★★★★
()
Ответ на: комментарий от annulen

Да, и еще кэширование последнего запроса в каждой из N ячеек для ускорения разрулирования коллизий. Но в unordered_map поиск половинным делением по хэшу, а в описанном Вами случае гарантированные коллизии в ячейках за счет укороченного интервала, и еще неизвестно что хуже.

ИМНО тут нужно ограничивать диапазон ID (скажем short, 2^16) и юзать обычный вектор, а пустые ID хранить в set для ускорения выделения. Если конечно ТС-у 2^16 объектов хватит;-)

AIv ★★★★★
()
Последнее исправление: AIv (всего исправлений: 1)
Ответ на: комментарий от annulen

Я не верю в чудеса. Скорей всего там что нить в этом роде и замутили...

AIv ★★★★★
()

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

note173 ★★★★★
()
Ответ на: комментарий от note173

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

netcat ★★
()
Последнее исправление: netcat (всего исправлений: 2)

У меня из похожего есть только работа с текстурами.

Сделано это так: В статическую функцию (член класса GLTexture) передается «путь» к текстуре (что-то вида «/interface/icon/home»), внутри функции создается текстура, заворачивается в самописный хитрый «указатель» и добавляется в список уже сущесвтвующих текстур.

При повторной попытке создания такой же точно текстуры будет возвращен еще один хитрый «указатель» на нее.

Как только все указатели на ресурс в программе уничтожены - он выгружается из памяти.

Хитрый указатель виден пользователю как объект класса GLTexture, у которого в паблик торчит только конструктор копирования, а остальные конструкторы в привате.

P.S. Если я правильно понял, о чем ты вообще написал.

trex6 ★★★★★
()
Последнее исправление: trex6 (всего исправлений: 1)
Ответ на: комментарий от quiet_readonly

В C++ нет автоматического управления памятью - раз

Ещё скажите, что в C++ нет классов.

Полагаю, что речь о GC, кторого, естественно, в плюсах нет.

идентификаторы указывают на значение, а не на ссылку, - два

Что, простите?

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

andreyu ★★★★★
()
Ответ на: комментарий от AIv

1) Де факто поиск по хэш-значению экививалентен поиску по rb-tree, занимает O(log2(N)) и основан на половинном делении.

Не знаю, откуда у вас такие факты, но у меня поиск по хешу такой:

index = hash_value % hash_table_size

Поиск получается быстрый, приложение получает указатель на объект, если тот уже загружен.
Одна «проблема» - нужна утилита, которая подготовит ресурсы и создаст файл с хешами или расскажет о коллизиях (тут уже ручная работа - тупо меняем имя ресурса, хотя можно заставить и утилиту сделать это по некому правилу).

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Не знаю, откуда у вас такие факты

Посмотрите сырцы или потестите скорость доступа в unordered_map зависимости от числа записей. Очень поучительно.

у меня поиск по хешу такой

Если у Вас хватает свободных слотов в таблице, то нафига тут хэш таблица? Достаточно обычного вектора. Если у Вас не хватает слотов, то расскажите как Вы будете искать среди объектов с одинаковым index = hash_value % hash_table_size.

AIv ★★★★★
()
Ответ на: комментарий от trex6

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

То есть разраб даже с подсистемами на прямую работать не будет.

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

Dron ★★★★★
() автор топика
Ответ на: комментарий от trex6

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

Dron ★★★★★
() автор топика
Ответ на: комментарий от note173

Хватит уже писать велосипеды

Нет, нет и ещё раз нет это полезно, для образования в частности, делаю для удовольствия и вообще придумывать что-то интересно ;)

Сначала нужно найти и использовать готовую реализацию

Реализация это дело второе гораздо важнее архитектура, а уж как реализовать это мои проблемы и тут 100500 подходов реализации можно придумать. Хотя посмотреть на готовое полезно тут я спорить не стану вы правы. Пинки дали в нужных направлениях я и изучаю.

Сейчас всё именно на стадии изучения и проектирования если что.

Dron ★★★★★
() автор топика
Ответ на: комментарий от dmitryalexeeff

Магистр Йода, это Вы?

Ага собственной, маленькой персоной :)

А вообще не распарсил смысл вопроса.

Dron ★★★★★
() автор топика
Ответ на: комментарий от dmitryalexeeff

По-моему, это просто периодически отваливающиеся запятые

wingear ★★★★
()
Ответ на: комментарий от anonymous

А как же коллизии?

Я же написал, как решать коллизии.

andreyu ★★★★★
()
Ответ на: комментарий от Dron

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

note173 ★★★★★
()
Ответ на: комментарий от AIv

Посмотрите сырцы или потестите скорость доступа в unordered_map зависимости от числа записей. Очень поучительно.

К чему вы это вообще сказали?

Если у Вас хватает свободных слотов в таблице, то нафига тут хэш таблица? Достаточно обычного вектора.

Кто сказал, что индексы все будут идти подряд? Хеш универсальнее.

Если у Вас не хватает слотов, то расскажите как Вы будете искать среди объектов с одинаковым index = hash_value % hash_table_size.

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

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

К чему вы это вообще сказали?

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

Кто сказал, что индексы все будут идти подряд? Хеш универсальнее.

А вектор кардинально быстрее. Индексы пойдут так, как их выделят, тут полна свобода, и они не обязаны идти подряд - в векторе могут быть дырки тащем то.

Во-пепрвых, все это решается на этапе сборки.

А это Вы к чему сказали O_O?

Во-вторых, проблему коллезий решают давно и непринужденно.

Как именно? И сколько такие решения стоят с т.з. производительности?

AIv ★★★★★
()
Ответ на: комментарий от AIv

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

Таблица не помещается в кеш?

А это Вы к чему сказали O_O?

Мы в этой ветке ведем речь о том, как организовать работу с ресурсами в движке.

Как именно? И сколько такие решения стоят с т.з. производительности?

Зависит от ситуации, но это все решается на этапе сборки.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Таблица не помещается в кеш?

ТС не знает сколько у него объектов. Но если таблица влезает в кэш, то однозначно это должен быть вектор.

Мы в этой ветке ведем речь о том, как организовать работу с ресурсами в движке.

Спасибо К.О. И как этому относится Ваша фраза что все решается на этапе сборки? Она применима тащем то к 99% проектов.

Зависит от ситуации, но это все решается на этапе сборки.

Вы повторяетесь. Или давайте конкретные решения по разрешению коллизий применительно к данной ситуации с оценкой их накладных расходов, или не надо ля-ля.

AIv ★★★★★
()
Ответ на: комментарий от AIv

ТС не знает сколько у него объектов. Но если таблица влезает в кэш, то однозначно это должен быть вектор.

Есть truetype. Есть текст, который использует этот фонт. Есть инпут от пользователя. Какие глифы понадобятся в данный момент не известно. Растеризовать все глифы глупо. Хранить индексы в векторе накладно. Вот тут хеш будет очень хорош. И таблица будет небольшая, и текстура минимальная.

Спасибо К.О. И как этому относится Ваша фраза что все решается на этапе сборки? Она применима тащем то к 99% проектов.

Тогда с чем вы спорите?

Вы повторяетесь. Или давайте конкретные решения по разрешению коллизий применительно к данной ситуации с оценкой их накладных расходов, или не надо ля-ля.

Вам нужны конкретно мои решения по коллизиям или общепринятые решения?

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Хранить индексы в векторе накладно. Вот тут хеш будет очень хорош. И таблица будет небольшая, и текстура минимальная.

Следите за руками. На каждый ID, а каком бы контейнере он не лежал, требуется держать некую структура данных - состояние объекта, тип объекта и т.д. и т.п. У вектора самая большая скорость доступа, памяти под него (под не используемые ID) при известном и разумном числе объектов потребуется немного. Про кэширование - ОС лучше Вас знает что и как кэшировать. И в чем профит от хэш-таблицы, которая при отсутствии коллизий ничем не лучше вектора длиной N (кроме вызова операции %N на каждый доступ) а при наличии коллизий по сравнению с вектором аццки тормозит?

Тогда с чем вы спорите?

Мы не спорим, тем более не спорим с тем что «все решаестя на этапе сборки». Это Вы тут пропагандируете хэш-таблицы;-)

Вам нужны конкретно мои решения по коллизиям или общепринятые решения?

Мне нужны магические решения, которые обеспечивают доступ к хэш таблице с той же скоростью, что и к вектору. У Вас такие еcть?

AIv ★★★★★
()
Ответ на: комментарий от dmitryalexeeff

Оу, билин запятые опять.

Dron ★★★★★
() автор топика

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

Dron ★★★★★
() автор топика

Как уже похоже сказали, от него надо VFS, кэширование.

Скажем десериализатор разворачивает карту из блоба. Встречает физический объект, передает соответсвующий кусок в физику. Там создается физ. объект, задается ориентация/положение/скорость из потока. И есть ссылка на /res/phys/obj4, физика идет к ресурсам, получает блоб, разворачивает в свои структуры.

Дальше графический объект, для примера сохраняемых данных нет, только сслыка на сетку и текстуру. Через ресурсы получаем и то и другое. Создается граф. объект.

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

Логика связывания, самое простое - скопировать (передать ссылку) матрицы ориентации из физики в графику. Более сложная логика может сама создавать новые объекты. Таким образом можно делать одновременно и игровые объекты и например UI.

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

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

amaora ★★
()

Разраб будет иметь просто переменную с идентификатором скажем
переменная int monstr. Далее передаёт её скажем рендеру
render(monstr,-10,0,0); рендер передаёт значение обратно менеджеру тот
ведёт поиск по идентификатору указателя на объект и уже реально
передаёт настоящему рендеру косвенно или на прямую производя все
необходимые операции.

В этом вызове я вижу добавление в очередь на рендер. Но есть ли смысл каждый раз решать что рендерить а, что нет? Может быть ещё и в каком порядке? Не лучше ли оставить такие вопросы самому рендеру?

amaora ★★
()
Ответ на: комментарий от amaora

надо VFS

Смотрю пока на PhysicsFS вроде норм.

Интересные мысли спасибо.

Dron ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.