Вверх ↑
Главный модератор
Ответов: 2997
Рейтинг: 395
#1: 2020-02-08 14:20:39 ЛС | профиль | цитата
    Работа элемента в разных пакетах

  Инфраструктура элемента может хранить реализации для разных пакетов и/или несколько версий реализации для каждого пакета. Давайте добавим в сборку реализации нашего элемента для пакетов Windows и CNET. Сначала поместим в ресурсы сборки файлы с кодом элемента для каждого из пакетов:
Реализация для пакета Windows


unit hi%CLASSNAME%;

interface

uses Kol,Share,Debug;

type
THI%CLASSNAME% = class(TDebug)
private
greeting:string;
public
_data_Data:THI_Event;
_prop_Greeting:string;
_event_onGreeting:THI_Event;
procedure _work_doSayHello(var _Data:TData; Index:word);
procedure _var_Greeting(var _Data:TData; Index:word);
end;

implementation

procedure THI%CLASSNAME%._work_doSayHello;
begin
greeting := ReadString(_Data,_data_Data,_prop_greeting);
_hi_CreateEvent(_Data,@_event_onGreeting,greeting);
end;

procedure THI%CLASSNAME%._var_Greeting(var _Data:TData; Index:word);
begin
if greeting='' then dtString(_Data,ReadString(_Data,_data_Data,_prop_greeting)) else dtString(_Data,greeting);
end;

end.
Реализация для пакета CNET


func init
if(linked("Greeting") and linked("doSayHello"))
sys.add_var(this.name, 2)
end
end

func doSayHello(data)
if(linked("Greeting"))
blk.println(this.codename, ' = ', d("Data", 2, this.props("Greeting").value), ';')
event("onGreeting", this.codename)
else
event("onGreeting", d("Data", 2, this.props("Greeting").value))
end
end

func Greeting
if(linked("doSayHello"))
return(this.codename)
else
return(this.props("Greeting").value)
end
end
  Сохраняем в папку \Resources два файла с именами hiExample.pas и hiExample.hws и помещаем их в ресурсы сборки:

  Переименуем ресурсы для этих файлов в понятные нам имена:

  Добавим в метод инициализации элемента код необходимый для развёртывания ресурсов в пакетах:

public override void init(int flag = 0)
{
base.init(flag);
deployEnvironment(Share.packSet.getPackByName("CNET"));
deployEnvironment(Share.packSet.getPackByName("delphi"));
...
}

protected virtual void deployEnvironment(Pack pack)
{
if (pack == null)
return;
byte[] buffer = null;
string codeName = null;
string className = GetType().Name;
switch (pack.name.ToLower())
{
default:
return;
case "cnet":
buffer = Properties.Resources.cnet_rtcg_script;
codeName = String.Format("hi{0}.hws", className);
break;
case "delphi":
string code = Encoding.UTF8.GetString(Properties.Resources.delphi_source_code);
code = code.Replace("%CLASSNAME%", className);
buffer = Encoding.UTF8.GetBytes(code);
codeName = String.Format("hi{0}.pas", className);
makeConfFile(pack);
break;
}
string codeFile = Path.Combine(pack.pathCode(), codeName);
if (File.Exists(codeFile))
{
if (Helpers.getChecksum(codeFile).Equals(Helpers.crc32(buffer)))
return;
Helpers.fileMoveOverwrite(codeFile);
}
File.WriteAllBytes(codeFile, buffer);
}

protected virtual void makeConfFile(Pack pack)
{
StringBuilder confText = new StringBuilder();
confText.AppendLine("[About]");
confText.AppendFormat("Version={0}{1}", this.tpl.version, Environment.NewLine);
confText.AppendFormat("Author={0}{1}", this.tpl.author, Environment.NewLine);
confText.AppendFormat("Mail={0}{1}", this.tpl.mail, Environment.NewLine);
confText.AppendLine();
confText.AppendLine("[Type]");
confText.AppendLine("Class=Element");
confText.AppendFormat("Info={0}{1}", this.tpl.conf.info, Environment.NewLine);
confText.AppendFormat("Tab={0}{1}", this.tpl.conf.tab, Environment.NewLine);
confText.AppendLine();
confText.AppendLine("[Property]");
foreach (ConfProperty prop in this.tpl.conf.prop)
confText.AppendFormat
(
"{0}{1}{2}={3}|{4}|{5}{6}"
, prop.flags.hasFlag(PropertyFlag.DBLOPEN) ? "+" : ""
, prop.flags.hasFlag(PropertyFlag.MAKEPOINT) ? "@" : ""
, prop.name
, prop.info
, (int)prop.type
, prop.list.isEmpty() ? prop.value.isEmpty() ? "" : String.Format("|{0}", prop.value.Replace(Environment.NewLine, @"\r\n")) : String.Format("|{0}", prop.list)
, Environment.NewLine
);
confText.AppendLine();
confText.AppendLine("[Methods]");
var methods = this.tpl.conf.mtd.Union(this.tpl.conf.def);
foreach (ConfMethod mtd in methods)
confText.AppendFormat
(
"{0}{1}={2}|{3}|{4}{5}"
, mtd.visible ? "" : "*"
, mtd.name
, mtd.info
, (int)mtd.mType
, (int)mtd.dataType
, Environment.NewLine
);
confText.AppendLine();
string confName = String.Format("{0}.ini", GetType().Name);
Helpers.overwriteIfDifferent(confText.ToString(), Path.Combine(pack.path(), Constants.ELEMENTS_CONF_PATH, confName));
}
  В приведённом коде развёртывания, реализуется создание файлов в папках пакетов \code, извлечённых из ресурсов сборки, а также для пакета Windows нужен соответствующий ini-файл элемента, так как кодогенератор считывает его во время создания целевого кода программы. Поэтому мы добавили метод makeConfFile(), который создаёт ini-файл «на лету» и помещает его в папку \conf пакета Windows. Добавим атрибуты установки элемента в дополнительных пакетах:

...
[Install("delphi", "Simple demo", "Core")]
[Install("CNET", "Simple demo", "Core")]
public class Example : ElementClass
{
...
}

  После успешной компиляции сборки открываем её в программе для размещения элемента на панели инструментов в указанной в аргументах атрибута вкладке и проверяем работу элемента в пакетах отличных от пакета Core:
Demo


  Можете скачать полный код проекта элемента: MyElementCore.zip
карма: 6
Дорогу осилит идущий. Install/Update HiAsm.NET
0