Войти
ПрограммированиеФорумИгровая логика и ИИ

Выбор методитики в загрузке сохраненных данных

#0
22:09, 14 окт. 2020

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

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

    void Проходим_По_Папкам(string путь)
    {
        bool bool_check = Directory.Exists(путь);
        int защита = 0;

        //если есть, идем дальше
        if (bool_check)
        {
            Debug.Log(this + ". путь = " + путь);

            //получаем все папки которе есть в этой папке
            string[] dirs = Directory.GetDirectories(путь);

            //Debug.Log(this + ". Папок в этой папке: dirs.Length = " + dirs.Length);
            //Debug.Log(this + ". Папка найдена - bool_check = " + bool_check);

            if (dirs.Length > 0)
            {
                //запускам по ним цикл
                for (int a = 0; a < dirs.Length; a++)
                {
                    //получаем файл который находится в этой папке
                    string[] fileEntries = Directory.GetFiles(dirs[a]);

                    Проходим_По_Папкам(dirs[a]);

                    //защита от зависания
                    защита++;

                    if (защита > 100)
                    {
                        Debug.Log(this + ". Сработала защита от зависания в Проходим_По_Папкам в цикле");

                        return;
                    }
                }
            }
  }

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


#1
22:42, 14 окт. 2020

sledo
> Такое дело, есть у меня потребность в создании бесконечной структуры иерархии,
> и я выбрал для сохранения ее данных иерархию папок.

Это называется граф типа "дерево". И ты уже придумал какое-то решение.
Остается только понять, что именно ты пытаешься решить (более чётко сформировать задачу).

#2
23:51, 14 окт. 2020

sledo
Не совсем понятен вопрос...
Но судя по заголовку темы, речь идёт о загрузке-сохранению дерева.
У меня конечно не бесконечная иерархическая структура, но более 400 000 узлов и листов (тезаурус иерархии понятий): https://yadi.sk/d/gVQ8IkVMofU9Gg - это маленький кусок для примера.
Пробовал несколько способов хранения дерева...
Самый лучший это хранить иерархию в базе данных.
В моём случае SQLite.
Относительно большое время  для сохранения неизбежно при больших объёмах, это не картинку сохранить\загрузить.

#3
16:34, 15 окт. 2020

rcsim
> И ты уже придумал какое-то решение.
Ну это да, просто одна голова хорошо, а много голов лучше.

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

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

#4
(Правка: 17:04) 17:03, 15 окт. 2020

sledo
Файлов сколько?
Если их десять тысяч и более, то загрузка из такой кучи - отнюдь не 10 секунд, тут как бы не было минут 30.
Файлы долго открываются, нельзя в релизной версии отставлять большое их количество.

#5
17:18, 15 окт. 2020

Zab
> Если их десять тысяч и более, то загрузка из такой кучи - отнюдь не 10 секунд,
> тут как бы не было минут 30.
> Файлы долго открываются, нельзя в релизной версии отставлять большое их
> количество.
В идеале конечно в каждой папке по одному файлу. Не могу сказать точно сколько будет их в итоге, поскольку планирую что сам пользователь будет создавать эту иерархию (делаю что-то типа стратегии, где таким образом создается армия - армия/отделение/солдат/объект у солдата/модуль на объекте/модуль на модуле/.../модуль на модуле).
Конечно я все это кэштрую, так что прогрузка только при сохранении и в начале игры. Не думаю что кто-то будет создавать прям вот тысячи папок, но оставить такую возможность я должен.

#6
21:32, 15 окт. 2020

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

#7
0:22, 16 окт. 2020

kipar
А свойства как описывать? Кроме того, огромный текстовый файл загружать в память - это как отказаться от ООП. Не, это я уже проходил, точно не решение.

#8
(Правка: 4:28) 4:26, 16 окт. 2020

sledo

Кроме того, огромный текстовый файл загружать в память
Писать всё в стрим.
Нужная часть стрима проецируется в память. + текст можно жать, например по LZMA нелету.
Стримы хорошо бьются(добавляются новые записи и безболезненно удалять любую запись) на бесчисленное количество частей.
Первая част - это оглавление, где хранятся указатели.
Причём там можно хранить бинарники, звуки, картинки и всё что хочешь.
Я так когда-то сохранял дерево всех своих ресурсов в виде ссылок на файлы, сайты и сами файлы - музыку,книги, картинки, статьи... и сейчас пользуюсь старой поделкой.
Ограничено только объёмом диска.
#9
8:26, 16 окт. 2020

sledo
Не текстовый, бинарный. Хотя можно и текстовый.
И не обязательно весь загружать, грузи последовательно по объекту за раз пока все не прочитаешь.

ПрограммированиеФорумИгровая логика и ИИ