OberonCore https://forum.oberoncore.ru/ |
|
Пример использования абстрактных типов с Meta https://forum.oberoncore.ru/viewtopic.php?f=35&t=3005 |
Страница 1 из 1 |
Автор: | Иван Денисов [ Четверг, 18 Ноябрь, 2010 16:23 ] |
Заголовок сообщения: | Пример использования абстрактных типов с Meta |
При разборе пакета SQL наконец внятно понял, зачем нужны абстрактные типы и Meta Родился один пример, чтобы проверить, как такое безобразие уживается в dll. Подумал, что это может оказаться полезным тем, кто хочет разобраться с использованием абстрактных типов. Вначале мы абстрактно описываем некоторый процесс, например есть объект содержащий вектор, есть функция вычисления длины. Вот и все. А реализовать это можно разными способами и реализации легко менять в BB. Объект не зря называется Driver, поскольку такой подход удобен в случае, например, общения с базой данных. Код: MODULE MyDriver; IMPORT Meta; TYPE Driver* = POINTER TO ABSTRACT RECORD x*, y*: REAL; END; Realisation = PROCEDURE (OUT d: Driver); PROCEDURE (d: Driver) Len* (): REAL, NEW, ABSTRACT; PROCEDURE (d: Driver) Values* (x, y: REAL), NEW, ABSTRACT; PROCEDURE Load* (realisation: ARRAY OF CHAR; OUT d: Driver; OUT res: INTEGER); VAR item: Meta.Item; mod: Meta.Name; ok, a: BOOLEAN; t: INTEGER; v: RECORD (Meta.Value) Load: Realisation END; BEGIN mod := realisation$; Meta.Lookup(mod, item); d := NIL; res := 0; IF item.obj = Meta.modObj THEN item.Lookup("Load", item); IF item.obj = Meta.procObj THEN item.GetVal(v, ok); IF ok THEN v.Load(d); res := 0 ELSE res := 3 END ELSE res := 2 END ELSE res := 1 END END Load; END MyDriver. Затем описываем первую реализацию драйвера. Код: MODULE MyRealisation; IMPORT Math, MyDriver; TYPE Driver = POINTER TO RECORD (MyDriver.Driver) END; PROCEDURE (d: Driver) Len* (): REAL; BEGIN RETURN Math.Sqrt(Math.IntPower(d.x, 2) + Math.IntPower(d.y, 2)) END Len; PROCEDURE (d: Driver) Values* (x, y: REAL); BEGIN d.x := x; d.y := y; END Values; PROCEDURE Load* (OUT d: MyDriver.Driver); VAR i: INTEGER; h: Driver; BEGIN NEW(h); d := h; END Load; END MyRealisation. И вторую реализацию. Код: MODULE MyRealisation2; IMPORT Math, MyDriver; TYPE Driver = POINTER TO RECORD (MyDriver.Driver) END; PROCEDURE (d: Driver) Len* (): REAL; BEGIN RETURN Math.Sqrt(d.x*d.x + d.y*d.y) END Len; PROCEDURE (d: Driver) Values* (x, y :REAL); BEGIN d.x := x; d.y := y; END Values; PROCEDURE Load*(OUT d: MyDriver.Driver); VAR i: INTEGER; h: Driver; BEGIN NEW(h); d := h; END Load; END MyRealisation2. Ну и наконец — использование. Код: MODULE MyUsage; IMPORT MyDriver, Out:=StdLog; PROCEDURE Test*(); VAR d1, d2: MyDriver.Driver; res1, res2: INTEGER; BEGIN MyDriver.Load("MyRealisation", d1, res1); MyDriver.Load("MyRealisation2", d2, res2); IF (res1 = 0) & (res2 = 0) THEN d1.Values(12, 10); d2.Values(12, 10); Out.Real(d1.Len() + d2.Len()) ELSE Out.String("Error") END END test; END MyUsage. Я все это делал, чтобы проверить, как такая функция будет работать в dll и что указывать при компиляции библиотеки, получается надо просто указывать обе реализации. Вроде работает. Если вместо Out сделать RETURN. ^Q DevLinker.LinkDll test.dll := Kernel+ Math Meta MyDriver MyRealisation MyRealisation2 MyUsage # ~ |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |