Класс Pzl

Материал из wikiru.visual-prolog.com

Назначение

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

Имплементация класса pzl содержится:

  • в случае pzl-контейнера (DLL) в библиотеке pzlContainer_YY.lib
  • в случае главного приложения в библиотеке pzlPort_XX.lib

здесь YY и XX - уровень лицензии.

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

Список доменов

pzlComponentsRegisterFileName_D Состояние файла-реестра компонент данного приложения
pzlContainerContentInfo_D Информация о компонентах контейнера
entityUID_D Идентификатор сущности

Описание доменов

pzlDomains::pzlComponentsRegisterFileName_D

Состояние файла-реестра компонент

pzlComponentsRegisterFileName_D=
  pzlRegistryFileName(string FileName);
  pzlRegistryFileNameWronglyDefined;
  pzlRegistryFileNameNotInUse.

Определяет одно из состояний назначения файла-реестра компонент для данного приложения.

pzlRegistryFileName(string FileName)
назначен файл с именем FileName.
pzlRegistryFileNameWronglyDefined
файл-реестр неправильно определен, возможно, отсутствовал на момент назначения.
pzlRegistryFileNameNotInUse
файл-реестр к данному моменту не назначался, то есть не используется.

pzlDomains::pzlContainerContentInfo_D

pzlDomains::entityUID_D

domains
 
    entityUID_D =
        str(string);
        uid(
        core::unsigned32 Unsigned,
        core::unsigned16 Short1,
        core::unsigned16 Short2,
        core::unsigned8 Byte1,
        core::unsigned8 Byte2,
        core::unsigned8 Byte3,
        core::unsigned8 Byte4,
        core::unsigned8 Byte5,
        core::unsigned8 Byte6,
        core::unsigned8 Byte7,
        core::unsigned8 Byte8).

pzlComains::pzlContainerContentInfo_D

    pzlContainerContentInfo_D = pzlComponentInfo_D*.
    pzlComponentInfo_D=pzlComponentInfo
        (
        string Alias,
        entityUID_D ComponentID,
        booleanInt Runable,
        core::namedValue_List UserDefinedInfo
        );
        void.

pzlDomains::pzlSystem_D

    pzlSystem_D = entityUID_D.

pzlDomains::pzlLicenseLevel_D

    pzlLicenseLevel_D = entityUID_D.

pzlDomains::pzlLicenseNo_D

    pzlLicenseNo_D = entityUID_D.

Список предикатов класса

classInfo.
Получение информации о версии и дате последнего изменения класса Pzl
Информация о контейнере
getContainerName:()->string ThisContainerName procedure ().
Получить имя файла-контейнера, в котором находится данная компонента
getContainerVersion:()->string ThisContainerVersion procedure ().
Получить идентификатор версии контейнера, в котором находится данная компонента
getLicenseLevel:()->string PZLUserLicenseLevel procedure ().
Получить значение уровня лицензии контейнера, в котором находится данная компонента
getComponentRegisterFileName:()->pzlDomains::pzlComponentsRegisterFileName_D ComponentRegisterFileName procedure ().
Получить имя файла-реестра компонент, назначенного для данного приложения
getContainerContentList:(string PZLContainerFileName)->pzlDomains::pzlContainerContentInfo_D ContentInfo procedure (i).
Получить список компонент, содержащихся в контейнере с заданным именем
Управление компонентами
newByID:(pzlDomains::entityUID_D,object InObject)->object OutObject.
Создать новый объект, используя уникальный идентификатор компоненты
newByName:(string Name,object InObject)->object OutObject procedure (i,i).
Создать новый объект, используя имя компоненты
setStdOutputStream:(outputStream OutputStream).
Назначить заданный выходной поток в качестве стандартного выходного потока для всех компонент, используемых данным приложением
Регистрация объектов
register:(string ObjectName,object Object) procedure (i,i).
Зарегистрировать объект под указанным именем ObjectName (однократно)
registerMulti:(string ObjectName,object Object) procedure (i,i).
Зарегистрировать объект под указанным именем ObjectName (возможно, многократно)
getObjectByName_nd:(string ObjectName)->object Object nondeterm (i).
Получить объект, зарегистрированный под указанным именем ObjectName
getNameByObject_nd:(object Object)->string ObjectNameLow nondeterm (i).
Получить регистрационное имя объекта
getNameAndObject_nd:(string ObjectName,object Object) nondeterm (o,o).
Получить имя объекта и сам объект
unRegister:(string ObjectName,object Object) procedure (i,i).
Снять с регистрации объект Object с указанным именем ObjectName
unRegisterByName:(string ObjectName) procedure (i).
Снять с регистрации все объекты с указанным именем ObjectName
unRegisterByObject:(object Object) procedure (i).
Снять с регистрации объект Object
unRegisterAll:() procedure ().
Очистить регистр объектов (снять с регистрации все объекты)
Служебные предикаты. Не документируются
releaseInactiveContainers:().
getContainerActivity_nd:(string FileName,unsigned RefCounter) nondeterm (o,o).
getContainerToBeUnloaded_nd:(string FileName) nondeterm (o).
subscribe:(notificationAgency::notificationListener NotificationListener).
unSubscribe:(notificationAgency::notificationListener NotificationListener).
newInstance:().
release:().

