TEAM-ADA Archives

Team Ada: Ada Programming Language Advocacy


Options: Use Forum View

Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Corey Minyard <[log in to unmask]>
Reply To:
Corey Minyard <[log in to unmask]>
Tue, 21 May 2002 09:22:01 -0500
text/plain (81 lines)
Maxim Reznik wrote:

> Randy Brukardt wrote:
> [skip]
>> But the *really* best solution is an OOP-based solution. This is
>> extensible
>> and type-safe and doesn't require unsafe compares and doesn't even need
>> (visible) access types. Admittedly, there is a bit more work up
>> front, but I
>> think access types should avoided unless there is really dynamic
>> allocation
>> (which can't happen with subprograms in Ada). One of the really nice
>> things
>> about Ada 95 is that you can do useful OOP without using any access
>> types.
>>               Randy Brukardt.
> Could you explain please how to avoid visible access type?
> I tought we should write something like
> package Subscriber is
>    type Listener is abstract tagged null record;
>    procedure Action (L : Listener) is abstract;
>    type Listener_Ptr is access all Listener'Class;
>    procedure Register (P : Listener_Ptr);
>    procedure Unregister (P : Listener_Ptr);
> end Subscriber;
> Maxim Reznik

I think he means that you can add data in the Listener record and it
wouldn't be visible.  In this example, I'd also recommend having a class
to register it against to allow multiple instances.  Generally you will
have the class to register that class against naturally, anyway, since
you will have some other type that is generating the events to register
against.  So if you needed a simple list (not that I'm recommending this
technique necessarily, this is just an example) and a call counter, you
could have:

package Subscriber is

   type Listener is abstract tagged private;
   procedure Action (L : Listener) is abstract;

   type Listener_Class is access all Listener'Class;

    type Event_Generator is abstract tagged private;
    type Event_Generator_Class is access all Event_Generator'Class;

   procedure Register (G : in out Event_Generator; P : Listener_Class);
   procedure Unregister (G : in out Event_Generator; P : Listener_Class);

    -- Sometimes singletons are handy if you just have one of something,
but you want to
    -- plan for being able to have more than one later.
   Event_Generator_Singleton : Event_Generator_Class;


    type Listener is abstract tagged record
        Next : Listener_Ptr; -- Used to form a linked list.
        Calls : Natural := 0; -- Number of times the action has been called.
    end record;

    type Event_Generator is abstract tagged record
        Action_List : Listener_Ptr;
    end record;

end Subscriber;