Modeling Language Core#

The Core modeling language is the the basis for any other language.

The Element class acts as the root for all gaphor domain classes. Diagram and Presentation form the basis for everything you see in a diagram.

All data models in Gaphor are generated from actual Gaphor model files. This allows us to provide you nice diagrams of Gaphor’s internal model.

../_images/3867dda5-7a95-11ea-a112-7f953848cf85.svg

The Element base class provides event notification and integrates with the model repository (internally known as ElementFactory). Bi-directional relationships are also possible, as well as derived relations.

The RepositoryProtocol, and EventWatcherProtocol protocols are important to connect the model to the repository and event handling mechanisms.

The Element Class#

The class Element is the core of Gaphor’s data model.

class gaphor.core.modeling.Element(id: str | None = None, model: RepositoryProtocol | None = None)[source]#

Base class for all model data classes.

property id: str#

An id (read-only), unique within the model.

property model: RepositoryProtocol#

The owning model, raises TypeError when model is not set.

Unlink the element.

All the elements references are destroyed. For composite associations, the associated elements are also unlinked.

The unlink lock is acquired while unlinking this element’s properties to avoid recursion problems.

Event handling#

handle(event) None[source]#

Propagate incoming events.

This only works if the element has been created by an ElementFactory

watcher(default_handler: Callable[[ElementUpdated], None] | None = None) EventWatcherProtocol[source]#

Create a new watcher for this element.

Watchers provide a convenient way to get signalled when a property relative to self has been changed.

To use a watcher, the element should be created by a properly wired up ElementFactory`.

This example is purely illustrative:

>>> element = Element()
>>> watcher = element.watcher(default_handler=print)
>>> watcher.watch("note")  # Watch for changed on element.note

Loading and saving#

load(name, value) None[source]#

Loads value in name.

Make sure that after all elements are loaded, postload() should be called.

postload() None[source]#

Fix up the odds and ends.

This is run after all elements are loaded.

save(save_func) None[source]#

Save the state by calling save_func(name, value).

OCL-style methods#

isKindOf(class_: type[Element]) bool[source]#

Returns True if the object is an instance of class_.

isTypeOf(other: Element) bool[source]#

Returns True if the object is of the same type as the other.

The Presentation class#

class gaphor.core.modeling.Presentation(diagram: Diagram, id: Id | None = None)[source]#

A special type of Element that can be displayed on a Diagram.

Subtypes of Presentation should implement the gaphas.item.Item protocol.

request_update() None[source]#

Mark this presentation object for update.

Updates are orchestrated by diagrams.

watch(path: str, handler: Callable[[ElementUpdated], None] | None = None) Self[source]#

Watch a certain path of elements starting with self.

The handler is optional and will default to a simple request_update.

Watches should be set in the constructor, so they can be registered and unregistered in one shot.

self.watch("subject[NamedElement].name")

This interface is fluent: returns self.

change_parent(new_parent: Presentation | None) None[source]#

Change the parent and update the item’s matrix so the item visually remains in the same place.

The Diagram class#

class gaphor.core.modeling.Diagram(id: str | None = None, model: RepositoryProtocol | None = None)[source]#

Diagrams may contain Presentation elements and can be owned by any element.

create(type_: type[P], parent: Presentation | None = None, subject: Element | None = None) P[source]#

Create a new diagram item on the diagram.

It is created with a unique ID, and it is attached to the diagram’s root item. The type parameter is the element class to create. The new element also has an optional parent and subject.

lookup(id: str) Presentation | None[source]#

Find a presentation item by id.

Returns a presentation in this diagram or return None.

select(expression: Callable[[Presentation], bool]) Iterator[Presentation][source]#
select(expression: type[P]) Iterator[P]
select(expression: None) Iterator[Presentation]

Return an iterator of all canvas items that match expression.

request_update(item: Item) None[source]#

Schedule an item for updating.

No update is done at this point, it’s only added to the set of to-be updated items.

This method is part of the gaphas.model.Model protocol.

update(dirty_items: Collection[Presentation] = ()) None[source]#

Update the diagram.

All items that requested an update via request_update() are now updates. If an item has an update(context: UpdateContext) method, it’s invoked. Constraints are solved.

Protocols#

class gaphor.core.modeling.element.RepositoryProtocol(*args, **kwargs)[source]#
create(type: type[T]) T[source]#

Create a new element in the repository.

select(self, expression: Callable[[Element], bool]) Iterator[Element]#

Select elements from the repository that fulfill expression.

select(self, type_: type[T]) Iterator[T]

Select all elements from the repository of type type_.

select(self, expression: None) Iterator[Element]

Select all elements from the repository.

lookup(id: str) Element | None[source]#

Get an element by id from the repository.

Returns None if no such element exists.

class gaphor.core.modeling.element.EventWatcherProtocol(*args, **kwargs)[source]#
watch(path: str, handler: Callable[[ElementUpdated], None] | None = None) EventWatcherProtocol[source]#

Add a watch for a specific path. The path is relative to the element that created the watcher object.

Returns self, so watch operations can be chained.

unsubscribe_all() None[source]#

Should be called before the watcher is disposed, to release all watched paths.