Logo Search packages:      
Sourcecode: ardour version File versions  Download package

history.h

/*
    Copyright (C) 2001 Paul Davis 

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    $Id: history.h,v 1.2 2004/11/29 03:04:45 pauld Exp $
*/

#ifndef __ardour_history_h__
#define __ardour_history_h__

#include <list>
#include <sigc++/signal_system.h>

template<class T>
struct History : public SigC::Object 
{
    typedef list<T *> StateList;
    
    StateList states;
    StateList::iterator current;

    History() { current = states.end(); }
    ~History() { states.erase (states.begin(), states.end()); }

    SigC::Signal0<void> CurrentChanged;

    void clear () {
          for (StateList::iterator i = states.begin(); i != states.end(); i++) {
                delete *i;
          }
          states.clear ();
          current = states.end();
          CurrentChanged();
    }

    void push (T *state) {
          /* remove any "undone" history above the current location
             in the history, before pushing new state. 
          */
          if (current != states.begin() && current != states.end()) {
                states.erase (states.begin(), current);
          }
          current = states.insert (states.begin(), state);
          CurrentChanged ();
    }

    T *top() { 
          if (current != states.end()) {
                return *current;
          } else {
                return 0;
          }
    }

    T *pop (bool remove) {
      if (current == states.end()) {
            return 0;
      }
      
      if (current == states.begin()) {
            return *current;
      }
      
      current--;
      T *state = *current;

      if (remove) {
            states.erase (current);
      }

      CurrentChanged ();
      return state;
    } 

    T *earlier (uint32_t n) {
          StateList::iterator i;
          
          if (current == states.end()) {
                return 0;
          }
          
          if (n == 0) {
                return *current;
          }
          
          /* the list is in LIFO order, so move toward the end to go "earlier" */
          
          for (i = current; n && i != states.end(); i++, n--);
          
          if (i == states.end()) {
                return 0;
          } else {
                current = i;
                CurrentChanged ();
                return *i;
          }
    }

    T *later (uint32_t n) {
          StateList::iterator i;
          
          if (current == states.end()) {
                return 0;
          }
          
          if (n == 0) {
                return *current;
          }
          
          /* the list is in LIFO order, so move toward the beginning to go "later" */
          
          for (i = current; n && i != states.begin(); i--, n--);
          if (i != current) {
                current = i;
                CurrentChanged();
          }
          return *i;
    }

    T *nth (uint32_t n) {
          StateList::iterator i;
          
          for (i = states.begin(); n && i != states.end(); n--, i++);
          
          if (i != states.end()) {
                if (i != current) {
                      current = i;
                      CurrentChanged ();
                }
                return *i;
          } else {
                return 0;
          }
    }
    
};

#endif /* __ardour_history_h__ */


Generated by  Doxygen 1.6.0   Back to index