Зачем я это прочитал?..
Грубо говоря, веб без JS не кому не нужен. Если кому-то не нравиться, пусть просто не пользуется вебом. JS в браузере работает в режиме sandbox, установить ПО в таком режиме не получится. Не понял что такое «несвободное ПО» если сайт в открытом доступе — заходи кто хочет.
На мой взгляд, говоря о реалистичности видео на разных частотах, не нужно скатываться в дискретный способ мышления и говорить только об fps. Дискретные эффекты покадровой съемки (особенно с малой выдержкой) дают причудливые стробоскопические эффекты на вращающихся колесах, лопастях, спицах и т.д. А недавно в инете ходило видео с камеры наблюдения где какая-то птичка летала не поднимая крыльев. Я бы сказал что нужно рассуждать в интегральных терминах. Рецепторы в глазу человека имеют определенную инертность (как на зажигание так и гашение сигнала), поэтому быстро двигающийся объект (например летающий на темном фоне белый кружок) будет восприниматься размазанным пятном. Длинна этого пятна будет зависеть от таких параметров как скорость движения, условия освещенности и т.д. Так вот, на видео длинна этого пятна не должна зависеть от fps. Образно говоря, на высоких fps может потребоваться длина выдержки больше чем 1/fps. Иначе начнутся стробоскопические эффекты, которые придется трактовать как «художественный замысел режисера». Но это не тоже самое что реализм…
Мне нужно в структуре файла иметь описание всех используемых структур c полями (имена и типы) в строковом виде. Хорошо бы по аннотациям вытягивать доп инфу (например, toltip info).
Да, но мне нужно в структуре файла иметь имя и тип в строковом виде, поскольку там сначала описание структуры а потом данные. Иначе редактор не сможет понять что куда можно добавить (sub-objects, array itmes). Плюс в файлах не нужны версии, при десериализации лишние поля игнорируются, а недостающие остаются default initialized.
Ай, поторопился, извините. Не та функция. Давайте попробуем еще раз с пояснениями. Класс для сериализации:
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 должна инстанциироваться не так явно, а через тип. Надеюсь так чуть понятнее.
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»). Некоторые вещи пишутся громоздко.
Когда 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)
Грубо говоря, веб без JS не кому не нужен. Если кому-то не нравиться, пусть просто не пользуется вебом. JS в браузере работает в режиме sandbox, установить ПО в таком режиме не получится. Не понял что такое «несвободное ПО» если сайт в открытом доступе — заходи кто хочет.
Сериалайзер обнюхивает этот класс примерно так:
Здесь просто печатается имя и значение полей заданных для сериализации, но в реальной жизни парсер генерирует вспомогательные данные (HashMap с именами) для ускорения процессов save/load из промежуточного представления сериализуемых данных, кеширауя их в статическое поле slzr. Ну и вспомогательная переменная t должна инстанциироваться не так явно, а через тип. Надеюсь так чуть понятнее.
Классический «for(;;)» убит (лучше бы убили «while» и «do/while»). Некоторые вещи пишутся громоздко.
Для HelloWorld работает хорошо. В прод не катит.
В какой то момент начались таргетинги на разные платформы: 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, то начинаются печали…