Maui: [Спецификация] Архитектура Slim Renderer

Созданный на 19 мая 2020  ·  56Комментарии  ·  Источник: dotnet/maui

ВНИМАНИЕ: эта спецификация все еще WIP, мы все еще экспериментируем с этой концепцией.

Описание

Архитектура тонких модулей рендеринга выигрывает от функций одновременного нацеливания и работы с одним проектом.

Пример

EntryRenderer.cs

public partial class EntryRenderer {
   public static PropertyMapper<IView> ViewMapper = new PropertyMapper<IView> {

     // Add your own method to map to any property         
     [nameof(IView.BackgroundColor)] = MapBackgroundColor

   };
}

EntryRenderer.iOS.cs

// You don’t need to register a new renderer.
public partial class EntryRenderer
{
     // You know what method to call because you named it!
   public static void MapBackgroundColor (IViewRenderer renderer, IView view)
     {
        // You don’t need to call any base methods here or worry about order.

        // Every renderer is consistent; you know where the native view is.
          var nativeView = (NativeView)renderer.NativeView;
          var color = view.BackgroundColor;

          if (color != null) {

            // Phew! That was easy!         
            nativeView.BackgroundColor = UIColor.FromRGB (204, 153, 255);
          }
     }
}

Стандартизация рендереров

Все рендеры по умолчанию будут перенесены на эту архитектуру для всех платформ.

Регистрация рендеров

RendererRegistrar будет существовать в службе зависимостей, и к нему будет обращаться serviceCollection.Get<IRendererRegistrar>() , что позволяет контролировать, какой рендерер связан с каким элементом управления.

Интерфейсы на рендерерах

Концепция картографа

Сопоставитель свойств отвечает за запуск действий при изменении свойств ответа. Сам тонкий рендерер не подписывается на изменения свойств, но некоторые объявленные действия выполняются в ответ на изменения.

Свойство сопоставления свойств элемента управления - public static и может быть расширено пользовательским кодом.

Сопоставитель свойств не играет роли в цикле обратной связи (нажата кнопка, введен текст)

ЗАДАЧИ: обсудите, что использовать для ключа сопоставления. string или object ? Было бы неплохо избежать сравнения строк в случае, когда мы можем сравнивать ссылки (в случае BindableProperties)

Как использовать устаревшие пользовательские рендереры

Как использовать сторонние элементы управления в зависимости от старых рендереров

Как дополнить существующие рендеры

Новая модель расширяемости для этой архитектуры основана на сопоставлении свойств. Если вы хотите добавить поддержку нового свойства, требуется только сопоставление нового свойства. Чтобы свойство существовало, необходимо создание подкласса элемента управления, а создание подкласса средства визуализации - нет.

Обратная совместимость

Мы хотим сохранить обратную совместимость с существующими пользовательскими модулями визуализации, иначе подклассы старых модулей визуализации будут влиять на архитектуру этого модуля.

Сложность: очень высокая

proposal-open slim renderer

Самый полезный комментарий

Пожалуйста, не пытайтесь сохранить обратную совместимость любой ценой. Это что-то новенькое. Он не обязательно должен быть совместим с XF. Вы можете сделать что-нибудь лучше.

Все 56 Комментарий

Xamarin формирует рендереры wpf, а некоторые из рендереров Android, такие как ButtonRenderer, работают быстро, и мы знаем, что здесь означает «быстро».
Будут ли эти рендеры быстрыми или нет?
Заранее спасибо.

@ysmoradi Ага! Эти новые средства визуализации будут следовать шаблону быстрого средства визуализации (т. Е. Без представления оболочки вокруг основного представления). Мы планируем сделать это для всех платформ, а не только для Android и WPF.

Пожалуйста, не пытайтесь сохранить обратную совместимость любой ценой. Это что-то новенькое. Он не обязательно должен быть совместим с XF. Вы можете сделать что-нибудь лучше.

Почему бы не создать платформу пользовательского интерфейса с собственным набором элементов управления без каких-либо сопоставлений и поведенческой логики, полностью написанной на C #, которая будет отображаться с помощью графической библиотеки Skia? Поскольку люди используют строго индивидуальный дизайн, нет необходимости пытаться соответствовать руководящим принципам разработки платформы. Единственное, что нужно - это возможность гибкой настройки. Пожалуйста, поправьте меня, если я чего-то упускаю, но я не понимаю, почему преимущество перед архитектурой Renderer.

Можно ли при таком подходе написать кроссплатформенный рендерер вместо рендерера, зависящего от платформы? Как отображение кнопок управления с четким управлением.

Платформенный рендерер - плохой дизайн. Как видите, существует множество управляющих библиотек xamarin, которые не поддерживают UWP из-за ограничений платформы.
Возьмем, к примеру, тень в UWP. Вы не можете получить угловую тень от угловой кнопки (конечно, вы можете изменить шаблон кнопки для этого, но это другое дело).

Я знаю, что создать кроссплатформенный рендер очень сложно. Но флаттер сказал нам, что это возможно. В долгосрочной перспективе лучшим решением будет кроссплатформенный рендерер.

Я думаю, что рендеринг всего приложения в виде настраиваемого 2D-холста может без проблем работать с мобильным приложением.

Но это может не работать для настольного приложения или сложного приложения, потому что существует так много действий пользователя, которые необходимо повторно реализовать, например, перетаскивание, выделение текста, сочетание клавиш для управления текстом и т. Д.