Используемые дополнительные ресурсы

Обязательно:

  • Класс Pzl использует библиотеку pzlPort_XX.lib, если целью проекта является исполняемоее приложение (.EXE) и библиотеку pzlContainer_XX - если целью проекта является контейнер (DLL). Указанные библиотеки фактически содержат имплементацию класса Pzl.
  • наличие пакета pzlConfig.

Описание предикатов

pzl::getContainerName/0

getContainerName:()->string ThisContainerName procedure ().
Получить имя файла-контейнера, в котором находится данная компонента

Описание

Возвращает имя (полный маршрут) файла, в котором находится данная pzl-компонента.

Пример

...
ContainerName=pzl::getContainerName(),
stdIO::writef("Компонента /"MyComponent/" находится в контейнер %",ContainerName),
...

Исключения

Исключения не генерируются

pzl::getContainerVersion/0

getContainerVersion:()->string ThisContainerVersion procedure ().
Получить идентификатор версии контейнера, в котором находится данная компонента

Описание

Возвращает версию pzl-контейнера, в котором находится данная компонента.

Версия контейнера представляется значением строкового типа (string) и определяется константой "pzlContainerVersion_C" в файле iPzlConfig.i проекта контейнера.

Пример

Например, файл iPzlConfig.i данного контейнера содержит объявление константы

constants
  pzlContainerVersion_C="1.0;001".

Следующий код получает номер версии данного контейнера

...
ContainerVersion=pzl::getContainerVersion(),
stdIO::writef("Версия контейнера - %",ContainerVersion),
...

В стандартный выходной поток будет выведено: "Версия контейнера - 1.0;001"

Исключения

Исключения не генерируются

pzl::getLicenseLevel/0

getLicenseLevel:()->string PZLUserLicenseLevel procedure ().
Получить значение уровня лицензии контейнера, в котором находится данная компонента

Описание

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

  • "Public" (публичная)
  • "Commercial" (коммерческая)
  • "Exclusive" (эксклюзивная)
  • "SuperExclusive" (супер-эксклюзивная)
  • "Unknown" (неизвестная)

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

Пример

Код, приведенный ниже, может получить уровень лицензии текущей компоненты

...
LicenseLevel=pzl::getLicenseLevel(),
stdIO::writef("Уровень лицензии текущего контейнера - %",LicenseLevel),
...

Исключения

Исключения не генерируются

pzl::getComponentRegisterFileName/0

getComponentRegisterFileName:()->pzlDomains::pzlComponentsRegisterFileName_D ComponentRegisterFileName procedure ().
Получить состояние назначения файла-реестра компонент для данного приложения

Описание

Возвращает один из следующих термов, определяющих состояние назначения файла-реестра компонент данного приложения.

  • pzlRegistryFileName(FileName) - FileName определяет полное имя файла
  • pzlRegistryFileNameWronglyDefined - файл-реестр неправильно определен
  • pzlRegistryFileNameNotInUse - файл-реестр не используется

Пример

...
RegisterStatus=pzl::getComponentRegisterFileName(),
(
   RegisterStatus=pzlDomains::pzlRegistryFileName(FileName),
   stdio::writef("Файл-реестр компонент - %\n",FileName)
or
   RegisterStatus=pzlDomains::pzlRegistryFileNameNotInUse,
   stdio::write("Файл-реестр компонент не используется\n")
or
   RegisterStatus=pzlDomains::pzlRegistryFileNameWronglyDefined,
   stdio::write("Файл-реестр компонент не был найден при назначении\n")
),
...

Исключения

Исключения не генерируются.

pzl::getContainerContentList/1

getContainerContentList:(string PZLContainerFileName)
  ->pzlDomains::pzlContainerContentInfo_D ContentInfo procedure (i).
Получить список компонент, содержащихся в контейнере с заданным именем

