Subject:    TableSlots don't have value change callback integrity!
Date:   Tue, 08 Dec 2009 11:28:39 -0700
From:   Phil Weinstein <Philip.Weinstein@colorado.edu>
To:   software <software@cadsweb.colorado.edu>

In the course of addressing these two bugs ...

... I discovered that one of the forms of setting values on TableSlots doesn't -- and cannot -- generate a value-changed callback!

The problem is with value-setting using this sort of syntax:

This syntax is supported with these two TableSlot class operators (used for the left side of those assignment operations):

I coded and substantially built an C++ solution -- BUT AM BAILING FROM THIS -- which basically consists of:

Instead of returning a "reference to a double" from the two TableSlot operators above, it returns an instance value of a new helper class: TableSlotCellRef (see below), and
That TableSlotCellRef class defines an assignment operator (from a double value) which performs the value assignment to the TableSlot cell in a way which generates a value-changed callback.

I did get this basically built, but it was looking like the mechanism needed to be extended to the TableSlotProxy class, and venturing into that revealed more complexity than is warranted now, so I'm backing out of this. FWIW, below are some technical details.

*** SO, we're going to have to work around TableSlot values not being reliably correct (up to date) in the GUI. I'm going to apply some bandaids, e.g. refreshing TableSlot displays at certain controller events (RI_STATE_CHANGED), e.g. especially, STOPPED and FINISHED (but only for TableSlots, and TableSlot subclasses).

CODE EXCERPTS (NOT USED):

// *************************************
// *** New class: TableSlotCellRef ***
// *************************************

class TableSlotCellRef
{
  private:
    TableSlot* _tslot;
    int _row;
    int _col;

  public:
    TableSlotCellRef (TableSlot* tslot, int r, int c);
    operator double() const;
    double operator= (double val);
};

TableSlotCellRef::TableSlotCellRef (TableSlot* tslot, int r, int c)
  : _tslot (tslot),
    _row (r),
    _col (c)
{
   rwAssert (_tslot != NULL);
}

TableSlotCellRef::operator double() const
{
   return _tslot->getValue (_row, _col);
}

double TableSlotCellRef::operator= (double val)
{
   // This will generate a callback
   _tslot->setValue (val, _row, _col);
   return (val);
}

// ***************************
// *** TableSlot changes ***
// ***************************

OLD: inline double& operator() (int col) const;
OLD: inline double& operator() (int row, int col) const;

NEW: inline TableSlotCellRef operator() (int col);
NEW: inline TableSlotCellRef operator() (int row, int col);

inline TableSlotCellRef TableSlot::operator() (int col)
{
   return TableSlotCellRef (this, 0, col);
}

inline TableSlotCellRef TableSlot::operator() (int row, int col)
{
   return TableSlotCellRef (this, row, col);
}

--- (end) ---