Почему бы не создать платформу пользовательского интерфейса с собственным набором элементов управления без каких-либо сопоставлений и поведенческой логики, полностью написанной на C #, которая будет отображаться с помощью графической библиотеки Skia? Поскольку люди используют строго индивидуальный дизайн, нет необходимости пытаться соответствовать руководящим принципам разработки платформы. Единственное, что нужно - это возможность гибкой настройки. Пожалуйста, поправьте меня, если я чего-то упускаю, но я не понимаю, почему преимущество перед архитектурой Renderer.

Я думаю, что рендеринг всего приложения в виде настраиваемого 2D-холста может без проблем работать с мобильным приложением.

Но это может не работать для настольного приложения или сложного приложения, потому что существует так много действий пользователя, которые необходимо повторно реализовать, например, перетаскивание, выделение текста, сочетание клавиш для управления текстом и т. Д.

Почему бы не создать платформу пользовательского интерфейса с собственным набором элементов управления без каких-либо сопоставлений и поведенческой логики, полностью написанной на C #, которая будет отображаться с помощью графической библиотеки Skia? Поскольку люди используют строго индивидуальный дизайн, нет необходимости пытаться соответствовать руководящим принципам разработки платформы. Единственное, что нужно - это возможность гибкой настройки. Пожалуйста, поправьте меня, если я чего-то упускаю, но я не понимаю, почему преимущество перед архитектурой Renderer.

Вы абсолютно правы во всем этом, но команду не заставляют выбирать единственный подход. Я думаю, все дело в нехватке времени. Я имею в виду, что им просто нужно выпустить "совершенно новый" полностью кроссплатформенный фреймворк пользовательского интерфейса через год вместе с .net 6. И гораздо менее рискованно брать за основу старый добрый, проверенный временем фреймворк. Это нормально и должно быть. Но я считаю, что с течением времени пользовательский рендеринг 2D-холста имеет гораздо больше преимуществ и действительно заслуживает того, чтобы называться «кроссплатформенным». Формы Xamarin - действительно хорошая вещь, и на сегодняшний день в ней есть огромный прогресс. Но пора двигаться дальше. В командах Microsoft и xamarin очень умные инженеры, и они, вероятно, рассматривают такой подход или, возможно, даже имеют какие-то связи с http://avaloniaui.net/ как козырной картой.

Почему бы не создать платформу пользовательского интерфейса с собственным набором элементов управления без каких-либо сопоставлений и поведенческой логики, полностью написанной на C #, которая будет отображаться с помощью графической библиотеки Skia? Поскольку люди используют строго индивидуальный дизайн, нет необходимости пытаться соответствовать руководящим принципам разработки платформы. Единственное, что нужно - это возможность гибкой настройки. Пожалуйста, поправьте меня, если я чего-то упускаю, но я не понимаю, почему преимущество перед архитектурой Renderer.

Было бы здорово иметь 4-й серый цвет по умолчанию для разработчиков Skia, который на 100% изменит его и обязательно обеспечит богатый дизайн,
Для обратной совместимости оставим эти 3 как есть, но добавим "нарисуй сам, дорогой разработчик" _skia_render и возьму на себя 90% ответственности за это разработчик.

Если концепция рендереров должна быть сохранена, можно ли подумать об устранении моста между общим кодом пользовательского интерфейса и рендерерами через INotifyPropertyChanged и обработчики событий? т.е.

  • Вместо установки _property_ на общий элемент управления и распространения события PropertyChanged , можно ли сопоставить и установить свойство непосредственно в рендерере платформы?
  • Вместо того, чтобы вызывать _method_ в общем элементе управления и запускать и обрабатывать событие средством визуализации, может ли метод быть отображен и задействован непосредственно на модуле визуализации платформы?

INotifyPropertyChanged отлично подходит для проектирования MVVM и моделей представления со слабой парой, но всегда казался неуклюжим механизмом моста между общим кодом пользовательского интерфейса и рендерерами платформы. Это, в свою очередь, приведет к повышению производительности, уменьшению «болтливости» между общим пользовательским интерфейсом и слоем рендеринга и более удобному взаимодействию с разработчиком.

Это долго, но стоит присмотреться к "внутреннему бейсболу" на Мауи.
https://www.youtube.com/watch?v=_MGh3xipWm4

Похоже, что архитектура Maui будет поддерживать как элементы управления, визуализированные платформой, так и элементы управления, нарисованные на холсте, и, кроме того, благородный @Clancey продолжит работу над набором рендеринга на основе skia для Maui, который будет работать не только в версии MVU. Мауи, но и для шаблона MVVM.

На первый взгляд Maui показался ребрендингом Forms, но при ближайшем рассмотрении это реструктуризация архитектуры Forms, чтобы сделать ее слои более слабосвязанными и тем самым поддержать многие из вещей, о которых мы спрашиваем в этой ветке. Впереди веселые времена.

Это немного не по теме, но я хотел спросить именно об этом, потому что он имеет прямое отношение к этой теме:

Как память работает с SKCanvasView (или Skia в целом)? Каждый ли всегда занимает память пропорционально своему размеру? Изменится ли это, если он будет перекрывать другие?

Если бы, например, у меня был элемент управления градиентом (средство визуализации, написанное на Skia), и, кроме того, у меня была полупрозрачная кнопка (средство визуализации, написанное на Skia), это занимало бы вдвое больше памяти, или графический контекст каким-то образом разделяется? Как насчет того, чтобы элементы управления Skia перекрывали элементы управления, не относящиеся к Skia?