Описание

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

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

  • "pzlPort" либо
  • имя файла (полный или относительный) маршрут к главному приложению

Каждый элемент возвращаемого списка представляет собой терм домена pzlComponentInfo_D

pzlComponentInfo_D=pzlComponentInfo
  (
  string Alias,
  entityUID_D ComponentID,
  booleanInt Runable,
  core::namedValue_List UserDefinedInfo
  )

Здесь

  • Alias - строковое имя компоненты,
  • ComponentID - идентификатор компоненты
  • Runable - булевый признак возможности самостоятельного запуска компоненты
  • UserDefinedInfo - список параметров, задаваемый и интерпретируемый создателем компоненты.

Пример

В примере ниже по событию onShowComponentsDescription (кнопка на панели) запрашивается информация о компонентах контейнера "..\\VPPuzzle\\Demo\\PZL\\HelloWorld.pzl", которая выводится в стандартный поток вывода

predicates
  onShowComponentsDescription : button::clickResponder.
clauses
  onShowComponentsDescription(_Source) = button::defaultAction:-
    DataList=pzl::getContainerContentList("..\\VPPuzzle\\Demo\\PZL\\HelloWorld.pzl"),
    foreach Element=list::getMember_nd(DataList) do
      stdio::writef("Element=%\n",Element)
    end foreach.

В частности, для этого контейнера, получим

Element=pzlcomponentinfo("HelloWorld",str("HelloWorld"),1,[])

А для контейнера FactDemo_UI тот же код

clauses
  onShowComponentsDescription(_Source) = button::defaultAction:-
    DataList=pzl::getContainerContentList("..\\VPPuzzle\\Demo\\PZL\\FactDemo_UI.pzl"),
    foreach Element=list::getMember_nd(DataList) do
      stdio::writef("Element=%\n",Element)
    end foreach.

Вернет (форматирование элементов терма для наглядности сделано вручную)

Data:=pzlcomponentinfo(
  "FactDemo",
   str("Fact_UI"),
   1,
   [
   namedvalue("CodeExporter",string("FactDemoExporter")),
   namedvalue("ProxyExporter",string("FactDemoExporter"))
   ]
   )

Исключения

Генерируются исключения, если

  • Не найден файл-контейнер
  • Невозможно загрузить DLL-контейнер
  • Версия DLL-контейнера не соответствует версии главного приложения
  • Уровень лицензии главного приложения ниже уровня лицензии запрашиваемого контейнера
  • DLL-контейнер не соответствует принятым pzl-соглашениям.

pzl::newByID/2

newByID:(pzlDomains::entityUID_D ComponentID,object InObject)->object OutObject.
Создать новый объект, используя уникальный идентификатор компоненты


Описание

Создает новый объект pzl-компоненты, зарегистрированной c идентификатором ComponentID.

Pzl-компонента с указанным идентификатором ComponentID должна быть зарегистрирована в одном из допустимых мест регистрации - в реестре Windows или в файле-реестре пользователя *.pzr.

Указатель на объект InObject может быть указателем на любой объект - экземпляр класса. Компонента, чей объект создается, должна знать домен-интерфейс объекта InObject, если в ней предусматривается обращение к этому объекту.

Возвращаемый Object является указателем на созданный объект. Для вызова предиката созданного объекта OutObject должен быть преобразован к домену, определяемому интерфейсом этого класса.

Пример

Компонента MyComponent поддерживает интерфейс iMyComponent, в котором определен предикат myPredicate(...).

...
Object=newByID(str("MyComponent"),This),
MyComponentInstance=tryConvert(iMyComponent,Object),
MyComponentInstance:myPredicate(...),
...

В случае использования уникального идентификатора UID

...
Object=newByID(uid(0xDF29A0EA,0x7BA6,0x4425,0x8D,0x88,0x2B,0x3C,0x6F,0xDA,0x0C,0x73),This),
MyComponentInstance=tryConvert(iMyComponent,Object),
MyComponentInstance:myPredicate(...),
...

Исключения

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

Возможные причины неуспешного создания компоненты

  1. pzl-система не имеет доступа к реестру компонент.
  2. pzl-компонента с указанным именем не найдена в реестре компонент.
  3. pzl-контейнер, содержащий компоненту, с указанным именем не может быть загружен
  4. pzl-контейнер и главное приложение имеют несовместимые версии
  5. главное приложение имеет уровень лицензии ниже, чем pzl-контейнер
  6. загруженный pzl-контейнер не содержит компоненту с указанным именем
  7. конструктор данный компоненты не может создать экзмепляр компоненты

