Views and Buffers

From Yzis Wiki

Jump to: navigation, search

This page to documents what happens to views and buffers, upon creation and deletion.

Contents

Introduction

View and Buffer are central concept to Yzis and to any editing application. Yzis uses the classical document-view design pattern (also known as model-view):

  • the document stores that data and had methods to modify itself
  • the view process user requests, which it converts into calls to document
  • the document send updates to the view

In Yzis, the document is a buffer, the view is a view. Things are a bit more complicated than in the theorical model, because the YZViewIface is pure virtual; it contains methods to be implemented by the gui frontend. One consequence of that is that libyzis can not instantiate YZView objects. Libyzis must pass requests to the gui so that it instantiate such objects. The same happen for deletion. Libyzis does not delete YZView instance, it asks the gui to do it.

In the past, the same was true for the YZBuffer. The first implementations of libyzis has a pure virtual YZBuffer. This is no longer the case but this code may still contain part of the old design.

libyzis view and buffer management

One core principle of Yzis is: the view owns the buffer. A buffer without view does not make much sense. The first thing done after the creation of a buffer is the creation of one view on it. And when the last view on a buffer gets closed, it (should) delete the buffer.

Consequence: YZSession contains a public method createBufferAndView() but the method createBuffer() is private. It's reserved for YZSession private usage.

Second important principle: the gui frontend deletes the view instance. Libyzis does not delete the instance itself. This was the case in the past and created lot of troubles when working with kpart in KDE.

With those two principles in mind, the rest is quite simple.

We will look at what Yzis does in specific cases:

Buffer and View creation

When a new buffer is needed, one should call YZSession::createBufferAndView( path ).

Code execution:

  • createBufferAndView() calls YZSession::createBuffer( path ). This is a private method of YZSession, only for YZSession private usage.
  • YZSession::createBuffer() creates the new buffer and calls YZSessionIface::guiCreateBuffer( YZBuffer * buf ) to inform the gui that the new buffer was created.
  • after that, YZSessionIface::guiCreateView( YZBuffer * buf ) requests the gui to instantiate an YZView. The newly created view is returned to YZSession.
  • then YZSession returns the view.


Example: Edit new file

When you type :edit some_file.txt on the command line, here is what happens. The code starts in libyzis/mode_ex.cpp.

  • if some_file.txt is already in a buffer, the code looks for a view containing it and makes that view active.
  • if there is no buffer containing some_file.txt, a call to YZSession::createBufferAndView() is made and the new view is made active.

Example: Files on the command line

The files that are specified on the command line are treated in YZSession::parseCommandLine( argc, argv ). Yzis will simply make one call to YZSession::createBufferAndView() for each file specified.

Example : GUI frontend creates a new buffer

For the GUI frontends with menu and toolbars, it is possible for the user to open a new file. The GUI frontend should simply call YZSession::createBufferAndView() for the newly created file.

Buffer and View deletion

Buffer and View deletion must be carefully handled. Like any C++ program, this can be the cause of crashes.

Deleting a buffer

Deleting a buffer happens for example when the user types :bdelete.

There is a method YSession::removeBuffer() that triggers the buffer deletion process:

  • first all views on the buffer are deleted with YSession::deleteView()
  • the destructor of the last view on the buffer calls YSession::deleteBuffer()
  • YSession::deleteBuffer() informs the gui of the buffer removal with YSessionIface::guiRemoveBuffer(), then deletes the YBuffer instance.


Deleting a view

Deleting a view can be triggered by the user closing a tab view, or by deleting the buffer containing the view.

The view deletion process is the following:

  • a call to YSession::deleteView( YZView * v ) is made
  • YSession::deleteView() checks if this is the last view and if not, a call to guiDeleteView( YView * v ) is made.
  • the gui process the guiDeleteView( YView * v ) call by deleting its view instance.
  • the ~YView() destructor is called.

Deleting the last view