Раньше я рассматривал возможность реализации некоторых причудливых графических элементов управления в Forms с использованием Skia, но непонимание того, как работает память, всегда вызывало достаточно беспокойства, чего у меня не было.

@GalaxiaGuy Я думаю, что использование элемента управления skia перекрывается с элементом управления, отличным от skia, точно так же, как элемент управления winform, размещенный на элементе управления wpf. Можно, но не лучшим образом.
Если у вас есть два элемента управления, отображаемых с помощью SKCanvasView , графический контекст не будет использоваться совместно. Лучший способ - объединить два визуализированных изображения и нарисовать их на одном холсте.
В моем тесте производительность SkiaSharp не так уж плоха, если вы просто делаете какие-то статические вещи. И я пытаюсь сделать несколько анимаций, на моем ноутбуке загрузка процессора немного высока.

Почему так много людей одержимы Скией? Хорошая спецификация рендеринга не зависит от движка рендеринга, используемого на низком уровне. Если конкретный рендерер платформы хочет использовать Skia (или Direct2D, или OpenGL, или что-то еще), это не должно вызывать беспокойства у прикладного уровня.

Самым большим обещанием XAML с WPF много лет назад была идея Lookless Controls, где фактическая графика элементов управления была отложена до шаблонов. Xamarin Forms использовали XAML без этой возможности, и это было его самым слабым местом, которое лишь спустя годы было частично исправлено спецификацией Drawing.
Я не думаю, что нам нужен еще один набор интерфейсов и абстракций по сравнению с существующими компонентами в различных ОС и фреймворках, но действительно незаметные элементы управления на основе XAML с шаблонами с независимыми от платформы визуальными примитивами и

Самым большим обещанием XAML с WPF много лет назад была идея Lookless Controls, где фактическая графика элементов управления была отложена до шаблонов. Xamarin Forms использовали XAML без этой возможности, и это было его самым слабым местом, которое лишь спустя годы было частично исправлено спецификацией Drawing.

Согласовано! И вам действительно нужно очень небольшое количество примитивов рендеринга, чтобы выполнить, вероятно, 99% всего, что нужно приложению:

  • Границы (включая опции для падающей тени и закругленных краев)
  • Линии / эллипсы / прямоугольники
  • Рендеринг обычного текста
  • Ввод обычного текста
  • Рендеринг форматированного текста
  • Ввод расширенного текста
  • HTML-рендеринг
  • Ведущий изображения
  • Аудио / видео ведущий
  • Кисти Solid и Linear / Radial Gradient

Платформы рендеринга XF стали настолько раздутыми, потому что всякий раз, когда к фреймворку добавляется новый тип элемента управления, это делается с новым рендерером, а не над созданием существующих примитивов в фреймворке.

Да, нужно было бы перенести гораздо больше логики на уровень фреймворка, наиболее сложным из которых является управление элементами ( VirtualizingStackPanel имеет решающее значение для наличия масштабируемого средства просмотра элементов, но, насколько мне известно, никогда не переносился эффективно за пределы WPF, потому что это так сложно). Но поскольку WPF является открытым исходным кодом, многое из этого можно перенести в MAUI сейчас, и я думаю, что, наконец, настало время, когда это должно начаться.

вам действительно нужно очень небольшое количество примитивов рендеринга, чтобы выполнить, вероятно, 99% всего, что нужно приложению.

Платформа Uno использует этот подход.

@velocitysystems

Можно ли сопоставить и установить свойство непосредственно в средстве визуализации платформы вместо установки свойства в общем элементе управления и распространения события PropertyChanged?

Это также большая цель этого изменения. Как только мы окажемся на другой стороне этих изменений, рендереры не будут знать, что означает BindableObject или INPC.

Это также большая цель этого изменения. Как только мы окажемся на другой стороне этих изменений, рендереры не будут знать, что означает BindableObject или INPC.

Таким образом, метод рендерера будет вызываться фреймворком всякий раз, когда изменяется значение BindableProperty вместо того, чтобы рендереру нужно было подписаться на PropertyChanged ?

@legistek правильно

Это в основном инвертирует зависимости

Таким образом, рендереры будут работать только против IButton.

А затем System.Maui добавит ссылку на проект средств визуализации, в отличие от того, как на данный момент средства визуализации имеют ссылки на Xamarin.Forms.Core

Я проверил спайк, который у нас здесь
https://github.com/dotnet/maui/pull/66

Итак, вы можете увидеть, как это может выглядеть

Я буду вести стрим сегодня в 3:30 по тихоокеанскому времени с @davidortinau, и мы будем говорить о тонких

https://www.twitch.tv/microsoftdeveloper

Присоединяйтесь к нам! Проверьте это! И задавайте вопросы!

@PureWeen К сожалению, я это пропустил. Будет ли запись доступна на YouTube?

Это также большая цель этого изменения. Как только мы окажемся на другой стороне этих изменений, рендереры не будут знать, что означает BindableObject или INPC.

Это огромное, действительно существенное улучшение. Несомненно, с переездом на Мауи сложная модель наследования, используемая во многих рендерерах, будет удалена в пользу более композиционного подхода?

Пойду сегодня на обзор №66.

