Задача состояла в том, чтобы навигация по дереву была такой же удобной как с XPath, а сериализованные данные занимали места даже меньше чем JSON. Получилось то, что получилось.
Написано на C# для Unity. Исходник можно скачать тут: StringTree.cs. Код далек от идеала, но в рамках испытаний показал себя достаточно быстрым и безотказным. Хотя алгоритм распаковки я, возможно, перепишу еще не раз.
Принцип работы
Допустим, мы имеем текстовый файл.
cabin { kitchen { fridge { // Количество мяса в холодильнике meat: 3; } } } // Данные о том, в какой комнате находится игрок currentRoom: "Cabin Kitchen"; inventory { pistol: 1; ammo: 10; }
StringTree stringTree = new StringTree(input); string ammo = stringTree["inventory/ammo"]; stringTree["cabin/kitchen/fridge/meat"] = "1"; string output = stringTree.Serialize(); // ammo: 10 /* output: cabin/kitchen/fridge/meat:1;inventory{pistol:1;ammo:10}currentRoom:"Cabin Kitchen" */
Помимо них класс имеет пару методов, присущих Dictionary, такие как Count и Clear, а также кучу вспомогательных Get'ов. Их работа описана в комментариях к коду.
Чтобы использовать класс вне Unity, достаточно удалить «using UnityEngine» и все «Debug.LogError» (или заменить их на подходящие вам аналоги).
Если обнаружите какие-либо недочеты, пожалуйста, сообщите.
P.S. Имеется также готовое решение для подобного хранения и упаковки байтовых массивов, но пока не знаю, куда его можно применить. Для числовых и строковых данных объем записи практически не уменьшается, но ее становится невозможно прочитать глазами.
А не проще использовать формат json?
ОтветитьУдалитьПо сути это и есть почти JSON, только без лишних кавычек и с возможностью присвоения значений несуществующим ранее переменным. Например, для описания предметов в инвентаре меня не устроил бы массив объектов вроде [ { "name" : "ammo", "count" : 10 } ] или двух параллельных массивов { "names" : [ "ammo" ], "counts" : [ 10 ] }. Но моя версия и не претендует на превосходство. :) Просто я не нашел более удобного способа сохранить состояние мира, структура которого не определена заранее. Хотя они, наверняка, есть. :)
УдалитьДописал в тексте, почему не.
Удалить