System/Docu/ru/Meta.odc

Meta

DEFINITION Meta;

	CONST
		undef = 0;
		typObj = 2; varObj = 3; procObj = 4; fieldObj = 5; modObj = 6;
		boolTyp = 1; sCharTyp = 2; charTyp = 3;
		byteTyp = 4; sIntTyp = 5; intTyp = 6; longTyp = 10; sRealTyp = 7; realTyp = 8;
		setTyp = 9; anyRecTyp = 11; anyPtrTyp = 12;
		procTyp = 16; recTyp = 17; arrTyp = 18; ptrTyp = 19;
		final = 0; extensible = 1; limited = 2; abstract = 3;
		hidden = 1; readOnly = 2; exported = 4;

	TYPE
		Name = ARRAY 256 OF CHAR;

		Value = ABSTRACT RECORD END;

		Item = RECORD (Value)
			obj-, typ-, vis-, adr-: INTEGER;
			(VAR i: Item) Valid (): BOOLEAN, NEW;
			(VAR i: Item) GetTypeName (OUT mod, type: Name), NEW;
			(VAR i: Item) BaseTyp (): INTEGER, NEW;
			(VAR i: Item) Level (): INTEGER, NEW;
			(VAR i: Item) Size (): INTEGER, NEW;
			(VAR arr: Item) Len (): INTEGER, NEW;
			(VAR in: Item) Lookup (IN name: ARRAY OF CHAR; VAR i: Item), NEW;
			(VAR i: Item) GetBaseType (VAR base: Item), NEW;
			(VAR rec: Item) GetThisBaseType (level: INTEGER; VAR base: Item), NEW;
			(VAR rec: Item) Is (IN type: Value): BOOLEAN, NEW;
			(VAR ptr: Item) Deref (VAR ref: Item), NEW;
			(VAR arr: Item) Index (index: INTEGER; VAR elem: Item), NEW;
			(VAR proc: Item) Call (OUT ok: BOOLEAN), NEW;
			(VAR var: Item) GetVal (VAR x: Value; OUT ok: BOOLEAN), NEW;
			(VAR var: Item) PutVal (IN x: Value; OUT ok: BOOLEAN), NEW;
			(VAR var: Item) GetStringVal (OUT x: ARRAY OF CHAR; OUT ok: BOOLEAN), NEW;
			(VAR var: Item) GetSStringVal (OUT x: ARRAY OF SHORTCHAR; OUT ok: BOOLEAN), NEW;
			(VAR var: Item) PutStringVal (IN x: ARRAY OF CHAR; OUT ok: BOOLEAN), NEW;
			(VAR var: Item) PutSStringVal (IN x: ARRAY OF SHORTCHAR; OUT ok: BOOLEAN), NEW;
			(VAR var: Item) PtrVal (): ANYPTR, NEW;
			(VAR var: Item) PutPtrVal (x: ANYPTR), NEW;
			(VAR var: Item) IntVal (): INTEGER, NEW;
			(VAR var: Item) PutIntVal (x: INTEGER), NEW;
			(VAR var: Item) RealVal (): REAL, NEW;
			(VAR var: Item) PutRealVal (x: REAL), NEW;
			(VAR var: Item) LongVal (): LONGINT, NEW;
			(VAR var: Item) PutLongVal (x: LONGINT), NEW;
			(VAR var: Item) CharVal (): CHAR, NEW;
			(VAR var: Item) PutCharVal (x: CHAR), NEW;
			(VAR var: Item) BoolVal (): BOOLEAN, NEW;
			(VAR var: Item) PutBoolVal (x: BOOLEAN), NEW;
			(VAR var: Item) SetVal (): SET, NEW;
			(VAR var: Item) PutSetVal (x: SET), NEW;
			(VAR type: Item) New (): ANYPTR, NEW;
			(VAR val: Item) Copy (): ANYPTR, NEW;
			(VAR rec: Item) CallWith (proc: PROCEDURE (VAR rec, par: ANYREC); VAR par: ANYREC), NEW
		END;

		Scanner = RECORD 
			this-: Item;
			eos-: BOOLEAN;
			(VAR s: Scanner) ConnectToMods, NEW;
			(VAR s: Scanner) ConnectTo (IN obj: Item), NEW;
			(VAR s: Scanner) Scan, NEW;
			(VAR s: Scanner) GetObjName (OUT name: Name), NEW;
			(VAR s: Scanner) Level (): INTEGER, NEW
		END;

	LookupFilter = PROCEDURE (IN path: ARRAY OF CHAR; OUT i: Item; OUT done: BOOLEAN)

	PROCEDURE Lookup (IN name: ARRAY OF CHAR; OUT mod: Item);
	PROCEDURE LookupPath (IN path: ARRAY OF CHAR; OUT i: Item);
	PROCEDURE GetItem (obj: ANYPTR; OUT i: Item);
	PROCEDURE GetThisItem (IN attr: ANYREC; OUT i: Item);
	PROCEDURE InstallFilter (filter: LookupFilter);