Глядя на №66, приятно видеть, что тонкие рендеры построены и вызываются с помощью «приманки и переключателя», а не с использованием отражения. Несколько мыслей:

  • Смогут ли средства визуализации Slim решать проблемы сборки мусора, особенно на Android, где существует несоответствие между управляемым и собственным жизненным циклом элемента управления? Это особенно заметно в дочерних представлениях в виртуализированных макетах, что приводит к ужасному ObjectDisposedException .
  • Приведут ли средства визуализации Slim к прекращению поддержки Effect ? Эффекты могут быть полезны, но в конечном итоге они добавляют сложность и еще одну возможность задержки жизненного цикла макета.
  • Как «двустороннее» свойство будет работать с новым дизайном средства визуализации? Например, допустим, у меня есть MediaElement со свойством Position ( TimeSpan ). Сеттер обновляет текущую позицию, а геттер получает текущую позицию из собственного медиаплеера, то есть AVPlayer , MediaPlayer . Есть ли дизайн для сопоставления _getter_ с тонкими модулями рендеринга?

Смогут ли средства визуализации Slim решать проблемы сборки мусора, особенно на Android, где существует несоответствие между управляемым и собственным жизненным циклом элемента управления? Это особенно заметно в дочерних представлениях в виртуализированных макетах, что приводит к ужасному исключению ObjectDisposedException.

У нас есть кое-какие идеи !! Мы хотим немного переработать стратегии удаления, чтобы, надеюсь, разрешить большинство, если не все исключения ODE. Прямо сейчас мы очень агрессивно избавляемся от всего в android / iOS, но я уверен, что мы можем просто положиться на сборщик мусора в том, что делает сборщик мусора. Если мы просто разыменуем все и позволим сборщику мусора выполнить работу, которая должна помочь во многих из этих случаев

Приведут ли Slim-рендереры к прекращению поддержки Effect? Эффекты могут быть полезны, но в конечном итоге они добавляют сложность и еще одну возможность задержки жизненного цикла макета.

Это определенно хорошая вещь, на которую стоит обратить внимание, пока мы развиваем эту идею. Как только мы достигнем окончательного дизайна всего этого, мы рассмотрим эффекты. Но, да, я мог видеть, что эффекты устаревают, поскольку они предназначены для использования собственных элементов без использования полного средства визуализации. Картографы в основном устаревшие эффекты

Как «двустороннее» свойство будет работать с новым дизайном средства визуализации? Например, скажем, у меня есть MediaElement со свойством Position (TimeSpan). Сеттер обновляет текущую позицию, а получатель извлекает текущую позицию из собственного медиаплеера, то есть AVPlayer, MediaPlayer. Есть ли дизайн для сопоставления геттера с тонкими модулями рендеринга?

Мы все еще немного работаем над этим. Поправьте меня, если я ошибаюсь https://github.com/dotnet/maui/blob/slim-renderers/Maui.Core/PropertyMapper.cs#L91

Как «двустороннее» свойство будет работать с новым дизайном средства визуализации? Например, скажем, у меня есть MediaElement со свойством Position (TimeSpan). Сеттер обновляет текущую позицию, а получатель извлекает текущую позицию из собственного медиаплеера, то есть AVPlayer, MediaPlayer. Есть ли дизайн для сопоставления геттера с тонкими модулями рендеринга?

Мы все еще немного работаем над этим. Поправьте меня, если я ошибаюсь https://github.com/dotnet/maui/blob/slim-renderers/Maui.Core/PropertyMapper.cs#L91

Не совсем. Таким образом, ActionMapper - это то же самое, что и PropertyMapper, за исключением того, что они не вызываются на этапе SetElement. Итак, для таких вещей, как WebView, GoBack. Вы не хотите вызывать это во время инициализации, но это все равно что-то, что вам нужно для связи с Renderer.

Мы уже поддерживаем двухстороннее отображение. т.е. вход. Когда текстовое значение случайно попадает в запись. IEntry имеет string Text {get;set;} и мы просто устанавливаем значение. Итак, для медиа-элементов у вас есть 2 варианта. Один просто устанавливает назад положение / время, когда оно изменяется. Если вы хотите, чтобы это было что-то, что вы вместо этого запрашиваете. Вы можете сделать это. Представления xplat имеют доступ к рендереру. view.Renderer.NativeView as NativeMediaView Теперь вы можете снять любую недвижимость, какую захотите!

Вот несколько видео из наших стримов во время сборки

@Clancey здесь будет более подробно
https://www.youtube.com/watch?v=_MGh3xipWm4

Я немного касаюсь их здесь с Дэвидом
https://www.youtube.com/watch?v=lAmwjfZY1IM

Как «двустороннее» свойство будет работать с новым дизайном средства визуализации? Например, скажем, у меня есть MediaElement со свойством Position (TimeSpan). Сеттер обновляет текущую позицию, а получатель извлекает текущую позицию из собственного медиаплеера, то есть AVPlayer, MediaPlayer. Есть ли дизайн для сопоставления геттера с тонкими модулями рендеринга?

Мы все еще немного работаем над этим. Поправьте меня, если я ошибаюсь https://github.com/dotnet/maui/blob/slim-renderers/Maui.Core/PropertyMapper.cs#L91

Не совсем. Таким образом, ActionMapper - это то же самое, что и PropertyMapper, за исключением того, что они не вызываются на этапе SetElement. Итак, для таких вещей, как WebView, GoBack. Вы не хотите вызывать это во время инициализации, но это все равно что-то, что вам нужно для связи с Renderer.

