Комментарии 55
В JSON даже комментарии нельзя вставлять, не говоря уже о схемах и прочем.
Для передачи данных да, он компактнее и, может, более читаем. Но для разметки, конфигов я предпочту XML.
У JSON в плане использования как языка разметки есть фатальные недостатки — неименованые типы объектов и отсутствие встроенных текстовых нод. Из-за этого при определении списка элементов приходится писать что-то типа
{
"@type": "StackPanel",
"children": [
{
"@type": "TextBlock",
"text": "Hello world"
},
{
"@type": "Button",
"text": "Click me"
}
]
}
вместо
<StackPanel>
<TextBlock>Hello world</TextBlock>
<Button Text="Click me"/>
</StackPanel>
В QML это будет
ColumnLayout {
Text {
text: qsTr("Hello world")
}
Button {
text: qsTr("Click me")
}
}
Единственный косяк QML — возможность писать код прямо в разметке — так и поощряет быдлокодить и приходится каждый раз себя бить по рукам для разделения вида контролов и их логики
QML позволяет быдлокодить примерно так:
Button {
property int times = 0
text: qsTr("Clicked %1 times").arg(times)
onClicked: times++
}
Что в XAML получится кудааа длиннее. Но в то же время WPF заставит сделать аккуратно, а QML на все это пофиг. Поэтому от мало-мальски сложного проекта на QtQuick начинают течь слезы, если только разработчик не заставил себя следовать какой-нибудь методологии (вроде Flux)
<Button Click="Onclick" Content="{x:Bind GetClickCount()}"/>
А логику уже в codebehind, если это логика UI. Ну или во вьюмодель если бизнес.
Кстати, в андроидовском axml можно тоже в биндингах делать некую логику. Отличная замена конвертерам.
Но вот полностью функции писать в верстке. Сомнительное это преимущество.
Поэтому от мало-мальски сложного проекта на QtQuick начинают течь слезы, если только разработчик не заставил себя следовать какой-нибудь методологии
QML — это всего лишь GUI, и javascript там нужен для реализации логики GUI. Бизнес-логика должна реализовываться отдельно. Имо если в проекте много говнокода, слезы потекут независимо от того, на чем он написан
Тут на самом деле есть один тонкий момент — никто не запрещает написать так:
{
"StackPanel":
{
"TextBlock": "Hello world",
"Button":
{
"Text": "Click me"
}
}
}
но тут встает вопрос с повторением свойств, например:
{
"StackPanel":
{
"TextBlock": "Hello world",
"Button":
{
"Text": "Click me"
},
"Button":
{
"Text": "And me!"
}
}
}
Парсеры, тот же JSON.parse, при повторении свойства вернет значение именно последнего свойства (работает аналогично инициализации объекта), а вот при потоковом парсинге (например с помощью JsonTextReader из Json.NET) мы увидим все свойства, даже повторяющиеся и можем их корректно обработать. Но это очень холиварный момент. Очень.
Потом я уже столкнулся с plist. Когда xml используется по json-идеалогии. тогда его из-за излишней многословности читать действительно сложнее.
Воспользуюсь примером kekekeks:
Если сравнивать такой json:
{
"@type": "StackPanel",
"children": [
{
"@type": "TextBlock",
"text": "Hello world"
},
{
"@type": "Button",
"text": "Click me"
}
]
}
И XML написанный в том же стиле (примерно как plist):
<panel>
<type>StackPanel</type>
<children>
<control>
<type>TextBlock</type>
<text>Hello world</text>
</control>
<control>
<type>Button</type>
<text>Click me</text>
</control>
</children>
</panel>
То, конечно, json выигрывает. Но нормальный XML намного удобнее:
<StackPanel>
<TextBlock>Hello world</TextBlock>
<Button Text="Click me"/>
</StackPanel>
Тут тег однозначно сопоставляется с экземпляром объекта, свойства объекта с атрибутами. Иерархия тоже легче читается.
Вот кое-что есть на хабре: https://habrahabr.ru/post/328684/
Вы точно понимаете, как работает P/Invoke? Вы точно понимаете, как именно работает электрон и почему именно он тормозит?
Но специально я не сравнивал — любопытствую. Демка из статьи выше у меня запустилась сильно медленнее, чем стартует Visual Studio Code. Да, воторой запуск такой же медленный, как первый :)
потому что строка в .net и null-terminated UCS-2 в WinAPI — это разные штуки
На самом деле нет, дотнетные строки нуль-терминированы, вы можете взять указатель и передать как есть. Да, в ряде случаев маршалинг нужен, но это контролируемый процесс. Так, всё взаимодействие с DirectX у нас идёт через msil-инструкцию calli, которая выполняет прямой вызов по указателю без автоматических преобразований.
Демка из статьи выше у меня запустилась сильно медленнее, чем стартует Visual Studio Code
А вы её запускали через dotnet run
? Он каждый раз дёргает MSBuild и кучу ненужностей, чтобы определить, надо ли пересобрать проект (и обычно пересобирает даже тогда, когда не надо). Процесс этот не быстрый. Сделайте dotnet publish
под нужную платформу и уже собранный релизный вариант запустите.
msil-инструкцию calli, которая выполняет прямой вызов по указателю без автоматических преобразований
Интересно, а где можно на это посмотреть?
См. SharpGenTools, которым обрабатывается используемый нами SharpDX в процессе сборки. Мы себя отдельно SharpGenTools используем в AvalonStudio для генерации кода интеропа с libdbgshim/ICorDebug для отладки кода под .NET Core.
"Неторопливая" — очень относительное понятие. Да, PInvoke медленный по сравнению с прямым вызовом функции, он добавляет от 10 до 30 инструкций (см MSDN). Но надо понимать, что эта разница — порядка наносекунд, и в случае вызова функций сложнее a+b
просто теряется. Например, Ignite.NET работает с JVM через PInvoke, и тормозов от этого не испытывает.
Electron:
- тащит за собой целый браузер, жрёт немеряно памяти и создаёт новый процесс на каждый чих
- C# быстрее JavaScript и лучше во всех отношениях
- XAML лучше HTML
Другое дело, что layout & rendering в Electron действительно может быть быстрее для некоторых сценариев, браузерный движок очень круто заоптимизирован под это дело.
Спасибо за настроение и за код!!
Спасибо за статью и рекламу Avalonia! Очень нравится концепция, надеюсь выстрелит.
Классический эффект ранних интро.
Единственное — в этом эффекте у снежинок обычно добавляли небольшие флуктуации по горизонтали — как это и выглядит в натуре, если нет ветра.
Добавил эту фичу и сделал pull-request: https://github.com/ptupitsyn/let-it-snow/pull/1/commits
- Java
- Kotlin
- WebAssembly? O_o
Нет. Вместо него поверх CoreCLR работает UWP. Который нигде кроме Windows 10 работать не планирует.
Где? В .NET Core? Или поддержка вайном UWP? Первое технически слабореализуемо (Mono уже пытались когда-то давно реализовать поддержку WinForms поверх вайна, получилось плохо), во второе слабо верится, ввиду общей непопулярности UWP как платформы.
Они его продвигать могут сколько угодно, но разработчиков под UWP от этого не прибавится. По фичам он проигрывает WPF всухую, а единственную платформу, ради которой это дело хоть кто-то использовал, благополучно похоронили.
Под win S запускаются только приложения рз маркета.
Через Desktop Bridge на этой Win S хоть Windows Forms можно запустить.
По фичам он проигрывает WPF всухую
Ну нет же (в смысле не всухую). Все новые фичи API делаются в WinRT и в WPF доступны только через костыли в виде Desctop Bridge.
Те фичи, что не поддерживаются в WinRT либо в планах, либо под вопросом существования (как например трей).
Grid.SharedSizeGroup
завезли уже? А свои MarkupExtension уже можно делать? Уже сколько лет технологии, а даже таких базовых вещей нет.
А WinRT-only-фичи — это какое-нибудь живое обновление плиток, которое нужно мессенджерам и приложениям по доставке пиццы.
Если передергивать, то кому нужны все эти Grid.SharedSizeGroup и MarkupExtension?
В WPF завезли нормальную поддержку DPI и UI Адаптивный под разные инструменты ввода? Даже таких базовых вещей нет.
А WinRT-only-фичи, кроме вами озвученных — пуш уведомления, поддержка экстеншенов из коробки, нормальная поддержка HDPI, SvgImageSource, Composition API, поддержка windows timeline из коробки, пакетная упаковка приложений (аля мак ос).
кому нужны все эти Grid.SharedSizeGroup и MarkupExtension
Нужны при разработке чего-то более сложного, чем приложение для доставки пиццы. Свои markup extensions даже в Xamarin.Forms есть.
В WPF завезли нормальную поддержку DPI и UI Адаптивный под разные инструменты ввода
DPI всегда вполне вменяемо поддерживался. В 4.6.2 прикрутили поддержку per-monitor DPI. С DPI проблемы были не в WPF, а в винформах, ибо винформы базируются на технологиях из 90-х
пуш уведомления
пакетная упаковка приложений (аля мак ос).
Делается через desktop bridge, к технологии отображения окон на экран отношения не имеет.
Ок, продолжу ваше ребячество:
Ничего сложнее «приложения по доставке пиццы» нельзя написать не используя RelativePanel, AdaptiveTrigger и условного XAML (последний «даже в Xamarin.Forms есть» в каком-то виде).
В 4.6.2 прикрутили поддержку per-monitor DPI.Ага бекпортировали из UWP в технологии 00-х.
Делается через desktop bridge
Как я выше и писал, через костыли в виде Desktop to UWP Bridge. Тогда только Классическим (аккуратное слово, означающее то же, что и легаси в общем-то) приложениям разрешают доступ до современного WinRT API.
AdaptiveTrigger реализуется средствами WPF посредством биндинга к ActualWidth и конвертера. RelativePanel при желании можно реализовать самостоятельно, более-менее работающая есть на гитхабе.
Условный XAML делается на уровне своего markup extension (как это сделано в Xamarin.Forms)
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS"
xmlns:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
xmlns:formsAndroid="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.Platform.Android;targetPlatform=Android"
xmlns:win="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Version=255.255.255.255,
Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"
x:Class="NativeViews.NativeViewDemo">
<StackLayout Margin="20">
<ios:UILabel Text="Hello World" TextColor="{x:Static ios:UIColor.Red}" View.HorizontalOptions="Start" />
<androidWidget:TextView Text="Hello World" x:Arguments="{x:Static formsandroid:Forms.Context}" />
<win:TextBlock Text="Hello World" />
</StackLayout>
</ContentPage>
А расскажите что мешает например сделать биндинги к Qt(зачем ещё одна графическая либа)? Известный фреймворк, сделан профессионально, из коробки до кучи фич от лайв редактирования до трансляции в браузер. Кастомизируется по самое нехочу. Отличная лицензия. Из недостатков только что веб в один клик не запилить(хотя зная современный веб это можно считать плюсом) и что заставляет под себя подстраиваться (хотелось бы более универсальное как стандартная библиотеки, чтобы не тянуть зависимости ядра, а сразу заюзал функционал в любой проект без остального qt).
Здорово! Приятно видеть, что UI dotNet с XAML можно запускать на этих платформах.
Расширение Avalonia для студии содержит XAML Designer, но у меня он не заработал.
Previewer can currently run only on Desktop .NET Framework. That's the main reason why net461 is included to TargetFrameworks list in our .NET Core app template. That's it, for now you have to use multitargeting (hint: you can have everything targeting netstandard, it's only final executable that needs to target .NET 4.6+.
Кроссплатформенная новогодняя демка на .NET Core и Avalonia