comp.lang.ada
 help / color / mirror / Atom feed
* Generic Instances Scope control  ???
@ 2000-02-22  0:00 Vladimir Olensky
  2000-02-22  0:00 ` Ray Blaak
  0 siblings, 1 reply; 4+ messages in thread
From: Vladimir Olensky @ 2000-02-22  0:00 UTC (permalink / raw)


I encountered a problem that need control over scope
and accessibility depth for instance of generic procedure.

-------------------------------------
There is some object controller.
It can use some OS asynchronous operation.
The last one upon it's completion  calls controller provided
completion procedure and pass it  OS async operation
return code. This return code should be used  to update
controller async status field so that  it could be queried by the
controller client to see the status of  async operation.

OS callback procedure signature does not contain
information about which object it should update,
so to bind that procedure to the particular controller
one need to use generic procedure with  updated
object  as generic formal object .

At the end of the message is a  working example
(GNAT specific) that does all that.

The problem is that I want to hide instantiation of generic
callback procedure and its registration to controller from
client of that controller  but I can not do that now.
Instance of generic callback procedure and pointer to it
should have  the same scope and accessibility level as
controller instance.
So I can not create callback procedure instance and
bind it to the controller in any inner scope (let's say
in Ada.Finalization.Initialize procedure).
As a result of that this operations should be performed
by the client in spite that all that could be performed
automatically (theoretically).

If there would be something (e.g. Scope Attribute or  some
compiler pragma) that tell compiler that code for the instance
of generic procedure declared in some inner scope should
have some defined outer scope (and life span) that would
solve that problem.

Something like this:
      for proc_name'Scope use  concrete_object'Scope;

The other part of the problem in automatic  generic
procedure  instantiation is ability to dynamically set or
extend name for such procedure instance to avoid name
clashes between several controller instances.

May be there are ways to do all that now and I just do not
know them ?

Regards,
Vladimir Olensky

Here is an working example with some
public declarations that I want to hide from
package clients:
-- =================================

with Ada.Finalization; use Ada.Finalization;

package G is

   type Callback_Proc_Ptr is
        access procedure (ret_code : Integer);
   -- OS signature for callback procedure
   -- which is called upon completion of
   -- OS asyncronous operation
   -- This pointer will be passes as parameter
   -- to some OS API call.
   -- When OS call that procedure it should
   -- update status_code field of
   -- the Controller_Type instance.
   -- The problem is that this procedure does
   -- not know anything about controller
   -- which field it should update

   type Controller_Type is new Limited_Controlled with
      record
         status_code   : Integer :=0;
         callback_proc : Callback_Proc_Ptr := null;
      end record;

   procedure Register_Callback (
              C   : in out Controller_Type;
              CBP : in     Callback_Proc_Ptr);

   -- To bind OS callback routine to the
   -- particular Controller instance
   -- we declare generic procedure with
   -- Controller as a formal generic
   -- parameter
   generic
      Controller : in out Controller_Type;
   procedure GStat (OS_Ret_Code : Integer);

end G;
---------------------------------------
package body G is

   procedure Register_Callback (
      C   : in out Controller_Type;
      CBP : in     Callback_Proc_Ptr) is
   begin
      C.callback_proc := CBP;
   end Register_Callback;

   procedure GStat (OS_ret_code : Integer) is
   begin
      Controller.Status_Code := OS_ret_code;
   end GStat;

end G;

------------------------------

with G; use G;
with Gnat.IO; use GNAT.IO;
procedure tst_Gen is

   c1 :  Controller_Type;
   procedure c1_stat is new GStat (Controller => c1);
    --> want to hide c1_stat from client

   c2 :  Controller_Type;
   procedure c2_stat is new GStat (Controller => c2);
    --> want to hide c2_stat from client

   procedure OS_API_Emulation

      command : integer;
      callback_proc : Callback_Proc_Ptr )
   is
   begin
      callback_proc (command+10);
   end OS_API_Emulation;

begin

   Register_Callback (c1, c1_stat'Unrestricted_Access);
   Register_Callback (c2, c2_stat'Unrestricted_Access);
    -->  want to hide Register_Callback  from client

   -- Controller 1 is calling OS API
   OS_API_Emulation (
      command => 1,
      callback_proc => c1.callback_proc );

   -- Controller 2 is calling OS API
   OS_API_Emulation (
      command => 2,
      callback_proc => c2.callback_proc );


   Put ( c1.status_code);  -- prints 11
   New_Line;
   Put ( c2.status_code);  -- prints 12

end;









^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Generic Instances Scope control  ???
  2000-02-22  0:00 Generic Instances Scope control ??? Vladimir Olensky
@ 2000-02-22  0:00 ` Ray Blaak
  2000-02-23  0:00   ` Vladimir Olensky
  0 siblings, 1 reply; 4+ messages in thread
From: Ray Blaak @ 2000-02-22  0:00 UTC (permalink / raw)


"Vladimir Olensky" <vladimir_olensky@yahoo.com> writes:
> procedure tst_Gen is
> 
>    c1 :  Controller_Type;
>    procedure c1_stat is new GStat (Controller => c1);
>     --> want to hide c1_stat from client
[...]
> begin
> 
>    Register_Callback (c1, c1_stat'Unrestricted_Access);
>     -->  want to hide Register_Callback  from client
[...]

Just do the instantiation and registeration in another package; no scope
operator is needed:

  with G; use G;
  generic
      Controller : in out Controller_Type;
  package Register_GStat is
  end Register_GStat

  package body Register_GStat is
      procedure Stat is new GStat (Controller => Controller);
  begin
      Register_Callback (Controller, Stat'Unrestricted_Access);
  end Register_GStat;

and then:

 procedure tst_Gen is
    c1 :  Controller_Type;
    package c1_stat is new Register_GStat (Controller => c1);
 begin
    -- Register_Callback is already called by this point.
    ...
 end test_Gen;

-- 
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
blaak@infomatch.com                            The Rhythm has my soul.




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Generic Instances Scope control  ???
  2000-02-22  0:00 ` Ray Blaak
