Skip to content

Commit

Permalink
Merge pull request #318 from gaphor/documentation
Browse files Browse the repository at this point in the history
Documentation
  • Loading branch information
danyeaw committed May 15, 2020
2 parents 9911bc2 + fffc2b3 commit 26cecc7
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 100 deletions.
2 changes: 1 addition & 1 deletion docs/connect.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ In Gaphor, if a connection is made on a diagram between an element and a
relationship, the connection is also made at semantic level (the model). From a
GUI point of view, a button release event is what kicks of the decision whether
the connection is allowed. Please reference the page on [Items and
Elements](item.md) if you need a reminder on the difference between the two.
Elements](items.md) if you need a reminder on the difference between the two.

```eval_rst
Is relation with this element allowed?
Expand Down
22 changes: 20 additions & 2 deletions docs/event_system.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,26 @@

The Generic library provides the `generic.event` module which is used to
implement the event system in Gaphor. This event system in Gaphor provides an
API to *subscribe* to events and to then *handle* those events so previously
subscribed *handlers* are being executed.
API to *subscribe* to events and to then *handle* those events so that
previously subscribed *handlers* are executed.

In Gaphor we manage event handler subscriptions through the EventManager
service. Gaphor is highly event driven:

* Changes in the loaded model are emitted as events
* Changes on diagrams are emitted as events
* Changes in the UI are emitted as events

Although Gaphor depends heavily on GTK for its user interface, Gaphor is using
its own event dispatcher. Events can be structured in hierarchies. For example,
an AttributeUpdated event is a subtype of ElementUpdated. If we are interested
in all changes to elements, we can also register ElementUpdated and receive all
AttributeUpdated events as well.

```eval_rst
.. autoclass:: gaphor.core.eventmanager.EventManager
:members:
```

For more information about how the Generic library handles events see the
[Generic documentation](https://generic.readthedocs.io).
10 changes: 8 additions & 2 deletions docs/framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Gaphor is built in a light, service oriented fashion. The application is split
in a series of services, such as a file, event, and undo managers. Those
services are loaded based on entry points defined in the `pyproject.toml` file.
To learn more about the architecture, please see the description about the
[Service Oriented Architecture](so.md).
[Service Oriented Architecture](service_oriented.md).

## Events

Expand All @@ -33,11 +33,17 @@ button is pressed.

The main portion of Gaphor that executes first is called the `Application`.
Only one Application instance is permitted. The Application will look for
services defined as [gaphor.services](services.md). Those services are loaded
services defined as [gaphor.services](service_oriented.md). Those services are loaded
and initialized.

The most notable services are:

### event_manager

This is the central component used for event dispatching. Every service that
does something with events (both sending and receiving) depends on this
component.

### file_manager

Loading and saving a model is done through this service.
Expand Down
37 changes: 19 additions & 18 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,48 +13,49 @@ If you're into writing plug-ins for Gaphor you should have a look at our
fabulous `Hello world <https://github.com/gaphor/gaphor.plugins.helloworld>`_
plug-in.

Platforms
---------

Setting up a development environment, and packaging Gaphor on different
platforms:

.. toctree::
:caption: Installation
:maxdepth: 1

windows
linux
macos
windows

.. _tech-section:
.. toctree::
:caption: Concepts
:maxdepth: 1

Tech section
------------
framework
service_oriented
event_system
modeling_language
items
undo

.. toctree::
:caption: UML and data model
:maxdepth: 1

framework
model
stereotypes
datamodel
connect
items
services
so
storage
undo
xml-format
event_system

.. toctree::
:maxdepth: 2
:caption: Storage
:maxdepth: 1

storage
xml-format

External links
^^^^^^^^^^^^^^
--------------

* You should definitely check out `Agile Modeling <http://www.agilemodeling.com>`_ including these pages:

1. `UML Diagrams <http://www.agilemodeling.com/essays/umlDiagrams.htm>`_ (although Gaphor does not see it that black-and-white).
2. http://www.agilemodeling.com/essays/
* The `official UML specification <https://www.omg.org/spec/UML>`_. This ''is'' our data model.
* The `official UML specification <https://www.omg.org/spec/UML>`_. This ''is'' our data model.
10 changes: 5 additions & 5 deletions docs/model.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ The events are sent using a signaling mechanism, called handlers.
## Model details

Pay attention to the following changes/additions with respect to the
official Gaphor model, in the `uml2.gaphor` file:
official Gaphor model, in the `models/UML.gaphor` file:

- Additions to the model have been put in the package
AuxilaryConstructs.Presentations and .Stereotypes.
AuxiliaryConstructs.Presentations and .Stereotypes.
- A Diagram element is added in order to model the diagrams.
- A special construct has been put into place in order to apply
stereotypes to model elements. The current UML Specification is not
clear on that subject.
- The Slot.value reference is singular.

``` note:: ValueSpecification is generated as if it were a normal attribute. As a result, its subclasses (Expression, OpaqueExpression, InstanceValue, LiteralSpecification and its Literal* subclasses) are not available.
```
- ValueSpecification is generated as if it were a normal attribute. As a
result, its subclasses (Expression, OpaqueExpression, InstanceValue,
LiteralSpecification and its Literal* subclasses) are not available.
40 changes: 40 additions & 0 deletions docs/modeling_language.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Modeling Languages

