File: intermodule_communication.rst

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 (105 lines) | stat: -rw-r--r-- 5,277 bytes parent folder | download | duplicates (3)
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
*************************
Intermodule communication
*************************

As described above, GPS is organized into largely independent
modules. For instance, the various views, browsers, help, vcs
support,... are separate modules, that can either be loaded at startup
or not.

When they are not loaded, the correspondings features and menus are not
available to the user.

These modules need to communicate with each other so as to provide the
best possible integration between the tools. There currently exists a
number of ways to send information from one module to
another. However, some of these technics depend on Ada-specific types,
and thus makes it harder to write modules in different languages like
C or Python.

The following communication technics are currently provided:

* Direct calls
  A module can explicitly specify that it depends on another one. This
  is done by changing the project file, and adding the necessary "with"
  statements in the code.  This technics is highly not recommended, and
  should never be used when one of the other technics would do the job,
  since it defeats the module independency.  The only place it is
  currently used at is for direct calls to the Register_* commands.
  Most of the time, these Register_* subprograms are also available through
  XML customization files, and thus limit the direct dependencies between
  modules, while providing greated extensibility to the final user.

* Shell calls
  Each module can register new shell commands for the interactive shell
  window.  Any other module can call these commands. There is no direct
  dependency on the code, although this means that the module that
  provide the command must be loaded before the other module.  This
  technics is used for instance for the codefix module, that needs a
  high degree of integration with the source editor module. It will also
  be used for communicating with Emacs.

* Addition to contextual menus
  A module is free to add entries to the main menu bar or to any
  contextual menus within GPS.

  Most of the time, a module will decide to add new entries depending on
  what the contextual menu applies to (the current context), although it
  might also decide to do that based on what module is displaying the
  contextual menu. Modules are identified by their name, which can
  easily be tested by other menus.

* Context changes
  Every time a new MDI child is selected, or when a module chooses to
  emit such a signal, a context change is reported via a gtk+ signal. A
  context is an Ada tagged type, created by the currently active
  module. There exists different kinds of contexts, some for files
  (directories and project), others for entities (same as before, but
  with an entity name in addition, other for a location (adding line and
  column),...  New types of contexts can be created by the modules
  without impacting the rest of GPS. All callbacks must test that the
  context they receive matches what they can handle.

  These contexts are also used for the contextual menus

  A module can choose to emit the signal to report changes to its
  context by emitting the signal. Other modules can they update their
  content accordingly. This is how the switches editor updates the
  project/directory/file it is showing when a new selection is done in
  the project view.

* hooks and action hooks
  Hooks are similar to the usual gtk+ signals.
  Each hook is a named collection of subprograms to be called when the hook is
  executed. Such hooks are executed by various parts of GPS when some actions
  take place, like reloading the project, loading a file,...

  These are the most powerful way for a module to react to actions taking place
  in other parts of GPS, and to act appropriately.

  In most cases, all the subprograms in a hook are executed in turn, and thus
  they all get a chance to act.

  However, in some other cases, the subprograms are only executed until one of
  them indicates that it has accomplished a useful action, and that no other
  subprogram from this hook should be called. These are called **action hooks**.
  This is the fundamental mechanism used by GPS to request for instance the
  edition of a file: the module that wishes to display a file executes the
  hook "open_file_action_hook" with the appropriate argument. At this point, all
  subprograms bound to this hook are executed, until one of them acknowledge that
  it knows how to edit this file (and hopefully opens an editor). Then no other
  subprogram from this hook is called, so that the file is not open multiple
  times.

  This mechanism is used for instance by the module that handles the external
  editors. It is setup so that it binds to the "open_file_action_hook" hook. Any
  time a file needs to be open, the callback from this module is called first.
  If the user has indicated that the external editor should always be used, this
  external editors module opens the appropriate editor, and stops the execution
  of the hook. However, if the user didn't wish to use an external editor, this
  module does nothing, so that the callback from the source editor module is
  called in turn, and can thus open the file itself.

  See :file:`gps-kernel-hooks.ads` for more information on hooks.