home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / dreamscape / source / Dreamscape / Headers / abstract / h / state < prev    next >
Encoding:
Text File  |  1996-07-17  |  2.6 KB  |  109 lines

  1.  
  2. // abstract.h.state
  3.  
  4. // Dreamscape - C++ class library for RISC OS
  5. // Copyright (c) 1996 Mark Seaborn <mseaborn@argonet.co.uk>
  6. //
  7. // This library is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU Library General Public
  9. // License as published by the Free Software Foundation; either
  10. // version 2 of the License, or (at your option) any later version.
  11. // See the Dreamscape documentation for more information.
  12.  
  13. #ifndef dreamscape_state_H
  14. #define dreamscape_state_H
  15.  
  16. #include "list.h"
  17. #include "algorithm.h"
  18.  
  19. template <class Type> class State;
  20. template <class Type> class Echo;
  21.  
  22. template <class Type>
  23. class State {
  24.   friend Echo<Type>;
  25.   List<Echo<Type> *> echoes;
  26.  
  27. public:
  28.   State<Type> &operator=(const Type &state)
  29.     { set_state(state); return *this; }
  30.   operator Type() const { return get_state(); }
  31.  
  32.   inline virtual void set_state(const Type &state);
  33.   inline virtual void get_state(Type &state) const {}
  34.   Type get_state() const { Type temp; get_state(temp); return temp; }
  35. };
  36.  
  37. template <class Type>
  38. class Echo {
  39.   friend State<Type>;
  40.   State<Type> *_state;
  41.  
  42. protected:
  43.   virtual void update() = 0;
  44.   State<Type> *state() { return _state; }
  45.  
  46. public:
  47.   inline Echo(State<Type> *s);
  48.   inline virtual ~Echo();
  49. };
  50.  
  51. template <class Type>
  52. inline void State<Type>::set_state(const Type &state) {
  53.   for(ListIterator<Echo<Type> *> l=echoes.begin(); l!=echoes.end(); ++l)
  54.     (*l)->update();
  55. }
  56.  
  57. template <class Type>
  58. inline Echo<Type>::Echo(State<Type> *s): _state(s) {
  59.   _state->echoes.push_front((Echo<Type> *) this);
  60. }
  61.  
  62. template <class Type>
  63. inline Echo<Type>::~Echo() {
  64.   _state->echoes.erase(find(_state->echoes.begin(), _state->echoes.end(),
  65.     (Echo<Type> *) this));
  66. }
  67.  
  68.  
  69. template <class Type>
  70. class IndirectState: public State<Type> {
  71.   State<Type> *state;
  72. public:
  73.   IndirectState(State<Type> *s): state(s) {}
  74.  
  75.   void set_state(const Type &state) { state->set_state(state); }
  76.   void get_state(Type &state) const { state->get_state(state); }
  77.  
  78.   IndirectState<Type> operator=(State<Type> *s)
  79.     { state->s; set_state(state->get_state()); return *this; }
  80.   operator State<Type>() const { return get_attached(); }
  81.  
  82.   void attach(State<Type> *s)
  83.     { state = s; set_state(state->get_state()); return *this; }
  84.   State<Type> get_attached() const { return state; }
  85. };
  86.  
  87. /*
  88.  
  89. We could now have a font size state and echo:
  90.  
  91. class FontSizeState: public State<int> {
  92. };
  93.  
  94. class FontSizeEcho: public Echo<int> {
  95. };
  96.  
  97.  
  98. Create a font size echo with a number range gadget:
  99.  
  100. class FontSizeNumberRange: public FontSizeEcho {
  101.   NumberRange *gadget;
  102.   void update()
  103.     { gadget->set_value(state()->get_state()); }
  104. };
  105.  
  106. */
  107.  
  108. #endif
  109.