END Meta.


Meta предоставляет доступ к информации времени выполнения о типах Компонентного Паскаля. Meta усекает ее до открытой информации, то есть, доступ к неэкспортированным элементам модуля не разрешен. Meta безопасен, он не позволяет изменять данные, которые не экспортированы или не изменяемы. В общем, Meta позволяет делать с модулем только то, что может быть сделано также в обычном клиентском модуле. Отличия в том, что Meta является более динамичным; он допускает поиск, просмотр и изменение данных в зависимости от решений во время выполнения, без статического импорта просматриваемого или изменяемого модуля.

Константы не доступны через Meta, они не сделаны доступными во время выполнения, чтобы уменьшить требования к памяти.

Примеры:
ObxCtrls	элемент управления - ползунокl, расширенный из Controls.Control
ObxFldCtrls	специализированное  текстовое поле, расширенное из Controls.Control

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

	Meta.Lookup(moduleName, item);
	IF item.obj = Meta.modObj THEN
		item.Lookup(procedureName, item);
		IF item.obj = Meta.procObj THEN
			item.GetVal(item0, ok);
			IF ok THEN
				item0.fun(x)
				...

Элемент item является нормальным, нерасширенным Meta.Item. Напротив, item0 должен быть расширением Meta.Value, которое содержит одно дополнительное поле соответствующего процедурного типа:

	item0: RECORD (Meta.Value)
				fun: PROCEDURE (x: REAL): REAL
			END;


CONST undef
Возможный код результата для классов объекта, классов типа, классов видимости.

CONST typObj, varObj, procObj, fieldObj, modObj
Классы объекта.

CONST boolTyp, sCharTyp, charTyp, byteTyp, sintTyp, intTyp, longTyp,
			sRealTyp, realTyp, setTyp, anyRecTyp, anyPtrTyp, procTyp, recTyp, arrTyp, ptrTyp
Классы типа.

CONST final, extensible, limited, abstract
Атрибуты записи.

CONST hidden, readOnly, exported
Классы видимости.


TYPE Name
Строковой тип для имен элементов.


TYPE Value
ABSTRACT
Значение может быть расширено только один раз, единственным полем.


TYPE Item (Value)

obj-: INTEGER	obj IN {typObj..modObj}
Класс объекта.

typ-: INTEGER	obj IN {boolTyp..procTyp}
Тип объекта.

vis-: INTEGER	vis IN {hidden..exported}
Видимость.

adr-: INTEGER
Адрес памяти.

PROCEDURE (VAR i: Item) Valid (): BOOLEAN
NEW
Определяет, является ли элемент правильным, то есть инициализированным, установленным в соответствующий тип, и загружен ли его модуль.

PROCEDURE (VAR i: Item) GetTypeName (OUT mod, type: Name)
NEW
Возвращает имя типа элемента и имя модуля этого типа.

