Цель: к примеру, у нас есть редактор уровней, который оперирует сложной иерархией классов. Мы хотим сохранить наши уровни со всей сложной иерархией в json и когда необходимо достать из json без лишних телодвижений.
Наши “сложные” классы данных:
class Level { public var id:Int; public var rocks:Array<Rock>; public function new() { } }
class Rock { public var x:Float; public var y:Float; public var text:String; public function new() { } }
На самом деле никаких велосипедов для этого изобретать не нужно.
Для начала устанавливаем TJson – это библиотека для комфортной работы с json на Haxe независимо от таргета.
haxelib install tjson
Не забываем подключить библиотеку в проект:
<haxelib name="tjson" />
Теперь нам понадобится класс EXTJsonSerialization.hx – качаем по ссылке и добавляем в проект. (спасибо доброму человеку написавшему его)
Ну вот теперь берем наши “сложные” классы и проверяем, как это работает.
var level = new Level(); level.rocks = new Array<Rock>(); var rock = new Rock(); rock.x = 1; rock.y = 10; rock.text = "Go to left"; level.rocks.push(rock); rock = new Rock(); rock.x = 90; rock.y = 400; rock.text = "Go to right"; level.rocks.push(rock); // Собственно encode класса Level в json: trace(EXTJsonSerialization.encode(level, Level));
Получаем вот такой json:
{ "id" : 0 ,"_explicitType" : "examples.Level" ,"rocks" : [ { "_explicitType" : "examples.Rock" ,"y" : 10 ,"x" : 1 ,"text" : "Go to left" } ,{ "_explicitType" : "examples.Rock" ,"y" : 400 ,"x" : 90 ,"text" : "Go to right" } ] }
Обратите внимание на поле “_explicitType” – оно расставляется в каждом объекте и указывает на его тип, чтобы у нас не возникло проблем при парсинге. Таким образом, иерархия наших классов с данными может быть практически любой.
Обратная магия работает одной строкой:
var lvl:Level = EXTJsonSerialization.decode(text, Level);
В итоге, в переменной lvl мы имеем нашу иерархию классов без dynamic’ов и безликих object’ов .
Остается только дописать сохранение файлов, но это уже в другой раз, если кому-то интересно.