[PythonCAD] More repo code updates

Art Haas ahaas at airmail.net
Fri Oct 29 22:56:34 CEST 2004


On Thu, Oct 28, 2004 at 11:37:28PM -0200, Gustavo Barbieri wrote:
> On Thu, 28 Oct 2004 18:58:25 -0500, Art Haas <ahaas at airmail.net> wrote:
> > On Thu, Oct 28, 2004 at 03:11:36PM -0200, Gustavo Barbieri wrote:
> > > On Thu, 28 Oct 2004 11:51:25 -0500, Art Haas <ahaas at airmail.net> wrote:
> > > [ ... snip ... ]
> > 
> > Deleted objects are stored by saving the values of various attributes of
> > the object, but the object itself is destroyed. For example, a Point has
> > 'x' and 'y' coordinates, plus some internal bookkeeping values. So, when
> > a Point instance is deleted, the values of these attributes are stored
> > in an EntityData instance (see PythonCAD/Generic/entity.py), and the
> > object is deleted.
> 
> Maybe you should implement __repr__ for each object. __repr__ method
> is used to return a expression that could be used to reconstruct the
> object... then you eval()uate it :)

At one point I tried using __repr__ for doing this, but I could not get
that approach to work. The problem was in dealing with objects that
contain references to other objects, plus complex objects like
Dimensions were cumbersome to represent in the __repr__ format.

> > The problem I saw with keeping the deleted objects around dealt with the
> > interrelationship between various objects. A Segment instance keeps
> > references to two Point instances, and these two Point instances also
> > store a reference to the Segment. I thought that trying to store the
> > entity values, and using those values to recreate the entity should the
> > user do so, was a better approach to recreating the entity than leaving
> > all the reference between entities yet marking deleted entities in some
> > fashion. I still like my approach, but if better approaches are
> > presented a switch can certainly be considered.
> 
>  - Suppose you have a Group, a Layer and a Line. Line is in both Group
> and Layer.
>  - Delete the Line: push it into DeletedObjects (our undo list) and
> remove it from Group and Layer.
>  - a) Undo: pop the head of DeletedObjects and ask it to reattach to
> previous attached groups, they will be Group and Layer.
>  - b) It drops from the DeletedObjects list (undo maximum steps
> reached), just delete it. No one holds a reference to it.
> 
>  - Suppose the same Group, Layer and Line
>  - Delete the Group: push it into DeletedObjects and ask its contents
> to delete itself if they're just in this group (assuming that an
> object could be in various groups). You can think its children as
> deleted but they be kept by the group itself, not the DeletedObjects,
> so they'll not count as undo steps. It's recursive.
>  - a) Undo: pop the head of DeletedObjects and ask it to reattach
> itself to previous attached groups, they will be just Layer. Call this
> reattach to every children and recursively
>  - b) It drops from the DeletedObjects list, just delete it.
> 
> Will this work or I'm under thinking it?

The approach sounds valid, but the devil is in the details. Like I said
in an earlier mail, I'm open to better implementations of recreating
deleted objects, but what is in the program now works. I can visual some
sort of variable each instance would have called 'active' that is set to
True when the object is created. If the object is deleted the variable
is set to False. Some sort of entity deletion/recreation approach could
be designed to use this variable, and like you describe above the
deleted entities could be stored off in a list and pull back from the
list if and when they are recreated.

> The problem with reconstructing the object is how do you keep all
> those references an object can have.

I'll use the example of a Layer containing a two Points and a Segment
connecting these two Points. The layer stores references to both points
and the segment, and each point and segment have the layer as their
parent entity. Now, the segment gets deleted. The deletion operation
first removes the Layer's storage of the segment, then saves the undo
history of the segment, then removes the Layer as the parent to the
segment. Now the segment removes its references to the points, and the
points remove their references to the segment. Each of the points is
then checked to see if they are unused by other objects, if if so then
each point is deleted.

Recreating the segment entails reversing the operations done above.
First, any of the deleted points are readded to the Layer, and the
Point/Layer references are reestablished. Then the Segment is recreated
using the points as endpoints, and added again to the Layer, thusly
reconnecting the various Segment/Layer references.

The descriptions above describe code mostly found in the 'layer.py' file
with the delObject(), _delSegment(), _freeObj(), and _delPoint() methods
containing unsurprisingly deletion code, and addObject(), _addPoint(),
and _addSegment() containing the addition code.

Art
-- 
Man once surrendering his reason, has no remaining guard against absurdities
the most monstrous, and like a ship without rudder, is the sport of every wind.

-Thomas Jefferson to James Smith, 1822


More information about the PythonCAD mailing list