Предусловие
i.Valid()	20
i.typ >= recTyp	21
модуль типа загружен	24

PROCEDURE (VAR i: Item) BaseTyp (): INTEGER
NEW
Возвращает базовый тип элемента.

Предусловие
i.Valid()	20
i.typ IN {arrTyp, recTyp, ptrTyp}	21

PROCEDURE (VAR i: Item) Level (): INTEGER
NEW
Возвращает уровень элемента.

Предусловие
i.Valid()	20
i.typ IN {recTyp, arrTyp}	21

PROCEDURE (VAR i: Item) Size (): INTEGER
NEW
Возвращает размер элемента в байтах.

Предусловие
i.Valid()	20
i.typ # undef	21

PROCEDURE (VAR arr: Item) Len (): INTEGER
NEW
Возвращает длину массива.

Предусловие
i.Valid()	20
i.typ = arrTyp	21

PROCEDURE (VAR in: Item) Lookup (IN name: ARRAY OF CHAR; VAR i: Item)
NEW
Ищет элемент в модуле или поле в записи.

Предусловие
in.Valid()	20
in.obj = modObj  OR  in.typ = recTyp	21

Постусловие
i.obj # undef
	поиск удался
i.obj = undef
	поиск потерпел неудачу

PROCEDURE (VAR i: Item) GetBaseType (VAR base: Item)
NEW
Присваивает base базовый тип i.

Предусловие
i.Valid()	20
i.typ IN {recTyp, arrTyp}	21

PROCEDURE (VAR rec: Item) GetThisBaseType (level: INTEGER; VAR base: Item)
NEW
Присваивает base базовый тип уровня level. Если уровень не существует, i.obj устанавливается в undef.

Предусловие
i.Valid()	20
i.typ IN {recTyp, arrTyp}	21
level >= 0  &  level < 16	28

PROCEDURE (VAR rec: Item) Is (IN type: Value): BOOLEAN
NEW
Выполняет проверку типа rec IS type.

Предусловие
rec.Valid()	20
rec.typ = recTyp	21
type IS Item
	type.Valid()	20
	type.typ = recTyp	21
~(type IS Item)
	type.Level() = 1	25
	number of fields of type = 1	26

PROCEDURE (VAR ptr: Item) Deref (VAR ref: Item)
NEW
Разыменовывает указатель ptr и присваивает результат ref.

Предусловие
ptr.typ = ptrTyp	21
ref должно быть записью уровня 1	25
ref может иметь только одно поле	26

PROCEDURE (VAR arr: Item) Index (index: INTEGER; VAR elem: Item)
NEW
Присваивает elem элемент index массива arr.

Предусловие
arr.Valid()	20
arr.typ = arrTyp	21
arr.obj = varObj	22

PROCEDURE (VAR proc: Item) Call (OUT ok: BOOLEAN)
NEW
Вызывает процедуру без параметров.

Предусловие
proc.Valid()	20
proc.obj = procObj  OR  proc.obj = varObj & proc.typ = procTyp	21

PROCEDURE (VAR var: Item) GetVal (VAR x: Value; OUT ok: BOOLEAN)
NEW

PROCEDURE (VAR var: Item) PutVal (IN x: Value; OUT ok: BOOLEAN)
NEW

PROCEDURE (VAR var: Item) GetStringVal (OUT x: ARRAY OF CHAR; OUT ok: BOOLEAN)
NEW

PROCEDURE (VAR var: Item) GetSStringVal (OUT x: ARRAY OF SHORTCHAR; OUT ok: BOOLEAN)
NEW

PROCEDURE (VAR var: Item) PtrVal (): ANYPTR
NEW

PROCEDURE (VAR var: Item) PutPtrVal (x: ANYPTR)
NEW

PROCEDURE (VAR var: Item) IntVal (): INTEGER
NEW

PROCEDURE (VAR var: Item) PutIntVal (x: INTEGER)
NEW

