Listing 3: The AnalogOutput class

class AnalogOutput
{
    friend Configure;
    friend MasterRun;
    const Address output_;
    Time lastRelevel_;
    Auditor *auditor_;
    Bool returnToIdle_;
    Signal level_, step_, idleLevel_;

    void relevel( const Signal &newLevel ) {
    const Time time = mtime();
    const Time interval = time - lastRelevel_;
    const Signal lower = level_ - step_ * interval, 
        upper = level_ + step_ * interval;

    if( newLevel > upper )
        level_ = upper;
    else if( newLevel < lower )
        level_ = lower;
    else
        level_ = newLevel;
    writeAnalog( output_, level_ );
    lastRelevel_ = time;
    auditor_->refresh();
    }
    void idleLevel( const Signal &iLvl )    { idleLevel_ = iLvl; }
    void stepSize( const Signal &stepSize ) { step_ = stepSize; }
    void reset() {
    if( ready() )
        returnToIdle_ = Global::false;
    }

public:
    void idle()              { returnToIdle_ = Global::true; }
    Bool ready()       const { return idleLevel_ == level_; }
    Signal idleLevel() const { return idleLevel_; }
    Signal stepSize()  const { return step_; }
    Signal level()     const { return level_; }

    void level( const Signal &newLevel ) {
    if( returnToIdle_ && level_ != idleLevel_ )
        relevel( idleLevel_ );
    else
        relevel( newLevel );
    }
};
/* End of File */