home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / tvision / tvstrm / tvstream.txt
Encoding:
Text File  |  1991-10-18  |  7.0 KB  |  136 lines

  1. //========================================================================
  2. //  The following information has been provided by the Technical
  3. //  Support staff at Borland International.  It is provided as a
  4. //  courtesy and not as part of a Borland product, and as such, is
  5. //  provided without the assurance of technical support or any specific
  6. //  guarantees.
  7. //========================================================================
  8.  
  9. Topic:   Streamable objects (persistance)
  10.  
  11. Associated reading: Chapter 8, Ch. 13 p223-237, look at the source code in 
  12.     TVDemo that deals with saving and restoring the desktop.  
  13.     (TVDemo::saveDesktop() and TVDemo::storeDesktop() in tvdemo1.cpp and 
  14.     TVDemo::loadDesktop() and TVDemo::retrieveDesktop() in tvdemo3.cpp)
  15.  
  16. Discussion: How can an object be created, saved and restored at a later 
  17.     time, but still have the properties the the previous object had?.  
  18.     Furthermore, can this be done with runtime identification of what the 
  19.     object actually was?  Class TStreamable is a required base class for 
  20.     any persistant object and TView is derived from both TObject and 
  21.     TStreamable.  Thus any view that is displayed on the screen can be 
  22.     streamed (with a little modification to the class.)  If such an object 
  23.     contains instances other objects they must be streamable as well.  For 
  24.     example, a TListBox contains a TCollection*.  If this had been a 
  25.     TNSCollection* (non-streamable collection) then a TListBox could not be 
  26.     safely streamed.  We will use the a modified set of streams classes 
  27.     function from C++ streams to read/write data to auxilary storage media.  
  28.     The following is a list of steps needed to make an object streamable:
  29.  
  30.     1) The object must have TStreamable in its hierarchy.  Anything derived 
  31.        from TView already fits this.  If you are deriving a new object from 
  32.        TObject and you want to be able to stream such items, then use 
  33.        multiple inheritance to also derive it from TStreamable.
  34.  
  35.     2) Override the virtual read/write for data related to class (if the 
  36.        class is derived from something, then you will call the parents 
  37.        read/write function first.  e.g. TView::write(). )  These should be 
  38.        protected data members.  Prototypes are:
  39.  
  40.            void write( opstream& )
  41.            void *read( ipstream& )     //  returns 'this'
  42.  
  43.     3) Include a private constructor which accepts one parameter of type 
  44.        streamableInit.  Have the constructor call the parent class 
  45.        constructor and pass it the parameter streamableInit.  e.g.
  46.  
  47.            TClassName( streamableInit ) : TView( streamableInit ) { }
  48.  
  49.     4) Have a public member function that builds a 'template' for the 
  50.        object. This will be used by the stream manager to create an 
  51.        instance of an object whose data it is currently reading.
  52.  
  53.             TStreamable *TClassName::build()
  54.                 { return new TClassName( streamableInit ); }
  55.  
  56.     5) Have a public static const character pointer called name.  This 
  57.        should be initialized to a unique character string, normally the 
  58.        class name, e.g.
  59.  
  60.             const char * const TClassName::name = "TClassName";
  61.  
  62.     6) You need to register the object with the stream manager.  This 
  63.        requires creation of an object of type TStreamableClass and passing 
  64.        the name, address of the build member function and a third parameter 
  65.        to it's constructor.  The name of this instance is normally 
  66.        RClassName.  e.g.
  67.  
  68.             TStreamableClass RClassName( TClassName::name,
  69.                                          TClassName::build,
  70.                                          __DELTA( TClassName ) );
  71.  
  72.        Also, when you are using a class that descends from Turbo Vision 
  73.        objects, you have to pull in their registration instances too.  This 
  74.        done with the __link() macro.  You will have to use it for the TV 
  75.        class that you have derived your object from.  It takes a single 
  76.        argument that is the class name of the TV class involved, except the 
  77.        first letter is an 'R' instead of a 'T'.  If you derived TMyWindow 
  78.        from TWindow, you would do this:
  79.  
  80.             __link( RWindow );
  81.  
  82.     7) This is optional, but you can overload the >> and << operators for 
  83.        this object with the following lines:
  84.  
  85.             inline ipstream& operator >> (ipstream& is, TClassName & cl)
  86.                 { return is >> (TStreamable&) cl; }
  87.             inline ipstream& operator >> (ipstream& is, TClassName *& cl)
  88.                 { return is >> (void *&) cl; }
  89.             inline opstream& operator << (opstream& os, TClassName & cl)
  90.                 { return os << (TStreamable&) cl; }
  91.             inline opstream& operator << (opstream& os, TClassName * cl)
  92.                 { return os << (TStreamable *) cl; }
  93.  
  94.     As an exercise, try making the desktop objects streamable and implement 
  95.     two menu items which will save and restore the desktop.  Saving the 
  96.     contents simply requires using the forEach() member function to iterate 
  97.     through the items in the desktop, writing each out to the stream as we 
  98.     go.  Restoring is a little different because you must first clear the 
  99.     current desktop before reading in the new items.  (If you did not clear 
  100.     the current desktop, then where would those objects go when the old 
  101.     desktop was restored?)  Once the desktop is cleared, you can read in 
  102.     the items and insert them.
  103.  
  104.     Add two new menu items - Save and Restore Desktop.  Add stream support 
  105.     to the objects in the program that can go in the desktop. See the above 
  106.     discussion and the TV Demo source code for examples of streaming a 
  107.     class.  (e.g. PUZZLE.CPP and PUZZLE.H.)  The save/restore items are 
  108.     easy to implement - you don't have to cycle through the items inserted 
  109.     in the desktop, simply use the << or >> operators to send 
  110.     TProgram::deskTop out/in the stream.
  111.  
  112. Classes used:
  113.  
  114.     i/ofpstream - These are the names of the stream objects you will be
  115.       working with, rather than the normal C++ iostream library functions.
  116.  
  117.     TStreamable - Base class for all streamable objects.  Any class that
  118.       is streamed MUST be descended from this class.  (Note: Anything
  119.       derived from TView already meets this requirement.)
  120.  
  121.     TStreamableClass - An object of this type is created for the purposes of
  122.       registering a new object with the streams.  This gives the stream
  123.       manager the tools to build an object that is being read.
  124.  
  125. Macros:
  126.  
  127.     __link( RTVClassName ) - Used to register the Turbo Vision object
  128.       RTVClassName.
  129.  
  130.     __DELTA( TClassName ) - This calculates the difference in address value 
  131.       between a TClassName* and the embedded TStreamable* within.  
  132.       TClassName has multiple base classes, TStreamable and TObject, so 
  133.       these addresses are not necessarily the same.  The stream manager 
  134.       needs this delta value to be able to properly cast a TStreamable* 
  135.       back to the object it is supposed to be.
  136.