Добавлен , опубликован
Здравствуй, XGM.
Недавно я столкнулся с рядом проблем в сериализации Unity, которые свели на ноль возможность построить определенную архитектуру. При том ранее такая архитектура была возможна - мне всего-то навсего нужно было построить "дерево" из классов.
Вкупе с тем, что стандартная сериализация уже несколько раз серьезно давала мне пощечину в реализации редакторов - это привело меня к тому, чтобы попробовать написать собственный "альтернативный" вариант сериализации. Чудесным код я не назову - я не протестировал его должным образом, да и не шибко он вышел красивым.
Но кое-какого результата добиться я смог, и этот результат удовлетворяет моим потребностям. Я решил не забивать на это дело и в дальнейшем расширять возможности данного скрипта, улучшать и дорабатывать его, потому что он действительно может помочь решить многие архитектурные проблемы.
Я положил свою наработку на недавно заведенный мной git-hub. Так же я решил задействовать вики-раздел, который помог бы понять как с этим работать.
На момент написания данной новости я смог добиться определенного результата в наработке, однако планирую потратить еще как минимум ночь на ее расширение и упрощение, прежде чем продолжу заниматься своими делами.
Основные преимущества перед сериализацией Unity:
  • Возможность создавать собственные правила для сериализации уже существующих классов.
  • Решение проблем сохранения ссылочности в композитных типах
  • Возможность сохранить данные любого типа - Generic-классы, интерфейсы, object и т.д.
  • Массивы не режутся
  • Поддержка прямоугольных и зубчатых массивов
Однако на текущий момент есть и существенные минусы:
  • Чувствительность к изменениям
  • Необходимость сериализации данных вручную через специальный объект-капсулу
  • Одни и те же экземпляры в разных капсулах после ребилда дают разные экземпляры
  • Скрипт еще слишком сырой
Но тем не менее - скрипт уже способен выполнять свою функцию и с ним можно работать.
В общем, пользуйтесь.
0
29
8 лет назад
0
что-то я разочаровался в гитхабе, я ожидал увидеть там возможность оставлять комменты.
А теперь по коду:
  • Расстроился из-за того, что нет комментариев
  • Расстроился из-за большого количества switch/case конструкций
  • ByteConstants не отображает суть( Это же на самом деле ObjectTypes
  • При использовании рефлексии советую использовать кэширование, потому что доступ через рефлексию довольно медленный
0
27
8 лет назад
Отредактирован Devion
0
ByteConstants не отображает суть( Это же на самом деле ObjectTypes
Я планировал туда вообще закидывать константы. Но да, по сути смысл иной, переименую.
alexprey:
Расстроился из-за большого количества switch/case конструкций
Меня это тоже очень огорчает, но не придумал, чем это заменить. Думаешь вызов данных из скажем хеш таблицы будет быстрее?
Была мысль задействовать функторы в массивах, но они точно медленней.
Проверил, да, хештаблицы+функторы медленнее. Мой ход мыслей таков, что это все равно относится к кишкам, в которые лезть не придется. Там все эти классы лежат в internal'e, с ними работать не нужно напрямую. Потому в принципе я так или иначе должен выбирать наоборот то решение которое быстрее, даже если быстрее свитч кейс. Хотя согласен, что перебор лучше делать реже.
За комментарии и кеширование - это временно. Пока слишком часто все переделываю
0
29
8 лет назад
0
Меня это тоже очень огорчает, но не придумал, чем это заменить. Думаешь вызов данных из скажем хеш таблицы будет быстрее?
одинаково, но коду придаст гибкости и расширяемости
2
27
8 лет назад
Отредактирован Devion
2
одинаково, но коду придаст гибкости и расширяемости
Я заапдейтил предыдущий пост. Результат оказался в три раза медленнее.
По сути эти переборы можно вообще убрать, сделать один перебор на объект. Но в этом случае функции считывания/записи станут еще уродливей, будет одно длинное такое спагетти.
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: При большом количестве объектов и определенных связях сейчас переполняется стек, потому надо переписать ссылочность. Но это уже завтра.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.