PROCEDURE (VAR var: Item) RealVal (): REAL
NEW

PROCEDURE (VAR var: Item) PutRealVal (x: REAL)
NEW

PROCEDURE (VAR var: Item) LongVal (): LONGINT
NEW

PROCEDURE (VAR var: Item) PutLongVal (x: LONGINT)
NEW

PROCEDURE (VAR var: Item) CharVal (): CHAR
NEW

PROCEDURE (VAR var: Item) PutCharVal (x: CHAR)
NEW

PROCEDURE (VAR var: Item) BoolVal (): BOOLEAN
NEW

PROCEDURE (VAR var: Item) PutBoolVal (x: BOOLEAN)
NEW

PROCEDURE (VAR var: Item) SetVal (): SET
NEW

PROCEDURE (VAR var: Item) PutSetVal (x: SET)
NEW

PROCEDURE (VAR type: Item) New (): ANYPTR
NEW
Создает новый пустой объект в куче. Элемент должен быть записью или указателем. Тип нового объекта такой же, как указатель, или указатель на запись, описанный элементом.

PROCEDURE (VAR val: Item) Copy (): ANYPTR
NEW
То же, что и New, но при этом побайтно копирует содержимое.

PROCEDURE (VAR rec: Item) CallWith (proc: PROCEDURE (VAR rec, par: ANYREC); VAR par: ANYREC)
NEW
Вызывает процедуру proc с параметрами rec (то есть, самим элементом, параметр "self") и параметром par.


TYPE Scanner
Сканер позволяет перебрать все модули, все элементы в модуле или все поля в записи.

this-: Item
Результат самой последней операции Scan.

eos-: BOOLEAN
Этот флаг указывает, что последняя операция Scan попыталась читать после последнего элемента.

PROCEDURE (VAR s: Scanner) ConnectToMods
NEW
Каждый вызов s.Scan будет возвращать другой модуль.

Постусловие
s.this.obj = undef
~s.eos

PROCEDURE (VAR s: Scanner) ConnectTo (IN obj: Item)
NEW
Подключает сканер к конкретному модулю или записи.

Предусловие
obj.Valid()	20
obj.obj = modObj  OR  obj.typ = recTyp	21

PROCEDURE (VAR s: Scanner) Scan
Считывает новый элемент. Результат помещается в s.this. Если произошла попытка считывания после последнего элемента, устанавливается s.eos, в противном случае он очищается.

Предусловие
s подключен	20

PROCEDURE (VAR s: Scanner) GetObjName (OUT name: Name)
NEW
Возвращет имя последнего прочитанного элемента.

Предусловие
s.this.Valid()	20

PROCEDURE (VAR s: Scanner) Level (): INTEGER
NEW
Возвращает уровень расширения считанной записи.

Предусловие
s.this.Valid()	20
s присоединен к переменной записи	22


TYPE LookupFilter = PROCEDURE (IN path: ARRAY OF CHAR; OUT i: Item; OUT done: BOOLEAN)
Тип используется для обработки расширений, которые, например, позволяют Meta работать дистанционно.


PROCEDURE Lookup (IN name: ARRAY OF CHAR; OUT mod: Item)
Ищет модуль. 

Постусловие
mod.obj = modObject
	поиск прошел успешно
mod.obj = undef
	поиск потерпел неудачу

PROCEDURE LookupPath (IN path: ARRAY OF CHAR; OUT i: Item)
Ищет элемент через полный описатель, начинающийся с имени модуля.

PROCEDURE GetItem (obj: ANYPTR; OUT i: Item)
Создает элемент из указателя на переменную.

PROCEDURE GetThisItem (IN attr: ANYREC; OUT i: Item)
Используется внутренне для обработки расширений (создает элемент из переменной записи). Используйте вместо этого Lookup, LookupPath или GetItem.

PROCEDURE InstallFilter (filter: LookupFilter)
Устанавливает обработчик расширений.