@ 2000-02-23  0:00   ` Vladimir Olensky
  2000-02-23  0:00     ` Ray Blaak
  0 siblings, 1 reply; 4+ messages in thread
From: Vladimir Olensky @ 2000-02-23  0:00 UTC (permalink / raw)


   Though what you suggest  simplifies the initial problem
( reducing the number of visible details to only one)  but it
does not solve the essence of the problem.  Client still
need to make one generic package instance per each
declared controller object.

The point is to hide all that completely from the client.

   Client should not know anything except that he should
declare  controller object to be able to work with it.

  Everything should be done automatically by object constructor
which in our case is  Ada.Finalization.Initialize procedure and
have a life span until Finalize procedure is called.

Regards,
Vladimir Olensky

=================================

Ray Blaak wrote in message ...
>"Vladimir Olensky" <vladimir_olensky@yahoo.com> writes:
>> procedure tst_Gen is
>>
>>    c1 :  Controller_Type;
>>    procedure c1_stat is new GStat (Controller => c1);
>>     --> want to hide c1_stat from client
>[...]
>> begin
>>
>>    Register_Callback (c1, c1_stat'Unrestricted_Access);
>>     -->  want to hide Register_Callback  from client
>[...]
>
>Just do the instantiation and registeration in another package; no scope
>operator is needed:
>
>  with G; use G;
>  generic
>      Controller : in out Controller_Type;
>  package Register_GStat is
>  end Register_GStat
>
>  package body Register_GStat is
>      procedure Stat is new GStat (Controller => Controller);
>  begin
>      Register_Callback (Controller, Stat'Unrestricted_Access);
>  end Register_GStat;
>
>and then:
>
> procedure tst_Gen is
>    c1 :  Controller_Type;
>    package c1_stat is new Register_GStat (Controller => c1);

----> Want  c1_stat  to be hidden  - initial problem still exists

> begin
>    -- Register_Callback is already called by this point.
>    ...
> end test_Gen;













^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Generic Instances Scope control  ???
  2000-02-23  0:00   ` Vladimir Olensky
@ 2000-02-23  0:00     ` Ray Blaak
  0 siblings, 0 replies; 4+ messages in thread
From: Ray Blaak @ 2000-02-23  0:00 UTC (permalink / raw)


"Vladimir Olensky" <vladimir_olensky@yahoo.com> writes:
>    Though what you suggest  simplifies the initial problem
> ( reducing the number of visible details to only one)  but it
> does not solve the essence of the problem.  Client still
> need to make one generic package instance per each
> declared controller object.
> 
> The point is to hide all that completely from the client.

Your real problem is the need to associate the controller object with the
specific API call. Having a different routine for each object is not really
what is desired, since one needs to associate the specific controller with a
specific routine (which is why you were doing the generic instantiations).

Most languages, however, cannot do this, so most (all?) asynchronous
environments provide some sort of handle/context mechanism so that you can
associate completions with their initial invocations.  Otherwise one cannot
know which completions match to which calls.

The OS interface really needs to allow you to give the controller (or a
pointer to it) as part of the call, so that it can be used as data during the
callback. 

Once you have this, then Controller_Type does not even need to inherit from
Limited_Controlled at all, or even a tagged type, but can be a simple record.

-- 
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
blaak@infomatch.com                            The Rhythm has my soul.




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2000-02-23  0:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-02-22  0:00 Generic Instances Scope control ??? Vladimir Olensky
2000-02-22  0:00 ` Ray Blaak
2000-02-23  0:00   ` Vladimir Olensky
2000-02-23  0:00     ` Ray Blaak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox