Обновить
3
0.1

Пользователь

Отправить сообщение
На мой взгляд, говоря о реалистичности видео на разных частотах, не нужно скатываться в дискретный способ мышления и говорить только об fps. Дискретные эффекты покадровой съемки (особенно с малой выдержкой) дают причудливые стробоскопические эффекты на вращающихся колесах, лопастях, спицах и т.д. А недавно в инете ходило видео с камеры наблюдения где какая-то птичка летала не поднимая крыльев. Я бы сказал что нужно рассуждать в интегральных терминах. Рецепторы в глазу человека имеют определенную инертность (как на зажигание так и гашение сигнала), поэтому быстро двигающийся объект (например летающий на темном фоне белый кружок) будет восприниматься размазанным пятном. Длинна этого пятна будет зависеть от таких параметров как скорость движения, условия освещенности и т.д. Так вот, на видео длинна этого пятна не должна зависеть от fps. Образно говоря, на высоких fps может потребоваться длина выдержки больше чем 1/fps. Иначе начнутся стробоскопические эффекты, которые придется трактовать как «художественный замысел режисера». Но это не тоже самое что реализм…
Мне нужно в структуре файла иметь описание всех используемых структур c полями (имена и типы) в строковом виде. Хорошо бы по аннотациям вытягивать доп инфу (например, toltip info).
Есть ожидания, а есть реальность. Я просто оставлю это здесь js vs webasm
Не зажимают, а расширяют. Правда производительность WebAsm пока под вопросом. Плюс пока еще частое обращение к JS API…
Да, но мне нужно в структуре файла иметь имя и тип в строковом виде, поскольку там сначала описание структуры а потом данные. Иначе редактор не сможет понять что куда можно добавить (sub-objects, array itmes). Плюс в файлах не нужны версии, при десериализации лишние поля игнорируются, а недостающие остаются default initialized.
Переменная obj это пример инстанциирования. Ну и target js, т.е. RTTI урезан.
Ай, поторопился, извините. Не та функция. Давайте попробуем еще раз с пояснениями. Класс для сериализации:
interface Slzr {
    fun get_Slzr_Decl() : Array<Any?>
}
class MyClass : Slzr {
    companion object static {
        val slzr : Array<Any?> = arrayOf<Any?>(::MyClass, MyClass::class.simpleName, 7, arrayOf<Any>(MyClass::br, MyClass::fr))
    }
    var br = 777;
    var fr = "rrrr";
    override fun get_Slzr_Decl() : Array<Any?> = slzr;
}

Сериалайзер обнюхивает этот класс примерно так:
    var t : MyClass = MyClass()
    var sd = t.get_Slzr_Decl();
    @Suppress("UNCHECKED_CAST")
    var obj = (sd[0] as KFunction0<Any>)();
    var a : Array<*>? = sd[3] as? Array<*>;
    if(null!=a) {
        for(i in a.indices) {
            if(a[i] is KMutableProperty1<*,*>) {
                @Suppress("UNCHECKED_CAST")
                var pi = a[i] as? KMutableProperty1<Any, *>;
                if(null!=pi)
                    println("member: " + pi.name + " = " + pi.get(t as Any));
            }
        }
    }