Мы уже поддерживаем двухстороннее отображение. т.е. вход. Когда текстовое значение случайно попадает в запись. IEntry имеет string Text {get;set;} и мы просто устанавливаем значение. Итак, для медиа-элементов у вас есть 2 варианта. Один просто устанавливает назад положение / время, когда оно изменяется. Если вы хотите, чтобы это было что-то, что вы вместо этого запрашиваете. Вы можете сделать это. Представления xplat имеют доступ к рендереру. view.Renderer.NativeView as NativeMediaView Теперь вы можете снять любую недвижимость, какую захотите!

Еще одна вещь, которую следует учитывать, - это записи, которые поступают в C # 9. Особенностью является то, что они неизменяемы и имеют свойство доступа init . Таким образом, чтобы сделать их пригодными для использования при двусторонней привязке, сопоставителю необходимо иметь возможность возвращать новый экземпляр с помощью оператора with .

Я действительно надеюсь, что представления будут привязаны к записям, потому что это значительно упрощает работу с чистым MVVM или даже чистым MVU.

Вопрос: на опубликованной вами диаграмме элементы управления Windows отображаются с помощью Windows.UI.* , но, насколько я понимаю, это сейчас в процессе устаревания и не будет никаких обновлений: все улучшения в плавном отрисовке дизайна внесены происходит в Microsoft.UI.* как часть проекта WinUI. Не могли бы вы это прокомментировать?

Я думаю, что сопоставление с собственными элементами управления - большая ошибка, это ужасная часть Xamarin.Forms, вы не можете легко создавать уникальные и красивые макеты, вам нужно было следовать концепции и подходу элементов управления WPF и Flutter без внешнего вида с рендерингом движок написан на C ++ с использованием OpenGL / DirectX / Metal, поскольку это способствует переносимости, производительности и гибкости, а также не зависит от структур платформы, которые постоянно меняются.

Задача здесь, чтобы поговорить о новых картах архитектуры / свойств. Не то, против чего они противопоставляются. Просто чтобы повторить. Тонкая архитектура рендеринга для нативной системы не означает, что мы никогда не будем и никогда не сможем использовать подход рисованного управления. Но это позволяет нам смешивать и сопоставлять нативные и неродные элементы управления, где, если вы идете чисто отрисованным, это сложнее. Я планирую продолжить работу над элементами управления на основе Skia, которые следуют той же архитектуре Slim Renderer, включая слой рисования. https://github.com/Clancey/Comet/tree/dev/src/Comet.Skia/Handlers.

Мои 2 ¢ на этом рендерере (который, признаюсь, я не совсем понимаю, TBH):

У меня было представление о том, как мы могли бы реализовать как элементы управления, отрисованные на платформе (например, обертывание UIButton), так и элементы управления без внешнего вида (а-ля WPF), используя один и тот же класс управления. Честно говоря, это довольно просто: пусть класс Maui Button использует шаблон элемента управления и удаляет из него весь код рендеринга, зависящий от платформы. Затем предоставьте входящий шаблон для Button, содержащий ButtonRenderer. ButtonRenderer - это то, что общается с Cocoa / UIKit / UWP / и т. Д. С помощью специфичного для платформы кода для каждого набора инструментов пользовательского интерфейса, а класс Button, используемый разработчиком приложения, просто пересылает ему свои свойства. Если пользователь хочет использовать настраиваемую кнопку, он может просто переопределить шаблон и использовать классы рисования (независимо от того, как они выглядят) вместо ButtonRenderer, как мы это делаем в WPF. Честно говоря, я не знаю, возможно ли это (или даже уже используется) в Мауи сегодня, поскольку я никогда не тратил время на то, чтобы понять Xamarin.Forms так глубоко, как я понимаю WPF.

Скажи мне, что ты думаешь!

Я пытаюсь понять, что означают Slim-рендереры для разных моделей приложений (MVVM, MVU, ...).

Исходная диаграмма, кажется, говорит о том, что каждая модель приложения будет иметь свой собственный набор средств визуализации.
Но, на мой взгляд, было бы лучше иметь один набор средств визуализации для каждого типа визуализации (например, визуализация с использованием собственных элементов управления, таких как XF, отрисовка на холст и т. Д.).
Средству визуализации не нужно знать модель приложения, ему нужно только знать, какое значение сопоставлено какому свойству, чтобы он мог применить правильное обновление к базовому элементу управления.
Только IButton будет реализован по-разному для каждой модели приложения и будет отвечать за вызов сопоставленных функций своего средства визуализации.

Это важно, потому что сторонние библиотеки, такие как Fabulous, не будут иметь кадровых ресурсов Microsoft для реализации (со всеми связанными с этим ошибками) всех соответствующих средств визуализации для каждого элемента управления на каждой платформе.

Другой момент: интерфейсы управления ( IButton ) должны быть доступны только для получения, чтобы их использовали средства визуализации.
Средства визуализации не устанавливают значения, и каждая модель приложения будет формировать элементы управления по-разному (BindableProperty, BindingObject и т. Д.).
Например, Fabulous будет иметь неизменяемые просмотры. Только внутренне ему будет разрешено установить мутацию для экземпляра IButton .

Таким образом, Fabulous может напрямую использовать интерфейс IButton в качестве читателя для просмотра своего внутреннего словаря, чтобы рендереры могли работать.

// This is the type used by our users, sort of a Builder that return a new instance each time
// and append the set value to an internal list 
public struct Button
{
     public Button Text(string value) => (...);

     internal ReadOnlyDictionary<string, obj> Build() { ... }
}

