Mail Archives: geda-user/2015/09/11/10:06:57
While reading the past discussions here on the list, I had the impression
that some ideas are developed over and over again, while few people took
notice of the infrastructure which I already created.
An in-memory database? Look at libxornstorage. An interchange mechanism
between programs written in different languages? Look at libxornstorage
and write a wrapper for your favorite language if it doesn't already exist.
I'm not "working on the Python branch", and I haven't "created a complete
parallel to gnetlist, but based on Python rather than Scheme".
xorn-netlist *is* gnetlist. I'm gradually shifting the gEDA
infrastructure to a more modular design, using C where I have to (for
interoperability with any language) and Python where I can (for those
implementation parts which don't have to be hand-optimized in C). In the
process, I converted the API for netlist backends to Python, but that was
partly because there are no Guile bindings in Python, and the code turned
out to be much easier this way.
On Tue, 25 Aug 2015, Nicklas Karlsson (nicklas DOT karlsson17 AT gmail DOT com) [via
geda-user AT delorie DOT com] wrote:
> It might work better you postpone the memory representation and figure
> which kind of functions you need to access the objects. Then the access
> functions are decided it will be easier to think about the
> representation.
The thing is, I've already done exactly that. xornstorage.h is a
carefully designed interface that provides the kinds of queries which are
to be expected in both a GUI aplication and in scripts (excluding
rectangular selection, which is an entirely different problem on its own).
The implementation is independent from that and can easily be exchanged
for another one.
On Tue, 25 Aug 2015, Evan Foss (evanfoss AT gmail DOT com) [via
geda-user AT delorie DOT com] wrote:
> And now imagine the biggest difference of all. Instead of one giant
> program with poorly defined boundaries between layers you had
>
> * libpcbfile for moving between a memory representation of a layout
> and the file that stores it
> * libpcbgeo for processing geometric properties
> * libpcbexport for translation to pdf, ps, png, jpeg
> * libpcbnetlist for forward and backward annotation
> * libpcbui for providing the HID interface
>
> and etc.
This is just what I did with Xorn for schematic files:
xorn.storage - in-memory representation of schematic objects
xorn.geda.read - reads .sch/.sym files
xorn.geda.write - writes .sch/.sym files
xorn.geda.netlist - creates netlists from schematic files
xorn.geda.render - renders schematics to Cairo for display and PDF export (work in progress)
The obvious thing would be to continue that scheme for PCB, too:
xorn.storage - in-memory representation of PCB objects
xorn.pcb.read - reads .pcb files
xorn.pcb.write - writes .pcb files
xorn.pcb.netlist - creates netlists for back annotation
xorn.pcb.render - renders PCBs to Cairo for display and PDF export
Right now, there is some code duplication between libgeda and Xorn since I
didn't update libgeda to use the new infrastructure yet. This is on my
to-do list, though.
On Wed, 26 Aug 2015, Nicklas Karlsson (nicklas DOT karlsson17 AT gmail DOT com) [via
geda-user AT delorie DOT com] wrote:
> I guess it would be possible to get different views. What is needed is a
> set of functions to access the data. I guess should be a need for:
> iterate thru the objects on one layer, iterate thru the nets, iterate
> thru the descriptors, extract symbols with a particular value, iterate
> thru symbol coordinates to renumber them left rigt, ...
It shouldn't be necessary to iterate over the objects in the first place.
Of course, there are situations where you can't avoid it (like, for
example, when drawing them to the screen), but usually the storage library
should know best which algorithm(s) to use to handle the request most
efficiently. Therefore, it should be provided with a "high-level"
description of the query so it is able to optimize the request.
Imagine the following SQL query:
DELETE FROM objects WHERE radius = 0.;
Using Xorn as an example, you could either iterate over all objects,
looking for circles and arcs wth a matching radius, and delete these
objects:
xorn_object_t *objects;
size_t count;
unsigned int i;
xorn_get_objects(rev, &objects, &count);
for (i = 0; i < count; i++) {
xorn_obtype_t type = xorn_get_object_type(rev, objects[i]);
if (type == xornsch_obtype_circle &&
xornsch_get_circle_data(rev, objects[i])->radius == 0.)
xorn_delete_object(rev, objects[i]);
if (type == xornsch_obtype_arc &&
xornsch_get_arc_data(rev, objects[i])->radius == 0.)
xorn_delete_object(rev, objects[i]);
}
free(objects);
Or, you could provide the library with all information necessary to
optimize the request and let it figure out the details:
xorn_selection_t sel = xornsch_select_by_radius(rev, 0.);
xorn_delete_selected_objects(rev, sel);
xorn_free_selection(sel);
Maybe the list of objects is implemented in a way that is optimized for
item lookup, but makes deleting an object a really slow operation? In
this case, the library could implement xorn_delete_selected_objects as a
bulk deletion, which would result in a much faster response.
The current implementation of libxornstorage isn't very sophisticated, but
it has a well-documented API and an exhaustive test suite, so anyone who
is interested is welcome to provide a better alternative.
On Thu, 27 Aug 2015, Stephen R. van den Berg (srb AT cuci DOT nl) [via
geda-user AT delorie DOT com] wrote:
> It should easily be possible to have the applications display realtime
> from the db without creating complicated extra internal datastructures.
This is already how -lxornstorage works. With SQL, you have to create at
least the result array. With Xorn, you get raw pointers to the storage
structs. For example, the struct for a schematic text is defined as:
struct xornsch_text {
struct xorn_double2d pos;
int color;
int text_size;
bool visibility;
int show_name_value;
int angle;
int alignment;
struct xorn_string text;
};
where xorn_double2d is defined as:
struct xorn_double2d {
double x, y;
};
and xorn_string is defined as:
struct xorn_string {
const char *s;
size_t len;
};
This struct and the referenced string are copied exactly once--when
setting the data, so the library doesn't interfere with the calling
application's memory management. This concept obviously only works if all
calling applications are well-behaved and respect the "const" qualifier,
but that's the price of accessing the data structures directly.
Roland
- Raw text -