Oberon || Library || Module Index || Search Engine || Definition || Module
TYPE CreateProxyProc = PROCEDURE (VAR object: Services.Object; orig: Services.Object); TYPE InitProxyProc = PROCEDURE (object: Services.Object; orig: Services.Object); TYPE Interface = POINTER TO InterfaceRec; TYPE InterfaceRec = RECORD (Objects.ObjectRec) createProxy: CreateProxyProc; initProxy: InitProxyProc; END;
PROCEDURE Register(type: Services.Type; if: Interface); PROCEDURE Supported(type: Services.Type) : BOOLEAN; PROCEDURE GetSupportedBaseType(type: Services.Type; VAR baseType: Services.Type);
PROCEDURE CreateProxy(VAR proxy: Services.Object; orig: Services.Object);
PROCEDURE CreateUninitializedProxy(VAR proxy: Services.Object; orig: Services.Object); PROCEDURE InitializeAllInterfacesUpTo(proxy: Services.Object; type: Services.Type); PROCEDURE InitializeAllInterfacesBeyond(proxy: Services.Object; type: Services.Type);
PROCEDURE GetOrig(proxy: Services.Object; VAR orig: Services.Object);
Assume a base type T, an extension of T named T1, which itself has been extended by T2. All of them come with their own set of operations. A proxy implementation for T1 is obviously aware of the operations of T. Hence, it can implement easily all delegating operations for T and T1. However, it cannot foresee the extension T2. Proxies allows proxy implementations to focus on just one abstraction layer (e.g. that of T1), assuming that another proxy module takes care of the base type (e.g. T) and other modules of the possible extensions (e.g. T2). Each proxy module has to provide two interface procedures to Register:
Assume we have proxy modules ProxyT, ProxyT1, and ProxyT2. Then let us have a FilterT1 module that somehow filters all operations on T1 objects at the layer of T1 (not touching the operations at the T layer). Now, FilterT1 just needs to take care of the T1 operations. If the original object is an extension of T2, ProxyT and ProxyT2 will do the rest. ProxyT1 will be left out as this part is taken by FilterT1.
Note that none of the proxy modules can rely on an own static type extension even if they may have to create objects through the createProxy interface procedure. However, their delegating implementations have to work for anything that extends the type they are associated with. Hence, they will have to be based on disciplines (see Disciplines) instead of static type extensions if they need some bookkeeping. The link to the original target object does not need to be maintained, however, as GetOrig allows to retrieve it.
Supported tells if a given type has proxy support and GetSupportedBaseType returns the associated base type. Assume in the example above that the abstraction T2 is implemented by an extension T3. Then, if ProxyT, ProxyT1, and ProxyT2 registered themselves for T, T1, and T2, respectively, Supported would return TRUE for T3 and GetSupportedBaseType would return T2.
CreateProxy creates a proxy object proxy that delegates all operations to orig. Note that this creates a pure proxy object. None of the supported operations of the primary abstractions are filtered or changed in any way. The relation of proxy to orig is registered to Forwarders.
A filtering module that filters operations at some abstraction layer needs the initializations for all abstraction layers by the regular proxy modules but its own layer. This can be done by starting with CreateUninitializedProxy which returns a proxy object that has been created by the createProxy interface procedure of the most-extended proxy module. In the second step, all interfaces have to be initialized that are more basic than our abstraction layer using InitializeAllInterfacesUpTo which initializes all layers up to that of type which is included. In the third step, the initialization on the own abstraction layer has to be performed. Finally, InitializeAllInterfacesBeyond has to be invoked to initialize all interfaces for the extensions of type (excluding type). InitializeAllInterfacesBeyond also registers the relationship between proxy and orig to Forwarders.
GetOrig returns the original target object proxy is linked to.
Oberon || Library || Module Index || Search Engine || Definition || Module