Если возникает исключительная ситуация, связанная c причинами 3,4 и 5, то pzl-система пытается выгрузить контейнер. При невозможности выгрузить контейнер генерируется исключительная ситуация.

В стеке исключительных ситуаций последнее описание исключения содержит текст:

newByID failured for the Component with the ID <ID>
(предикат NewByID не выполнен для компоненты с идентификатором <ID>"

pzl::newByName/2

newByName:(string Name,object InObject)->object OutObject procedure (i,i).
Создать новый объект, используя имя компоненты

Описание

Создает новый объект pzl-компоненты, зарегистрированной под именем Name.

Pzl-компонента с именем Name должна быть зарегистрирована в одном из допустимых мест регистрации - в реестре Windows или в файле-реестре пользователя *.pzr.

Указатель на объект InObject может быть указателем на любой объект - экземпляр класса. Компонента, чей объект создается, должна знать домен-интерфейс объекта InObject, если в ней предусматривается обращение к этому объекту.

Возвращаемый Object является указателем на созданный объект. Для вызова предиката созданного объекта OutObject должен быть преобразован к домену, определяемому интерфейсом этого класса.

Пример

Компонента MyComponent поддерживает интерфейс iMyComponent, в котором определен предикат myPredicate(...).

...
Object=newByName("MyComponent",This),
MyComponentInstance=tryConvert(iMyComponent,Object),
MyComponentInstance:myPredicate(...),
...

Исключения

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

Возможные причины неуспешного создания компоненты

  1. pzl-система не имеет доступа к реестру компонент.
  2. pzl-компонента с указанным именем не найдена в реестре компонент.
  3. pzl-контейнер, содержащий компоненту, с указанным именем не может быть загружен
  4. pzl-контейнер и главное приложение имеют несовместимые версии
  5. главное приложение имеет уровень лицензии ниже, чем pzl-контейнер
  6. загруженный pzl-контейнер не содержит компоненту с указанным именем
  7. конструктор данный компоненты не может создать экзмепляр компоненты

Если возникает исключительная ситуация, связанная c причинами 3,4 и 5, то pzl-система пытается выгрузить контейнер. При невозможности выгрузить контейнер генерируется исключительная ситуация.

В стеке сообщений обработки исключений последнее описание исключения содержит текст:

newByName failured for the Component 'Name'
(предикат NewByName не выполнен для компоненты с именем "Name")

pzl::setStdOutputStream/1

setStdOutputStream:(outputStream OutputStream).
Назначить заданный выходной поток в качестве стандартного выходного
потока для всех компонент, используемых данным приложением

Описание

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

Так, если одна компонента назначила в качестве стандартного выходного потока поток A, а после этого другая компонента назначила в качестве стандартного выходного потока поток B то, когда управление вернется к первой компоненте, для нее стандартным выходным потоком будет поток B, установленный второй компонентой.

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

Такое поведение соответсвует принципу целостности приложения, построенного на компонентах.

Пример

Следующий пример создает новый выходной поток в окно сообщений и назначает его в качестве стандартного потока вывода

...
MessageStream=outputStream_message ::new(),
pzl::setStdOutputStream(MessageStream),
...

Исключения

Исключения не генерируются.

pzl::register/2

register:(string ObjectName,object Object) procedure (i,i).
Зарегистрировать объект под указанным именем ObjectName (однократно)

Описание

Позволяет зарегистрировать объект в глобальном (в масштабах данного приложения) регистре экземпляров. Любой объект класса системы программирования Visual Prolog, или объект компоненты могут быть зарегистрированы под именем, действительным в пределах данного приложения.

Предикат register(), получая на вход объект Object и строковое имя ObjectName, выбранное пользователем, помещает этот объект под этим именем в регистр.

Предикат register позволяет поместить объект с данным именем однократно. Если в регистре приложения объект с таким именем (независимо от регистра алфавита) уже имеется, то генерируется исключение. Один и тот же объект Object может быть помещен в регистр под различными именами. Повторяемость объекта Object не проверяется.

Пример

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

...
run():-
  pzlPort::init(),
  TaskWindow = taskWindow::new(),
  pzl::register(studioConstants::studioTaskWindow_C,TaskWindow),
  TaskWindow:addShowListener(onShow),
  TaskWindow:addMenuItemListener(resourceIdentifiers::id_file_run_profile,onRunProfile),
  TaskWindow:show().

По контексту программы известно, что в данном месте окно TaskWindow создается впервые, поэтому обработка возможного исключения не предусмотрена.

В примере ниже такая обработка предусмотрена, поскольку возможно повторное создание объекта формы. Считается, что переменная TaskWindow получила значение прежде и используется в качестве родительского окна

...
TicketForm = ticketForm::new(),
trap(pzl::register("Билетная Форма",TicketForm ),Error,ExceptionHandler(Error,"Билетная Форма")),
TicketForm :show(TaskWindow).
...

Исключения

Если в регистре уже имеется объект с таким же именем, что и ObjectName.

pzl::registerMulti/2

registerMulti:(string ObjectName,object Object) procedure (i,i).
Зарегистрировать объект под указанным именем ObjectName (возможно, многократно)

Описание

Позволяет зарегистрировать объект в глобальном (в масштабах данного приложения) регистре экземпляров. Любой объект класса системы программирования Visual Prolog, или объект компоненты могут быть зарегистрированы под именем, действительным в пределах данного приложения.

Предикат registerMulti(...), получая на вход объект Object и строковое имя ObjectName, выбранное пользователем, помещает этот объект под этим именем в регистр.

Предикат registerMulti(...) позволяет поместить в регистр только один объект Object c данным именем. Если такой объект с этим именем уже существует, то никакие действия над регистром не выполняются.

Вместе с тем под одним и тем же именем могут быть помещены несколько различных объектов.

Пример

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

...
FormEditorObject=formEditor::new(This),
pzl::registerMulti("Редактор Формы",FormEditorObject),
FormEditorObject:show(TaskWindow),
...

Исключения

Исключения не генерируются.

pzl::getObjectByName_nd/1

getObjectByName_nd:(string ObjectName)->object Object nondeterm (i).
Получить объект, зарегистрированный под указанным именем ObjectName

Описание

Предикат getObjectByName_nd(...) по заданному имени ObjectName возвращает в недетерминированном режиме все объекты, зарегистрированные ранее в регистре под этим именем. Если объекта с указанным именем в регистре нет, то предикат завершается неуспешно.

Пример

В примере ниже:

в первой клаузе проверяется не содержится ли в регистре объект с именем componentAlias_C. Если объект уже создавался, то он преобразуется к домену messageForm и на этот объект устанавливается фокус. Исполнение предиката завершается.

Во второй клаузе запоминается текущий выходной поток, создается объект класса messageForm, которому назначается, восстановленное из регистра окно приложения ApplicationWindow. Текущий объект регистрируется в регистре под именем componentAlias_C.

Предикат getApplicationWindow() восстанавливает указатель на объект ApplicationWindow из регистра.

createMessageForm(_InText):-
  Object=pzl::getObjectByName_nd(componentAlias_C),
  LiveObject=convert(messageForm,Object),
  LiveObject:setFocus(),
  !.
createMessageForm(_UserText):-
  defaultOutputStream_V:=stdio::getOutputStream(),
  ApplicationWindow=getApplicationWindow(),
  messageForm_V:=messageForm::display(ApplicationWindow),
  OutputStream=messageForm_V:getOutputStream(),
  pzl::setStdOutputStream(OutputStream),
  pzl::register(componentAlias_C,This),
  messageForm_V:setCloseResponder(onMessageFormCloseRequest),
  messageForm_V:addDestroyListener(onDestroy).
 
predicates
  getApplicationWindow:()->applicationWindow.
clauses
  getApplicationWindow()=convert(applicationWindow,TaskWindowObj):-
    TaskWindowObj=pzl::getObjectByName_nd(studioConstants::studioTaskWindow_C),
    !.
  getApplicationWindow()=_Win:-
    common_Exception::raise_User(classInfo,predicate_FullName(),"InternalError: Unexpected Alternative").
<vip>
 
'''Исключения'''
 
Исключительные ситуации не генерируются
 
==pzl::getNameByObject_nd/1==
<vip>getNameByObject_nd:(object Object)->string ObjectNameLow nondeterm (i).
Получить регистрационное имя объекта

pzl::getNameAndObject_nd/2

getNameAndObject_nd:(string ObjectName,object Object) nondeterm (o,o).
Получить имя объекта и сам объект

pzl::unRegister/2

unRegister:(string ObjectName,object Object) procedure (i,i).
Снять с регистрации объект Object с указанным именем ObjectName

pzl::unRegisterByName/1

unRegisterByName:(string ObjectName) procedure (i).
Снять с регистрации все объекты с указанным именем ObjectName

pzl::unRegisterByObject/1

unRegisterByObject:(object Object) procedure (i).
Снять с регистрации объект Object

pzl::unRegisterAll/0

unRegisterAll:() procedure ().
Очистить регистр объектов (снять с регистрации все объекты)