// This will be an implementation of IButton, hidden from our users
internal class FabulousButton : IButton
{
    private ReadOnlyDictionary<string, obj> _properties;
    FabulousButton(ReadOnlyDictionary<string, obj> properties)
    {
        _properties = properties;
    }

    void Update(ReadOnlyDictionary<string, obj> properties)
    {
        var previousProperties = _properties;
        _properties = properties;

        // Diffing of the 2 dictionaries to determine what changed
        // and which mapped functions inside the renderer should be called
        (...)
    }

    public string Text => _properties["Text"];
}

@TimLariviere Все, что вы сказали, работает :-)

Рисунок там сбивает с толку рендереры.

Единственная часть этого, о которой вам нужно будет беспокоиться, - это Fabulous Button, а обо всем остальном мы позаботимся.

По большей части интерфейсы доступны только для чтения.

Это интерфейс, используемый кнопкой
https://github.com/dotnet/maui/blob/slim-renderer-samples/Maui.Core/Views/IText.cs

Все, что вам действительно нужно (что касается рендереров), - это сигнализировать рендереру, что он должен повторно использовать IButton.

Например, в версии BindableObject всего этого мы просто вызываем здесь метод updateproperty Renderer.

https://github.com/dotnet/maui/blob/slim-renderer-samples/System.Maui.Core/VisualElement.cs#L1132

В какой-то момент (скоро?) У @Clancey будет общедоступная версия Comet, вы сможете посмотреть, как он это делает.

Я бы проверил
https://github.com/dotnet/maui/blob/slim-renderer-samples

Вы, вероятно, можете добавить к нему свой собственный Fabulous.Core, а затем начать добавлять реализации в интерфейсы.

@PureWeen О, круто. Спасибо, попробую поиграть с примерами, которые вы связали, чтобы посмотреть, как все идет.

@PureWeen @Clancey Я уверен, что команда Maui будет этим заниматься, но, пожалуйста, не могли бы новые Slim-рендеры отдать предпочтение композиции, а не наследованию. Наследование полезно, но, к сожалению, в XF оно сделало некоторые иерархии модулей рендеринга невероятно сложными и трудными в обслуживании.

@PureWeen
Этот URL
https://github.com/dotnet/maui/blob/slim-renderer-samples

дает 404, это личное?

@ Rand-Random

https://github.com/dotnet/maui/tree/slim-renderer-samples

@velocitysystems

Я уверен, что команда Maui будет этим заниматься, но, пожалуйста, не могли бы новые Slim-рендеры отдать предпочтение композиции, а не наследованию. Наследование полезно, но, к сожалению, в XF оно сделало некоторые иерархии модулей рендеринга невероятно сложными и трудными в обслуживании.

Вот как они устроены. Есть очень тонкий базовый класс, который наследуется напрямую от старого доброго System.Object

https://github.com/dotnet/maui/blob/slim-renderer-samples/Maui.Core/Renderers/View/AbstractViewRenderer.Android.cs

И родных связей не имеет.

Оттуда все определяется с помощью словаря.

https://github.com/dotnet/maui/blob/slim-renderer-samples/Maui.Core/Renderers/View/AbstractViewRenderer.cs#L31

Который в основном работает как декоратор.

Вы можете украсить мапперы дополнительными мапперами, а также добавить свои собственные функции и т. Д.

Мы стремимся охватить 95 процентов пользовательских сценариев, просто добавив свой собственный Func в картограф или просто получив доступ к собственным элементам напрямую, поскольку все это будет многоцелевым.

@PureWeen Каков наиболее подходящий канал для обсуждения реализации этих тонких модулей рендеринга в вашем примере?

У меня есть такие вопросы, как:

  • Будут ли значения по умолчанию определены централизованно? В XF они в настоящее время определяются при создании полей BindableProperty, но они не будут присутствовать в зависимости от модели приложения.
  • Станет ли класс Application (частично) интерфейсом? Он определяет множество вариантов поведения пользовательского интерфейса (ресурсы, меню, главная страница), и было бы здорово реализовать его по-другому.
  • Будет ли из интерфейсов управления извлекаться Measure / Arrange / и т. Д.? Я не думаю, что в моделях приложений есть смысл реализовывать их по-другому.

Будут ли значения по умолчанию определены централизованно? В XF они в настоящее время определяются при создании полей BindableProperty, но они не будут присутствовать в зависимости от модели приложения.

Это хороший вопрос. @ Кланси ? Не уверен, что мы это еще определили. Есть начальная фаза настройки, когда все сопоставители вызываются с текущим значением свойств (значение по умолчанию), но я не уверен, есть ли у нас еще план для значений по умолчанию и как они будут обобщены.

Станет ли класс Application (частично) интерфейсом? Он определяет множество вариантов поведения пользовательского интерфейса (ресурсы, меню, главная страница), и было бы здорово реализовать его по-другому.

Да! Мы надеемся свести все классы приложений (собственные и xplat) в один класс приложения. Почему вы об этом спрашиваете? Мне просто любопытно, что вы здесь используете, чтобы мы могли решить

Будет ли из интерфейсов управления извлекаться Measure / Arrange / и т. Д.? Я не думаю, что в моделях приложений есть смысл реализовывать их по-другому.

На данный момент это план. Идея состоит в том, чтобы извлечь весь наш код макета, чтобы он не зависел от BindableObject / Property. Таким образом, Blazor / Comet / другой может просто использовать StackLayout, и результат будет таким же.

