Добавлен , опубликован
Здравствуй, XGM.
Недавно я столкнулся с рядом проблем в сериализации Unity, которые свели на ноль возможность построить определенную архитектуру. При том ранее такая архитектура была возможна - мне всего-то навсего нужно было построить "дерево" из классов.
Вкупе с тем, что стандартная сериализация уже несколько раз серьезно давала мне пощечину в реализации редакторов - это привело меня к тому, чтобы попробовать написать собственный "альтернативный" вариант сериализации. Чудесным код я не назову - я не протестировал его должным образом, да и не шибко он вышел красивым.
Но кое-какого результата добиться я смог, и этот результат удовлетворяет моим потребностям. Я решил не забивать на это дело и в дальнейшем расширять возможности данного скрипта, улучшать и дорабатывать его, потому что он действительно может помочь решить многие архитектурные проблемы.
Я положил свою наработку на недавно заведенный мной git-hub. Так же я решил задействовать вики-раздел, который помог бы понять как с этим работать.
На момент написания данной новости я смог добиться определенного результата в наработке, однако планирую потратить еще как минимум ночь на ее расширение и упрощение, прежде чем продолжу заниматься своими делами.
Основные преимущества перед сериализацией Unity:
  • Возможность создавать собственные правила для сериализации уже существующих классов.
  • Решение проблем сохранения ссылочности в композитных типах
  • Возможность сохранить данные любого типа - Generic-классы, интерфейсы, object и т.д.
  • Массивы не режутся
  • Поддержка прямоугольных и зубчатых массивов
Однако на текущий момент есть и существенные минусы:
  • Чувствительность к изменениям
  • Необходимость сериализации данных вручную через специальный объект-капсулу
  • Одни и те же экземпляры в разных капсулах после ребилда дают разные экземпляры
  • Скрипт еще слишком сырой
Но тем не менее - скрипт уже способен выполнять свою функцию и с ним можно работать.
В общем, пользуйтесь.
`
ОЖИДАНИЕ РЕКЛАМЫ...
29
что-то я разочаровался в гитхабе, я ожидал увидеть там возможность оставлять комменты.
А теперь по коду:
  • Расстроился из-за того, что нет комментариев
  • Расстроился из-за большого количества switch/case конструкций
  • ByteConstants не отображает суть( Это же на самом деле ObjectTypes
  • При использовании рефлексии советую использовать кэширование, потому что доступ через рефлексию довольно медленный
27
ByteConstants не отображает суть( Это же на самом деле ObjectTypes
Я планировал туда вообще закидывать константы. Но да, по сути смысл иной, переименую.
alexprey:
Расстроился из-за большого количества switch/case конструкций
Меня это тоже очень огорчает, но не придумал, чем это заменить. Думаешь вызов данных из скажем хеш таблицы будет быстрее?
Была мысль задействовать функторы в массивах, но они точно медленней.
Проверил, да, хештаблицы+функторы медленнее. Мой ход мыслей таков, что это все равно относится к кишкам, в которые лезть не придется. Там все эти классы лежат в internal'e, с ними работать не нужно напрямую. Потому в принципе я так или иначе должен выбирать наоборот то решение которое быстрее, даже если быстрее свитч кейс. Хотя согласен, что перебор лучше делать реже.
За комментарии и кеширование - это временно. Пока слишком часто все переделываю
29
Меня это тоже очень огорчает, но не придумал, чем это заменить. Думаешь вызов данных из скажем хеш таблицы будет быстрее?
одинаково, но коду придаст гибкости и расширяемости
27
одинаково, но коду придаст гибкости и расширяемости
Я заапдейтил предыдущий пост. Результат оказался в три раза медленнее.
По сути эти переборы можно вообще убрать, сделать один перебор на объект. Но в этом случае функции считывания/записи станут еще уродливей, будет одно длинное такое спагетти.
UPD:
В общем. Нашел мыслю как сделать только по одному перебору за объект. Меньше никак, но там можно грамотно их расфасовать, закидывая то, что реже используется на дальние проверки. В результате будет разделенная логика в отдельных файлах, каждый из которых создается лишь один раз, что еще один плюс.
Как доделаю, накину обновление.
UPD:
Залил изменения.
  • Теперь каждый случай обособлен в отдельный класс, благодаря чему убралось несколько свитч-кейсов
  • Остался перебор, отвечающий за перевод в константу. Там пусть лучше так и будет
  • Немного комментов
  • Переиначил ByteConstants в ObjectTypes
  • Добавил кеширование полей в классах и структурах
UPD:
чё т долговато выходит. Попробовал на реальных операциях. один объект жует несколько секунд. Думаю дело в расширении массива, в общем будем разбираться.
UPD: да, дело таки в расширении массива, без этого все летает. Надо обдумывать как сделать так, чтобы объект перерасчитывался пореже
UPD:
Исправил. Теперь массив с байтами умножается на два, когда заканчивается, а уже после всего ресайзится до короткого.
UPD:
Добавил параметр capacity к ByteObject, чтобы можно было предсказывать начальный размер массива. По умолчанию он равен 16, не может быть меньше 8 (хотя размер массива - может быть, так то), и автоматически изменяется при изменении массива (ну чтобы две записи подряд не нагружали шибко).
Вот такого кода хватает для хранения дерева в окне:
    [MenuItem("Window/Test")]
    public static void Open()
    {
        var w = GetWindow<TestWindow>();
        w.tree = CreateTree();
    } 

    public void OnEnable() 
    {
        tree = treeSaver.Get<TreeView>();
    }

    public void OnDisable()   
    {
        treeSaver.Set(tree);
    }

    public TreeView tree;
    public ByteObject treeSaver = new ByteObject();
UPD: При большом количестве объектов и определенных связях сейчас переполняется стек, потому надо переписать ссылочность. Но это уже завтра.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.