Пётр Кушнир писал(а):
Обертки не всегда наследники. Сообщения проходят, а типы предков могут не совпадать.
Спасибо! Вроде понял. Написал пример для понятности.
Код:
MODULE DemoWrapper;
IMPORT Log, Views, Properties, Ports, Stores, Services;
TYPE
View = POINTER TO ABSTRACT RECORD (Views.View) END;
StdView = POINTER TO RECORD (View) END;
StdViewWrapper = POINTER TO RECORD (Views.View) inner: StdView; END;
PROCEDURE (v: StdView) Restore (f: Views.Frame; l, t, r, b: INTEGER);
BEGIN f.DrawRect(l, t, r, b, Ports.fill, Ports.red)
END Restore;
PROCEDURE (v: StdViewWrapper) Restore (f: Views.Frame; l, t, r, b: INTEGER);
BEGIN Views.InstallFrame(f, v.inner, 0, 100 * f.dot, 0, TRUE)
END Restore;
PROCEDURE (v: StdView) HandlePropMsg (VAR msg: Properties.Message);
BEGIN
WITH msg: Properties.Preference DO
WITH msg: Properties.TypePref DO
IF Services.Is(v, msg.type) THEN msg.view := v END
ELSE END
ELSE END
END HandlePropMsg;
PROCEDURE (v: StdViewWrapper) HandlePropMsg (VAR msg: Properties.Message);
BEGIN Views.HandlePropMsg(v.inner, msg)
END HandlePropMsg;
PROCEDURE New(): View;
VAR v: StdView;
BEGIN NEW(v); RETURN v
END New;
PROCEDURE Wrap(inner: View): StdViewWrapper;
VAR v: StdViewWrapper;
BEGIN
NEW(v);
WITH inner: StdView DO
v.inner := inner;
Stores.Join(v, v.inner);
RETURN v
ELSE RETURN NIL END
END Wrap;
PROCEDURE Do*;
VAR v1: View; v2: StdViewWrapper;
BEGIN
v1 := New();
v2 := Wrap(v1);
IF Properties.ThisType(v1, "DemoWrapper.StdView") # NIL THEN
Log.Bool(v1 IS StdView); Log.Ln;
END;
IF Properties.ThisType(v2, "DemoWrapper.StdView") # NIL THEN
Log.Bool(TRUE); Log.Ln;
END;
END Do;
END DemoWrapper.
DemoWrapper.Do