Почему вы об этом спрашиваете? Мне просто любопытно, что вы здесь используете, чтобы мы могли решить

Я еще не совсем уверен, чего хочу. Но в Fabulous в настоящее время нет хорошей истории для определения глобальных стилей и главного меню (как для macOS). Поскольку мы позволяем нашим пользователям создавать подклассы класса Application, мы в основном говорим им определять ресурсы / меню, как в классическом Xamarin.Forms.

Так что в идеале все свойства приложения, связанные с пользовательским интерфейсом, также должны быть частью представления, таким образом, мы могли бы применить к нему нашу логику различения представлений.

Что-то подобное

public interface IAppRoot
{
    IEnumerable<object> Resources { get; }
    IMenu MainMenu { get; }
    IPage MainPage { get; }
}

public class Application
{
    /// Bootstrapping and other logic of MAUI

   public IAppRoot Root { get; set; } // Replaces MainPage, which is typed for pages only
}

@PureWeen Другой вопрос: кто будет нести ответственность за запуск таких событий, как TextChanged , Toggled и т. Д.? Элементы управления или средства визуализации?

Я думаю, что одна вещь, которая значительно упростит реализацию других моделей приложений, - это возможность не запускать события изменения состояния, когда изменения являются программными.

Например, сегодня TextChanged при входе запускается как когда пользователь что-то пишет, так и когда мы делаем MyEntry.Text = "New value"; .
Я думаю, что реагирование на программное изменение бесполезно и неявно, что плохо для рассуждений о коде.

Также это привело к бесконечному циклу на Android, потому что платформа запускает свои события с небольшой задержкой, и это вынудило Fabulous выйти из синхронизации без возможности вернуться.
Единственный обходной путь, который мы нашли, - это сначала отменить подписку на событие перед установкой значения, а затем повторно подписаться ...

Любопытный вопрос. Когда MAUI не зависит от архитектуры, почему элементы управления называются именами архитектуры? Например, на диаграмме выше у нас есть Мауи. Mvvm .ButtonRenderer.Android? @PureWeen @Clancey

В XF есть что-то, называемое сжатыми макетами (которые содержат ошибки)
Есть ли у нас такая штука (точно без багов!) В MAUI?

Я вижу, как люди реагируют в этой ветке на использование Flutter / Skia подхода к рендерингу пользовательского интерфейса, и я в основном с ними согласен.
Я действительно рад, что MAUI потенциально будет поддерживать пользовательские / не собственные элементы управления и рендеринг.
Тем не менее, я должен сказать, что возможность работать с собственным пользовательским интерфейсом обеспечивает политическую основу.
И да, я указываю на Apple. Из-за последних новостей я не удивлюсь, если в какой-то момент по какой-то причине использование Flutter будет рассматриваться как «использование недокументированных / ограниченных функций» или «несоблюдение рекомендаций Apple UI» и т. Д.

Я вижу, как люди реагируют в этой ветке на использование Flutter / Skia подхода к рендерингу пользовательского интерфейса, и я в основном с ними согласен.
Я действительно рад, что в MAUI потенциально будет поддержка пользовательских / не родных элементов управления и рендеринга.
Тем не менее, я должен сказать, что возможность работать с собственным пользовательским интерфейсом обеспечивает политическую основу.
И да, я указываю на Apple. Из-за последних новостей я не удивлюсь, если в какой-то момент по какой-то причине использование Flutter будет рассматриваться как «использование недокументированных / ограниченных функций» или «несоблюдение рекомендаций Apple UI» и т. Д.

Если MAUI поддерживает Интернет (например, Flitter), мы всегда можем выполнить рендеринг в WebView.
Apple вряд ли когда-нибудь решится блокировать приложения на основе WebView, потому что некоторые крупные компании представлены в AppStore только через WebView.

Я вижу, как люди реагируют в этой ветке на использование Flutter / Skia подхода к рендерингу пользовательского интерфейса, и я в основном с ними согласен.
Я действительно рад, что в MAUI потенциально будет поддержка пользовательских / не родных элементов управления и рендеринга.
Тем не менее, я должен сказать, что возможность работать с собственным пользовательским интерфейсом обеспечивает политическую основу.
И да, я указываю на Apple. Из-за последних новостей я не удивлюсь, если в какой-то момент по какой-то причине использование Flutter будет рассматриваться как «использование недокументированных / ограниченных функций» или «несоблюдение рекомендаций Apple UI» и т. Д.

Если MAUI поддерживает Интернет (например, Flitter), мы всегда можем выполнить рендеринг в WebView.
Apple вряд ли когда-нибудь решится блокировать приложения на основе WebView, потому что некоторые крупные компании представлены в AppStore только через WebView.

это уже противоречит правилам - https://developer.apple.com/app-store/review/guidelines/#minimum -functionality

Прочитав немного назад и вчетвером, что представляет собой весь этот новый мир MAUI, пожалуйста, из любви ко всему святому, на самом деле сделайте запись один раз, чтобы использовать везде движок рендеринга, такой как SKIA или другой мультиплатформенный движок рендеринга, с необходимостью реализации пользовательского Пользовательский интерфейс на каждой платформе, как в Xamarin Forms, кажется старым и как будто это решение, созданное в седьмом круге ада.

