← Back to team overview

geda-developers team mailing list archive

[RFC] libgeda data structures and algorithms

 

Hi folks,

I've been running up against some serious issues with the data
structures in libgeda, which have been making my life pretty difficult
when trying to add features and/or fix bugs in gEDA/gaf.  I describe
them below, along with some possible approaches for addressing them.

I'd really appreciate any and all comments and/or feedback that you
could give me.  These will all fall in the "serious refactoring" bucket,
and I would really appreciate some sanity checking to ensure that I'm
not going to run into a snag that someone else could have spotted for
me!

Spatial indexing: tiles, R*-trees, and the "world size"
-------------------------------------------------------

The current tile system in libgeda is problematic.  If an object is
introduced to a page which lies outside the "world size", either wholly
or in part, the connection tracking and spatial lookup subsystems in
libgeda will just completely ignore it.  This caused some difficulties
to Ed Hennessy when he was working on the "gsch2pdf" tool that turned
out to be so difficult to track down that he ended up writing his own
connection tracking layer.  This shouldn't have been necessary!

As you may be aware, I'm in the process of converting the config system
over from Scheme functions to parsed configuration files, and I'd very
much like to get rid of the "world size" settings entirely.  At the
moment, it is only used to determine the scrollable region in gschem and
the extents of the tile system.

What I suggest is to replace the tile system with an R*-tree [1], and to
determine gschem's scrollable region using a heuristic based on the
drawn extents.

Relatedly, we also have a bunch of functions for handling rectangular
bounding boxes.  They currently work by passing around coordinates of
the bounding box corners as separate integers; I would like to introduce
an EdaRectangle structure to simplify these APIs.

[1] Beckmann, N.; Kriegel, H. P.; Schneider, R.; Seeger, B. (1990). "The
    R*-tree: an efficient and robust access method for points and
    rectangles". http://dx.doi.org/10.1145/93597.98741

Sets of objects
---------------

I have been trying to upgrade the gschem multi-attribute editor to show
unattached attributes when the selection is empty or an unattached
attribute is selected.  I have also been trying to figure out how to add
an indication to the gschem window title of whether the current page has
unsaved changes. Unfortunately, this has been stymied by the fact that
it's not currently possible to receive a signal when an object is added
to or removed from a page.

I noticed that this problem doesn't just affect the contents of pages.
It's also not possible to reliably be notified when objects are attached
or detached as attributes, nor when objects are added to or removed from
components or selections.

Using a GedaList doesn't really solve the problem.  It's not possible to
get notified of *which* items were added or removed via the "changed"
signal.  It would be ideal to be able to hook into insertion or removal
of objects from a collection so as to be able to ensure that state is
maintained (e.g. spatial indexing in PAGEs; parent/owner references; and
automatically removing an object from a page's selection when it is
removed from the page itself).

A further consideration is that in all of the places where collections
of objects are handled, a *set* is needed, not a simple list; inserting
an object into any of these collections more than once makes the
datastructures inconsistent.

I considered adding an EdaObjectSet to libgeda as a "proper" GObject.
However, it occurred to me that this might not be the best option,
because in the future it would make sense for a component to be an
EdaObjectSet but also an EdaObject (if we turned OBJECT into a
GObject).

My suggestion is therefore to introduce an EdaObjectSet as a gobject
"interface" to be implemented wherever it makes sense to handle a set of
objects.  It would then be possible add a "default" EdaObjectList class
that provides a default implementation for the interface and could be
used as the basis for turning the schematic page structure into a
GObject with useful signals.

Ideally, we shouldn't expose bare GLists anywhere in the API.  It's too
much of a temptation to write code which hacks at the list structures
directly rather than to use accessors that ensure consistency is
maintained.  I'd like to introduce an EdaObjectIter to be used to
iterate over object sets.

Safely loading schematics and symbols
-------------------------------------
We have a big crash bug with the current recursive nature of our
schematic file parser [2].  The only sane way to fix it appears to be to
resolve and load symbols from the library on a separate pass.

This might also be a good opportunity to modify the schematic loading
logic to support GInputStream from the GIO library.

The main problem I have with this at the moment is trying to figure out
what a sane API might look like.

Ideally, it would be good to provide user code with a way to get high
quality feedback on which symbols couldn't be loaded and why they
failed, and also to have a way to distinguish between symbols that we
tried and failed to load vs. symbols that we haven't tried to resolve
yet.  At the moment, if a symbol causes a parse error, 

[2] https://bugs.launchpad.net/geda/+bug/732326



That's all for now; it's late at night and I'm pretty knackered.
Unfortunately, these aren't all the issues that I'm banging my head
against...

                       Peter

-- 
Peter Brett <peter@xxxxxxxxxxxxx>
Remote Sensing Research Group
Surrey Space Centre

Attachment: pgph8K5t_Kohh.pgp
Description: PGP signature


Follow ups