Since version 2.0, Gaphor supports the concept of Modeling languages. This
allows for development of separate modeling languages separate from the Gaphor
core application.

The main language was, and will be UML. Gaphor now also supports a subset of
SysML.

A ModelingLanguage in Gaphor is defined by a class implementing the
`gaphor.abc.ModelingLanguage` abstract base class. The modeling language should
be registered as a `gaphor.modelinglanguage` entry point.

The ModelingLanguage interface is fairly minimal. It allows other services to
look up elements and diagram items, as well as a toolbox. However, the
responsibilities of a ModelingLanguage do not stop there. Parts of
functionality will be implemented by registering handlers to a set of generic
functions.

But let's not get ahead of ourselves. What is the functionality a modeling
language implementation can offer?

* A data model (elements)
* Diagram items
* A toolbox definition
* Connectors, allow diagram items to connect
* Grouping
* Editor pages, shown in the collapsable pane on the right side
* Inline (diagram) editor popups
* Copy/paste behavior when element copying is not trivial, for example with
more than one element is involved

We expose the first three by methods defined on the ModelingLanguage class. We
then expose the others by adding handlers to the respective generic functions.


```eval_rst
.. autoclass:: gaphor.abc.ModelingLanguage
:members:
```
74 changes: 66 additions & 8 deletions docs/so.md → docs/service_oriented.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,71 @@

Gaphor has a service oriented architecture. What does this mean? Well, Gaphor
is built as a set of small islands (services). Each island provides a specific
piece of functionality. For example, separate services are used to load/save
models, provide the menu structure, and handle the undo system.
piece of functionality. For example, we use separate services to load/save
models, provide the menu structure, and to handle the undo system.

Service are defined as entry points in the `pyproject.toml`. With entry points
applications can register functionality for specific purposes. Entry points are
grouped in so called *entry point groups*. For example the console_scripts
entry point group is used to start an application from the command line.
We define services as entry points in the `pyproject.toml`. With entry points,
applications can register functionality for specific purposes. We also group
entry points in to *entry point groups*. For example, we use the
console_scripts entry point group to start an application from the command
line.

Entry Points
============

## Services

Gaphor is modeled around the concept of services. Each service can be
registered with the application and then it can be used by other services or
other objects living within the application.

Each service should implement the Service interface. This interface
defines one method:

shutdown(self)

Which is called when a service needs to be cleaned up.

We allow each service to define its own methods, as long as the service
is implemented too.

Services should be defined as entry points in the `pyproject.toml` file.

Typically, a service does some work in the background. Services can also expose
actions that can be invoked by users. For example, the _Ctrl-z_ key combo
(undo) is implemented by the UndoManager service.

A service can also depend on another services. Service initialization resolves
these dependencies. To define a service dependency, just add it to the
constructor by its name defined in the entry point:

class MyService(Service):

def __init__(self, event_manager, element_factory):
self.event_manager = event_manager
self.element_factory = element_factory
event_manager.subscribe(self._element_changed)

def shutdown(self):
self.event_manager.unsubscribe(self._element_changed)

@event_handler(ElementChanged)
def _element_changed(self, event):

Services that expose actions should also inherit from the ActionProvider
interface. This interface does not require any additional methods to be
implemented. Action methods should be annotated with an `@action` annotation.

## Example: ElementFactory

A nice example of a service in use is the ElementFactory. It is one of the core services.

The UndoManager depends on the events emitted by the ElementFactory. When an
important events occurs, like an element is created or destroyed, that event is
emitted. We then use an event handler for ElementFactory that stores the
add/remove signals in the undo system. Another example of events that are
emitted are with `UML.Element`s. Those classes, or more specifically, the
properties, send notifications every time their state changes.

## Entry Points

Gaphor uses a main entry point group called `gaphor.services`.

Expand All @@ -35,6 +90,7 @@ Each service (and plugin) should implement the `gaphor.abc.Service` interface:

```eval_rst
.. autoclass:: gaphor.abc.Service
:members:
```

Another more specialized service that also inherits from `gaphor.abc.Service`,
Expand All @@ -44,6 +100,7 @@ implement the `gaphor.ui.abc.UIComponent` interface:

```eval_rst
.. autoclass:: gaphor.ui.abc.UIComponent
:members:
```

Typically a service and UI component would like to present some actions
Expand All @@ -53,6 +110,7 @@ interface:

```eval_rst
.. autoclass:: gaphor.abc.ActionProvider
:members:
```

## Example plugin
Expand Down
46 changes: 0 additions & 46 deletions docs/services.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/storage.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Saving and Loading Gaphor Diagrams
# Saving and Loading models

The root element of Gaphor models is the `Gaphor` tag, all other elements are
contained in this. The Gaphor element delimits the beginning and the end of an
Expand Down
2 changes: 1 addition & 1 deletion docs/windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ script that creates a Windows installer using
1. Run ``C:\msys64\mingw64.exe`` - a terminal window should pop up
```bash
$ cd win-installer
$ source build-installer.sh
$ ./build-installer.sh
```

0 comments on commit 26cecc7

Please sign in to comment.