если обратная совместимость является обязательной, «просто» сделайте новую и современную поддержку рендеринга способом рендеринга старых компонентов, я видел, что на других платформах есть изящное решение для этого, последнее, что я использовал, находится в движке UI единства, где новый современный UXML имеет рендеринг IMGUI.

@ jackie0100
Я полностью согласен

необходимость реализовывать собственный пользовательский интерфейс на каждой платформе, как в Xamarin Forms, кажется старым и как будто это решение, созданное в седьмом круге ада.

Что касается реализации средства визуализации, как насчет идеи IView IS A native view (вместо IView HAS A native view). т.е. наследование вместо композиции? Это привело бы к самой быстрой и минимальной архитектуре с абсолютно нулевыми «накладными расходами на формы». Вы в основном работаете с чистыми собственными представлениями и просто с общим интерфейсом.

Затем вы могли бы делать такие вещи, как, например, в области iOS, просто преобразовать ваше представление в UIView и добавить к нему собственный дочерний элемент (любого типа, который вы хотите), потому что IView - это UIView. Точно так же, если вы хотите выполнить «собственное встраивание», это просто, потому что IView - это UIView, вы можете просто добавить один из ваших IView в свое собственное представление, потому что они одно и то же. Это значительно обеспечит совместимость встроенного <-> maui с высочайшим уровнем производительности и минимальным потреблением памяти.

Мне кажется, что я сам создаю прототип. Возможно проект выходного / вечернего дня ...

image

Если MAUI поддерживает Интернет (например, Flitter), мы всегда можем выполнить рендеринг в WebView.

Не нужен WebView на iOS: можно отображать непосредственно в OpenGL или Metal .

Или используйте Skia с OpenGL или Metal под ним.

способность работать с собственным пользовательским интерфейсом обеспечивает политическую основу. [Яблоко]

В какой-то момент Apple удалила из своей письменной политики требование использовать собственные виджеты пользовательского интерфейса. Я не вижу никакого практического способа изменить политику обратно к ограничительной.

Тем не менее, возможность _устойчиво_ работать с собственными элементами управления - хороший вариант.

@legistek

Почему так много людей одержимы Скией? Хорошая спецификация рендеринга не зависит от движка рендеринга ...

Хотя я полностью согласен с тем, чтобы быть «агностиком», есть масса деталей, которые необходимо реализовать для рендеринга любого интерактивного пользовательского интерфейса - если вы перейдете непосредственно к OpenGL / Metal / Vulkan / любому низкоуровневому механизму рендеринга. Люди одержимы Skia, потому что это эффективный средний уровень между задачами пользовательского интерфейса приложения и самим механизмом рендеринга: Skia обрабатывает очень много того, что нужно было бы спроектировать и реализовать, если все, что у вас есть, - это голый металл. Нет причин заново изобретать эту работу. Хотя это не должна быть _only_ цель, это чрезвычайно ценная и зрелая цель, которая значительно упростит, скажем, переход от OpenGL к Vulkan.

Я также подозреваю, что нацеливание на Skia будет намного менее обременительным, чем поддержка Xamarin Forms двух параллельных иерархий виджетов - кроссплатформенных виджетов и собственных виджетов.

Skia может даже ускорить тот день, когда .Net Maui станет высокопроизводительным в браузере . Опять же, потому что вместо того, чтобы строить рендеринг на низком уровне, вы начинаете с соответствующей абстракции среднего уровня. Это была бы огромная победа.

Всем привет, не забывайте:
https://github.com/dotnet/maui/discussions/103

Посмотрев недавние видеоролики Maui, если я не ошибаюсь, кажется, что произошел дрейф в пользу более стилизованных элементов управления, при этом собственный элемент управления накладывается на рисунок, выполненный на независимой стороне платформы. Будь то skia или какое-то пакетное взаимодействие с собственным рисованием холста, я надеюсь, что этот подход будет реализован! По иронии судьбы модель рендеринга платформы XF всегда больше всего вредит платформам пользовательского интерфейса Microsoft, будучи наименее используемой.

Я бы также оставил открытой возможность для элемента управления явно не иметь собственный компонент, а для компоновщика макета, чтобы обнаружить это, он мог бы позволить автоматическое сокращение созданных собственных представлений (т.е. если все элементы управления в контейнере являются метками Maui, нарисованными с помощью skia, он мог бы сделать контейнер SkView и просто вызвать операцию рисования в дочерних элементах управления label) на Android, что повысило бы скорость таких вещей, как элементы списка, которые содержат много изображений + текстовые элементы управления, например.

Я не понимаю, что такое рендерер.
Если программа для поглощения визуальных различий цели называется средством визуализации, она должна быть поглощена Xamarin и MAUI вместе. Если нет, я думаю, что это незаконченный Xamarin и MAUI. И он никогда не будет завершен.
Я думаю, что прикладное программирование должно быть более независимым от различий в целевой среде.

Я не понимаю, что такое рендерер.
Если программа для поглощения визуальных различий цели называется средством визуализации, она должна быть полностью поглощена Xamarin и MAUI. Если нет, то я думаю, что это незаконченный Xamarin и MAUI. И это никогда не будет завершено.
Я думаю, что прикладное программирование должно быть более независимым от различий в целевой среде.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

jsuarezruiz picture jsuarezruiz  ·  7Комментарии

sim756 picture sim756  ·  16Комментарии

Joshua-Ashton picture Joshua-Ashton  ·  9Комментарии

jsuarezruiz picture jsuarezruiz  ·  3Комментарии

njsokalski picture njsokalski  ·  6Комментарии