Здесь просто печатается имя и значение полей заданных для сериализации, но в реальной жизни парсер генерирует вспомогательные данные (HashMap с именами) для ускорения процессов save/load из промежуточного представления сериализуемых данных, кеширауя их в статическое поле slzr. Ну и вспомогательная переменная t должна инстанциироваться не так явно, а через тип. Надеюсь так чуть понятнее.
Это не issue, а скорее crutch:
class MyClass : Slzr
{
    companion object static
    {
        val slzr : Array<Any?> = arrayOf<Any?>(::MyClass, MyClass::class.simpleName, 7, arrayOf<Any>(MyClass::br, MyClass::fr))
    }
    var br = 777;
    var fr = "rrrr";
    override fun get_Slzr_Decl() : Array<Any?> = slzr;
    fun reg_internal(vararg p: Any)
    {
        // for(i in p.indices)
        for(i in 0 until p.size)
        {
            if(p[i] is KMutableProperty0<*>)
            {
                var pi = p[i] as KMutableProperty0<*>;
                // var v = pi.get();
                if(pi.get() is Int)
                {
                    @Suppress("UNCHECKED_CAST")
                    pi = p[i] as KMutableProperty0<Int>;
                    pi.set(111);
                    // v = pi.get();
                    print("Int:\t");
                }
                else
                if(pi.get() is String)
                    print("String:\t");
                println("p[" + i + "] = " + pi.name + " -->" + pi.get());
            }
            else println("p[" + i + "]")
        }
    }
А что бы на Kotlin сериализовать без рефлексии, надо сначала все переложить в промежуточную структуру, а это дополнительный код с возможными опечатками. Ну там еще есть вариант с инстанциированием воспомогательного объекта и использованием массива вида [MyClass::field_a, MyClass::field_b...], что тоже не фонтан…
Use-case такой: сериализация идет в строго типизированную структуру данных, которую потом можно редактировать своим универсальным редактором (что-то вроде иерархического object-inspector). Формат может быть любой, (например JSON или бинарный). Сначала идет описание структуры (с возможностью пропускать), потом данные. К объектам это применяется (читается и пишется) через промежуточное представление, ориентируясь на имя и тип поля. Это позволяет гибко добавлять/удалять поля класса во время разработки (за номерами версий в файле следить не нужно). Чуть не забыл, в классе поля для сериализации нужны далеко не все.
Прошу НЛО удалить мой комментарий, а то фанаты заминусовали (да и статья, действительно, не про это).
Потыкав палочкой в Kotlin я увидел недоделанный долгострой. Первое что обнаружил: кросс-платформенный Reflect API отсутствует, хотя который год обещают.

Классический «for(;;)» убит (лучше бы убили «while» и «do/while»). Некоторые вещи пишутся громоздко.

Для HelloWorld работает хорошо. В прод не катит.
Когда 8 лет назад kotlin появился, он был похож на еще один backend для JVM. Синтаксис и грамматика со своими причудами и ключевыми словами (it, reified и т.п.), местами на пару букв короче чем в Java, местами длиннее. Странные решения, вроде отмены традиционного синтаксиса for(;;). По своему опыту могу сказать что циклы while и do{}while обычно вообще не используются, так как for(;;) самодостаточен. Вместо static members в kotlin классы двух видов: только static (это называется Object) и только не-static. Если в классе нужно и то и другое, встраиваем один класс в другой как companion (ему еще можно задавать имя, случайно не знаете зачем?). Если статический member один, то конструкция выгляди пухловато. Объявление объектов с динамическими полями в стиле JSON выглядит пухловато, в перемешку со строковыми «mutableListOf» и «mutableMapOf». Ну да на самом деле все это мелочи…

В какой то момент начались таргетинги на разные платформы: JVM, JS, LLVM. Появился соблазн иметь общую кодовую базу, но… Java, JS, C# по отдельности имеют не плохой RTTI (run-time type information), это позволяет писать свои сериализаторы и прочие reflect полезные штуки. В kotlin уже который год видим ошибки вида: «error: unsupported [This reflection API is not supported yet in JavaScript]».

Я понимаю что не всем это надо, но если проект чуть сложнее чем HelloWorld, то начинаются печали…
Так то, да. Язык не предназначен для исполнения в JS среде. Но раз уж речь зашло про wasm, то просто стало интересно чем wasm лучше js. Компилятор go2js гуглится (правда не официальный AFAIU)
И во сколько раз wasm будет быстрее чем js?
Да, только не раз в минуту, а по условию что «убежало» больше чем на 1-2 кадра
При выключении костыля синхронизация восстанавливается, для этого и проверяется условие.

Информация

В рейтинге
4 516-й
Зарегистрирован
Активность