ENB: A dict creates virtual temp status bits

22 views
Skip to first unread message

Edward K. Ream

unread,
Mar 10, 2015, 11:46:09 PM3/10/15
to leo-e...@googlegroups.com
The code that issues "recovered nodes" warnings must know whether v.b has been inited previously or not.  Alas, the present code (in at.terminateBody) uses this code instead::

    if v != at.root.v and old != new:
        # Not exactly correct. Old could be empty.
        # However, it appears to be good enough.
        if postPass:
            warn = old # The previous text must exist.
        else:
            warn = old and new # Both must exit.
        if warn:
            at.indicateNodeChanged(old,new,postPass,v)

This code will fail to issue a needed warning in case the old text was empty.  Very lazy of me.

One solution would be to set a vnode "bit" whenever the read code actually sets v.b. Defining a *real* vnode bit, by defining a new mask in v.statusBits would work fine.

However, it would be a nuisance to clear all the bits when the read code is completed.  All such bits (for *all* the vnodes in the outline) *do* have to be cleared so that future refresh-from-disk operations would work properly.

A more elegant way is to define a "virtual", temporary dict in the commander.  This dict would hold all the "bits".  We can define the following atFile accessors:

    def bodyIsInited(self,v):
        '''Return True if v.b has been inited.'''
        c = self.c
        return hasattr(c,'bodyInitedDict') and v.gnx in c.bodyInitedDict
       
    def bodySetInited(self,v):
        '''Indicate that v.b has been inited.'''
        c = self.c
        if not hasattr(c,'bodyInitedDict'):
            c.bodyInitedDict = {}
        c.bodyInitedDict[v.gnx] = True
       
    def clearAllBodyInited(self):
        '''Clear all v.b inited bits.'''
        c = self.c
        if hasattr(c,'bodyInitedDict'):
            delattr(c,'bodyInitedDict')

The read code will use this infrastructure as follows:

1. Any read code that sets v.b will call at.bodySetInited(v).

2. at.terminateBody will issue a warning as follows::

    if at.bodyIsInited(v) and new != old:
        at.indicateNodeChanged(old,new,postPass,v)

**Important**: it remains to be seen whether this will work as expected!  It may lead to duplicate warnings, but they should be easy to suppress.

3. at.readPostPass will call at.clearAllBodyInited() just before returning.

===== Summary

This is a beautiful new pattern.  In particular, creating and destroying c.bodyInitedDict happens automatically, without any need for supporting code outside the atFile read code.  Everything is localized.

Contrast this with the explicit, permanent gnx dict in the fileCommands code.  Maintaining this dict is tricky.  I'm not sure a virtual, temp dict could be used instead, but if it could it would make the code much less fragile.

Edward

P.S. Note: v.setBodyString is much faster than using v.b as a setter.  I have used v.b in this post as a shorthand.

EKR
Reply all
Reply to author
Forward
0 new messages