Вверх ↑
Главный модератор
Ответов: 2997
Рейтинг: 395
#1: 2019-11-19 13:33:44 ЛС | профиль | цитата
    Концепции виджета (Widget) и виртуальных точек элемента

  Философское понятие диалектики как единства и борьбы противоположностей наглядно отражается процессом разработки элементов. Разработчик буквально «разрывается» на части между желанием «объять необъятное» и сохранить минимализм визуализации представления элемента в схеме. Наполнение элемента функционалом снижает его универсальность как «кирпича мироздания», а погружение в подробности увеличивает размеры визуальной составляющей и как результат снижение читабельности схемы. Частично проблема решается контейнерами, менеджерами и разрывами линков, но это далеко не панацея. Дробление больших элементов на части перегружает панель элементов. Также надо учесть что дополнительный функционал - это время и силы разработчика (человеко-часы необходимые для разработки и отладки элемента). С другой стороны, дизайнер формы приложения использует понятие компонента как единой сущности представленной графическим эквивалентом на панели инструментов и визуальные элементы содержат в своей структуре его экземпляр. И вот, в попытках найти компромис между расширением функциональности элемента и сохранением его визуальной составляющей было введено понятие виджета элемента как части его структуры.

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

  Что такое виртуальные точки? Это точки элемента, которые заранее не определены автором элемента, но могут быть добавлены пользователем в элемент для расширения его возможностей. По сути это открытые члены класса виджета: конструкторы, поля, свойства, события, методы и т.д.

  Зачем они нужны? Например, .NET Framework предлагает к использованию большое количество классов, которые можно использовать для увеличения возможностей элемента, назначив реализацию класса виджету и получив через него доступ к открытым членам класса через добавление к элементу виртуальных точек. Однако парадигма HiAsm не рассчитана на использование большого количества точек у одного элемента и как решить какие из членов класса необходимы данному элементу? Чтобы разрешить эти вопросы предлагается функционал добавления на элемент точек, выбранных пользователем из списка доступных, но неописанных заранее в конфигурации данного элемента в том числе и как скрытые точки.

  Пример подключения к элементу нескольких виртуальных точек:
Demo



  Давайте расширим возможности элемента Example, используя виджет и виртуальные точки. Для этого назначим виджету элемента реализацию класса .NET Framework. Пусть, например, это будет String​Builder Класс.

  Добавим элементу атрибуты, описывающие метаданные виджета:
...
namespace ElementVirtual
{
...
[Edit(Class = "System.Text.StringBuilder")]
[Assembly("mscorlib.dll=System.Text.StringBuilder")]
...

  Заменим наследуемый базовый класс Element на ElementClass, который реализует работу с невизуальным виджетом:
...
namespace ElementVirtual
{
...
public class Example : ElementClass
...

  Переопределим метод подготовки элемента к запуску для получения экземпляра виджета и используем его для хранения данных элемента:
...
namespace ElementVirtual
{
...
public class Example : ElementClass
{
...
private StringBuilder local;
public override void prepareForRun(ref Element parent)
{
base.prepareForRun(ref parent);
this.local = this.widget as StringBuilder;
}

  Изменим методы-обработчики для работы с экземпляром виджета:
public override void do_work(ElementPoint point, ref TData data)
{
switch (point.name)
{
case "doSayHello":
this.local.Clear();
this.local.Append(readString(data, getPointByName("Data"), null));
this.on_event(getPointByName("onGreeting"), this.local.ToString());
break;

default:
base.do_work(point, ref data);
break;
}
}

public override void read_var(ElementPoint point, ref TData data)
{
switch (point.name)
{
case "Greeting":
if (this.local.isEmpty())
data.assign(new TData(Properties.Resources.greeting));
else
data.assign(new TData(this.local.ToString(), DataType.data_str));
break;

default:
base.read_var(point, ref data);
break;
}
}

  Так будет выглядеть код элемента после изменений:


  Посмотрим как изменились возможности элемента с использованием виджета:
Demo



  Теперь надо сделать изменения скрипта проекта Windows Forms.
//css_pc wfPrecompiler.cs;
public class Example : ElementClass
{
public override bool init(object entry)
{
Debug.WriteLine("{0}.init()".fString(this.codename));
@this.obj = sys.new_instance(this, "Hello World!".toLiteral());
@this.doSayHello = (Func<TArgs, TValue>)((data) =>
{
sys.blk.println(@this.obj, ".Clear();")
.println(@this.obj, ".Append(", d("Data"), ");");
@event("onGreeting", new TValue(String.Concat(@this.obj, ".ToString()"), true));
return TValue.empty;
});
@this.Greeting = (Func<TArgs, TValue>)((data) =>
{
return new TValue(String.Concat(@this.obj, ".ToString()"), true);
});
return base.init(this);
}
}

  Основные изменения - это наследование от класса ElementClass, который реализует работу с невизуальным виджетом и определение его экземпляра:
public class Example : ElementClass
{
...
@this.obj = sys.new_instance(this, "Hello World!".toLiteral());
...
}

  Проверим элемент в работе проекта Windows Forms:
Demo



  Если быть перфекционистом, то можно подгрузить описания виртуальных точек. Для этого добавим в ресурсы сборки ещё один файл в xml-формате с именем System.Text.Builder.xml, в котором находятся описания членов класса на русском и английском языках:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<doc>
<assembly>
<name>System.Text.StringBuilder</name>
</assembly>
<members>
<member name="M:System.Text.StringBuilder.ctor()">
<summary>Initializes a new instance of the StringBuilder class.</summary>
<summary xml:lang="ru">Инициализирует новый экземпляр класса StringBuilder.</summary>
</member>
...
<member name="M:System.Text.StringBuilder.ToString(Int32, Int32)">
<summary>Converts the value of a substring of this instance to a String.</summary>
<summary xml:lang="ru">Преобразует значение подстроки этого экземпляра в String.</summary>
</member>
</members>
</doc>

  И добавим пару строк кода в конструктор элемента, чтобы программа отобразила эту информацию в окне менеджера виртуальных точек:
public Example(PackElement pe, SDK sdk, int x, int y) : base(pe, sdk, x, y)
{
flag |= (int)(ElementFlag.IS_SYSTEM | ElementFlag.IS_VIRTUAL);
var widgets = pe.parent.widgets;
widgets.Add(new Widget(widgets, typeof(StringBuilder), Properties.Resources.System_Text_Builder));
}



  Мы увеличили возможности элемента Example, используя класс .NET Framework в качестве виджета. Можете скачать полный код проекта: MyElementCore.zip
карма: 6
Дорогу осилит идущий. Install/Update HiAsm.NET
0
Редактировалось 3 раз(а), последний 2020-02-11 08:34:55