On Mon, Jun 28, 2010 at 8:50 AM, Edward K. Ream <[email protected]> wrote:

> There are at least two conflicting goals:
>
> 1. Leave the old read code unchanged when new_read is False.
>
> 2. Simplify the code and use the same code as much as possible when
> reading both old and new style sentinels.

I woke up in the middle of the night with what looks like a good
solution.  The new-sentinels branch contains the new code.

The new approach has the following features:

1. There is no "unified" switch.  It's not needed.  As a result, the
old read code works *exactly* the way it has always worked, and in
essence, none of the old read code changes in any way.

2. v.tempBodyString is used the same way, regardless of
at.readVersion5 (that is, regardless of whether we are reading old or
new sentinels).  Specifically, v.tempBodyString contains the "final"
new body text, as set by at.terminateNode.

3. The real Aha is that the code does *not* try to ensure that
at.terminateNode is called for all nodes.  If it has *not* been
called, v.tempBodyList will contain the "accumulating" body text when
we are reading new sentinels (at.readVersion5==True).

It may be easier to understand what is going on by looking at some
crucial snippets of code.

Snippet 1: at.terminateNode

We get the newly-read body text as follows:

    tempString = hasattr(at.v,'tempBodyString') and at.v.tempBodyString or ''
    tempList = hasattr(at.v,'tempBodyList') and ''.join(at.v.tempBodyList) or ''
    new = g.choose(at.readVersion5,tempList,''.join(at.out))

When reading old sentinels, the new text is just at.out, as before.
When reading new sentinels, the new text is ''.join(at.v.tempBodyList)

at.terminateNode concludes as follows:

    # The old temp text is *always* in tempBodyString.
    old = tempString or at.v.getBody()

    # Warn if the body text has changed, except for the root node.
    if old and new != old and at.v != at.root.v:
        at.indicateNodeChanged(old,new)

    # *Always* put the new text into tempBodyString.
    at.v.tempBodyString = new

    # *Always delete tempBodyList.  Do not leave this lying around!
    if hasattr(at.v,'tempBodyList'): delattr(at.v,'tempBodyList')

The code above illustrates all the essential features of the new scheme:

1. v.tempBodyString), always contains the previous body text,
regardless of at.readVersion5. This is the crucial
simplification/unification.

2. at.indicateNodeChanged is a newly-refactored method that actually
report changes and creates conflict nodes.

3. at.terminateNode is careful always to delete the "tempBodyList".
Thus, when reading new sentinels, the existence of v.tempBodyList is a
flag that at.terminateNode has *not* been called for node v.

BTW, it took a *lot* of work to simplify the computation of 'old' to
tempString or at.v.getBody()


Snippet 2: at.copyAllTempBodyStringsToVnodes

The read logic calls this as a post-pass.  The crucial code is:

for p in root.self_and_subtree():
        # at.terminateNode may not have been called for p.v,
        # so we prefer p.v.tempBodyList if it exists.
        if   hasattr(p.v,'tempBodyList'): s = ''.join(p.v.tempBodyList)
        elif hasattr(p.v,'tempBodyString'): s = p.v.tempBodyString
        else: s = ''

As I write this, I realize that this code should also call
at.indicateNodeChanged if
a) v.tempBodyList exists and b) the text has been changed externally.
That can easily be done.

So that's about it.  Aside from the code mentioned above, the old read
code is unchanged.  The new code accumulates text in v.tempBodyList,
and the new read code can use the existence of v.tempBodyList to
determine whether the node has been terminated or not.

I believe this scheme is the simplest thing that could possibly work.
Happily, it's simple enough that I will have a good chance of
understanding it six years from now.

Edward

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/leo-editor?hl=en.

Reply via email to