File: gps-scripts.ads

package info (click to toggle)
gnat-gps 18-5
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 45,716 kB
  • sloc: ada: 362,679; python: 31,031; xml: 9,597; makefile: 1,030; ansic: 917; sh: 264; java: 17
file content (184 lines) | stat: -rw-r--r-- 8,866 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
------------------------------------------------------------------------------
--                                  G P S                                   --
--                                                                          --
--                        Copyright (C) 2013-2018, AdaCore                  --
--                                                                          --
-- This is free software;  you can redistribute it  and/or modify it  under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  This software is distributed in the hope  that it will be useful, --
-- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- --
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
-- License for  more details.  You should have  received  a copy of the GNU --
-- General  Public  License  distributed  with  this  software;   see  file --
-- COPYING3.  If not, go to http://www.gnu.org/licenses for a complete copy --
-- of the license.                                                          --
------------------------------------------------------------------------------
--  Base package for GPS scripting (GUI independent)

with GNATCOLL.Scripts;   use GNATCOLL.Scripts;
with GPS.Core_Kernels;   use GPS.Core_Kernels;

package GPS.Scripts is

   type Kernel_Scripts_Repository is
     new GNATCOLL.Scripts.Scripts_Repository_Record with private;
   --  Script repository with kernel pointer inside

   function Create
     (Kernel : GPS.Core_Kernels.Core_Kernel) return Kernel_Scripts_Repository;

   function Get_Kernel (Data : GNATCOLL.Scripts.Callback_Data'Class)
      return GPS.Core_Kernels.Core_Kernel;
   --  Return the kernel associated with Data

   function Get_Kernel
     (Script : access GNATCOLL.Scripts.Scripting_Language_Record'Class)
      return GPS.Core_Kernels.Core_Kernel;
   --  Return the kernel associated with Script

   ------------------
   -- Script_Proxy --
   ------------------

   type Script_Proxy is abstract tagged record
      Instances : Instance_List;
   end record;
   --  A type that should be used in types that are exported to python.
   --  They provide the following support:
   --  * Creating a new python class instance to wrap an Ada object of this
   --    type.
   --  * Ensure that one given Ada object is always represented by the
   --    same python instance. This allows python users to store their own
   --    custom data, and be able to get it every time the same Ada instance
   --    is manipulated.
   --  * Ensure that the python instances exist at least as long as the Ada
   --    object exists.
   --  * Ensures that once the Ada object is destroyed, any remaining python
   --    instance no longer references it anymore. Instead, its internal
   --    data is reset to a default value. From then on, acting on the
   --    python object will no longer make sense, but will not crash the
   --    application either.
   --  * Support multiple scripting languages (one instance of class per
   --    scripting language and per Ada object).

   function Class_Name (Self : Script_Proxy) return String is abstract;
   pragma Inline (Class_Name);
   --  Class_Name is the name in the scripting language. This is also used for
   --  the name of the internal field in the python class that stores
   --  the Ada object. This way, it is possible to have a python class
   --  store reference to multiple types of Ada objects, if they use
   --  different names.
   --
   --  Implementation:
   --  We could have set this as a discriminant of the type, but then this
   --  is not accessible from the generic package below for some reason. This
   --  class name must be known by Finalize to properly free the memory.

   procedure Free (Self : in out Script_Proxy);
   --  Severe the links between class instances stored in Self, and the
   --  Ada object.
   --  This will possibly destroy the instances, or if they are currently
   --  in use in the scripting language, it will simply ensure that the
   --  instances reference a null element.
   --
   --  Implementation:
   --  We could make Script_Proxy a controlled type so that the memory is
   --  freed automatically. The difficulty however is that this type will
   --  be part of a record that it passed to the generic package below, so
   --  Finalize is called every time From_Instance is called.

   type Instances_Status is (Has_Instances, Has_No_Instances);

   No_Data_Set_For_Instance : exception;

   generic
      type Element_Type is private;
      --  Data stored in the python class instance. This type is the one
      --  that includes a Script_Proxy field.
      --  Element_Type must not be a reference counted type, since otherwise
      --  there is a refcount cycle: Element_Type owns a Script_Proxy, that
      --  contains python class instances that own the Element_Type. In this
      --  case, use a Weak reference as the Element_Type.

      type Proxy is new Script_Proxy with private;
      --  Used to get access to the class name.

      with procedure Free (E : in out Element_Type) is null;
      --  After using Transfer_Ownership:
      --  this subprogram is called when the last instance associated with
      --  the element is destroyed.
      --  This procedure is never called if you did not use Transfer_Ownership
      --  since otherwise the script instances are owned by the element, and
      --  thus the instances can only be destroyed when the element itself has
      --  already been freed.

   package Script_Proxies is

      function Get_Or_Create_Instance
         (Self   : in out Proxy'Class;
          Obj    : Element_Type;
          Script : not null access Scripting_Language_Record'Class;
          Class_To_Create : String := "")
         return Class_Instance;
      --  If Obj was already associated with a class instance in the given
      --  scripting language, returns that same instance.
      --  Otherwise, create a new instance to wrap Obj.
      --  Self should be stored in Obj, but we need to pass it explicitly
      --  since we do not have access to it from this generic package.
      --  Class_To_Create can be used to override the name of the class that
      --  we are creating, when there are various children classes possible

      procedure Store_In_Instance
         (Self   : in out Proxy'Class;
          Inst   : Class_Instance;
          Obj    : Element_Type);
      --  Associate Inst with Obj.
      --  This procedure is only needed when the instance was created
      --  independently, for instance when implementing a Constructor_Method
      --  in Ada. Otherwise, better to use Get_Or_Create_Instance.

      function Has_Element (Inst : Class_Instance) return Boolean;
      --  Whether there is an element associated with Inst.

      function From_Instance (Inst : Class_Instance) return Element_Type;
      --  Return the element stored in the instance.
      --  This will raise No_Data_Set_For_Instance if no element was associated
      --  with this instance or if Inst is No_Class_Instance.

      generic
         with function Detach (E : Element_Type) return Element_Type;
         --  Return a new version of E, which does not own any script
         --  instance. E will be freed (with Free above).
      function Transfer_Ownership
         (Self : in out Proxy'Class) return Instances_Status;
      --  This procedure is used to change the ownership of data. After
      --  calling this procedure, the following is true:
      --  * Self is no longer referencing any instance.
      --  * script instances still exist if they are used by a script. If
      --    their last reference was in Self, they are destroyed.
      --  * they now reference some new data (created by calling Detach).
      --    This data should not own a reference to the script instances
      --    (so their Proxy field should be left unset).
      --    Detach is called exacty once if there is at least one script
      --    instance, and never otherwise.
      --  * when the script instances are destroyed eventually, the new
      --    data will be freed automatically.
      --
      --  This procedure can be used when some Data is no longer required on
      --  the Ada side, but existing script instances still need to access it
      --  to extract some information. For instance, we use this for Commands,
      --  so that scripts can access the output of the command even after the
      --  command has finished executing.

   end Script_Proxies;

private

   type Kernel_Scripts_Repository is
     new GNATCOLL.Scripts.Scripts_Repository_Record
   with record
      Kernel : GPS.Core_Kernels.Core_Kernel;
   end record;

end GPS.Scripts;