I'm trying to implement an Observer pattern using OOP and dynamic dispatching, but I'm not able to create an access-to-subprogram constant because the argument types of the named access and the procedure of the type extension don't match.
I provide a minimal reproducibable example, ommiting subscription:
package Alarms is
type time_t is mod 2**32;
type AlarmObserver_t is interface;
type Callback_t is access procedure (this : in out AlarmObserver_t);
type AlarmPublisher_t (<>) is tagged limited private;
function fConstructor (capacity : in Positive) return AlarmPublisher_t;
private
type AlarObserverAcc_t is access AlarmObserver_t'Class;
type dummy_t is new AlarmObserver_t with null record;
procedure pEventDummy (this : in out dummy_t) is Null;
dummy : constant AlarObserverAcc_t := new dummy_t;
dummyCallback : constant Callback_t := pEventDummy'Access; --Fails
type Node_t is limited
record
Observer : AlarObserverAcc_t := dummy;
Callback : Callback_t := dummyCallback;
time : time_t := time_t'Last;
end record;
defaultNode : constant Node_t := Node_t' (Observer => dummy,
Callback => dummyCallback,
time => time_t'Last);
type ObserverArray_t is array (Positive range <>) of Node_t;
type AlarmPublisher_t (capacity : Positive) is tagged limited
record
--Member "observers" has default initialisation because Node_t is initialised
observers : ObserverArray_t (Positive'First .. capacity);
end record;
end Alarms;
And the implementation to let you reproduce it:
package body Alarms is
function fConstructor (capacity : in Positive) return AlarmPublisher_t is
begin
return Obj : AlarmPublisher_t (capacity => capacity) do
Null;
end return;
end fConstructor;
end Alarms;
I was inspiring in Matthew Heaney callbacks Observer pattern
He use a class-wide argument for the access-to-subprogram procedure, but I would like to use OOP notation and let the concrete observers to have those procedures as primitives.
Why procedure pEventDummy is not compatible if dummy_t implements AlarmObserver_t interface? Can I do what I want?
Aucun commentaire:
Enregistrer un commentaire