home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / OOPTUT34.ZIP / STREAMS.TXT < prev    next >
Text File  |  1992-09-09  |  10KB  |  241 lines

  1.  
  2.                      NON-VIEW OBJECTS INCLUDING STREAMS.
  3.                      -----------------------------------
  4.  
  5.  Thus far the object types considered have all been views, descendant from
  6.  TView.  The non-view types, descendant from the root object type TObject
  7.  include streams, resource files, collections and string lists.
  8.  
  9.  A stream is a generalized object for handling input and output.  TStream is
  10.  the base abstract object providing polymorphic I/O to and from a storage
  11.  device.
  12.  
  13.  A resource file is a special kind of stream where generic objects can be
  14.  indexed via string keys.
  15.  
  16.  Collections involve TCollection which implements a general set of items,
  17.  including arbitrary objects of different types.
  18.  
  19.  String lists are formed from TStringList which implements a special kind of
  20.  string resource in which strings can be accessed via a numerical index.
  21.  
  22.  
  23.  Collections.
  24.  ------------
  25.  
  26.  A TCollection type is an object designed to extend the normal behaviour of
  27.  a Pascal array.  It has built-in methods for handling the array and it also
  28.  allows dynamic sizing.  It is polymorphic by virtue of the fact that it
  29.  uses untyped pointers and so allows the collection to consist of objects,
  30.  and non-objects, of different types and sizes.
  31.  
  32.  This release from the normal strict type checking of Pascal requires care
  33.  on the part of the programmer.  Furthermore, if non-TObject items are used
  34.  in a collection, then GetItem, PutItem and FreeItem must be modified, as
  35.  done in TStringCollection.
  36.  
  37.  TCollection (pp221-226) has four fields, a pointer to an array of item
  38.  pointers, a count of the current number of items, the currently allocated
  39.  size (limit), an increment value (delta) for use when the collection has to
  40.  grow . There are 23 methods, including Init, Load, Store, Insert, Done and
  41.  three iterator methods ForEach, FirstThat, LastThat.
  42.  
  43.  The example program TVGUID17.PAS illustrates the use of collections for a
  44.  client account object type, TClient, whose data fields are Account, Name
  45.  and Phone, all of type PString.  PClient points to the object TClient,
  46.  whose constructor requires three parameters, NewAccount, NewName and
  47.  NewPhone, all of type string.  The NewStr function is used in this
  48.  constructor to provide the PString types to the data fields as shown:
  49.  
  50.       Account := NewStr(NewAccount);
  51.       Name := NewStr(NewName);
  52.       Phone := NewStr(NewPhone);
  53.  
  54.  Similarly, in the destructor TClient.Done the DisposeStr function is used,
  55.  as follows:         DisposeStr(Account);
  56.                      ...
  57.  
  58.  The New function is used to allocate and initialize the collection as
  59.  follows:
  60.  
  61.       ClientList := New(PCollection, Init(10, 5);
  62.  
  63.       pointer of type PCollection, initialized with limit of 10 and delta 5.
  64.  
  65.  One of TCollection's methods, the Insert procedure, is then used to insert
  66.  an item into the collection.  One parameter is required, the item pointer,
  67.  itself derived from the New function, including initialization, as follows:
  68.  
  69.  WITH ClientList^ DO
  70.  BEGIN
  71.    Insert(New(PClient, Init('91-100', 'Anders, Smitty', '(406) 111-2222')));
  72.    ...
  73.    ...
  74.  
  75.  The ForEach iterator method is used in the example program to assist in
  76.  printing the information relating to all clients.  Essentially a procedure
  77.  Printall, which has one parameter, a pointer C of type PCollection, is
  78.  written with a nested procedure PrintClient, which does the actual printing
  79.  for each client.  The main procedure then calls the nested one as follows:
  80.  
  81.       C^.ForEach(@PrintClient); {for each item in C}
  82.  
  83.  Details of the iterator methods are given on pages 141-143 of the Guide. 
  84.  All iterators must call FAR local procedures, as explained on page 142 of
  85.  the Guide.
  86.  
  87.  Program TVGUID18.PAS deals with sorted collections, whilst TVGUID19.PAS
  88.  relates to string collections.
  89.  
  90.  Thus far, the items of each collection are of the same type, but it is
  91.  possible to have items treated polymorphically.  Collections can store any
  92.  object that is a descendant of TObject and they can be mixed.  The example
  93.  program TVGUID20.PAS puts three different graphical objects into a
  94.  collection.  (Note the warning in the Guide and in the program about the
  95.  full graph save option -g, the use of the GRAPH unit and the path to the
  96.  BGI file).
  97.  
  98.  A procedure MakeCollection, with parameter 'List', uses a pointer P to
  99.  GraphObject types, which may be points, rectangles or circles to insert the
  100.  objects into the collection with the statement:
  101.  
  102.       List^.Insert(P);
  103.  
  104.  This graphics collection is used in an extended version of this program,
  105.  TVGUID21.PAS, which puts the collection on a stream to a disk file
  106.  GRAPHICS.STM, which is then read by another program TVGUID22.PAS, as
  107.  explained below.
  108.  
  109.  Streams.
  110.  --------
  111.  
  112.  A Turbo Vision stream is a collection of objects directed to or from a
  113.  file, EMS, a serial port or some other device.  The I/O transfer occurs at
  114.  the object level rather than the data level, which is typical of a record.
  115.  
  116.  Turbo Pascal requires that files must be typed and that the type must be
  117.  determined at compile time, but it does not allow the creation of a typed
  118.  file of objects.
  119.  
  120.  Objects probably contain virtual methods, whose address is determined at
  121.  run-time, so that storing the VMT information outside the program is
  122.  pointless.  Streams provide a simple means of storing object data outside
  123.  the program, provided the object is a descendant of TObject.
  124.  
  125.  All standard Turbo Vision objects are ready to be used with streams and all
  126.  Turbo vision streams know about the standard objects.  New object types
  127.  derived from one of the standard objects can easily be prepared for stream
  128.  use and streams alerted to their existence.
  129.  
  130.  Each Turbo Vision object type is assigned a unique registration number,
  131.  which is written to the stream ahead of the object's data.  Then when the
  132.  object is read back from the stream, the registration number is received
  133.  first and Turbo Vision knows how much data to read and what VMT to attach
  134.  to it.
  135.  
  136.  Stream registration is a simple two-step process of defining a stream
  137.  registration record which is then passed to the global procedure
  138.  RegisterType.
  139.  
  140.  Stream registration records are of type TStreamRec, which is defined as
  141.  follows:
  142.                      PStreamRec = ^TStreamRec;
  143.                      TStreamRec = RECORD
  144.                      ObjType: Word;
  145.                      VmtLink: Word;
  146.                      Load: Pointer;
  147.                      Store: Pointer;
  148.                      Next: Word;
  149.                      END;
  150.  
  151.  By convention, all Turbo Vision stream registration records are given the
  152.  same name as the corresponding object type, with the initial letter 'T'
  153.  replaced by 'R'.  Thus the registration record for TDeskTop is RDeskTop.
  154.  
  155.  The 'object type' field is a unique type-identifier number (ID), in the
  156.  range 100-65535, assigned by the programmer (0-99 reserved for the standard
  157.  objects).  The programmer must keep a library of ID numbers and make them
  158.  available to users of any units.
  159.  
  160.  The 'VmtLink' field is a link to the object's virtual method table assigned
  161.  as the offset of the type of object:
  162.  
  163.       RSomeObject.VmtLink := Ofs(TypeOf(TSomeObject)^);
  164.  
  165.  The 'Load' and 'Store' fields contain the addresses of the Load and Store
  166.  methods of the object, respectively:
  167.  
  168.       RSomeObject.Load := @TSomeObject.Load;
  169.       RSomeObject.Store := @TSomeObject.Store;
  170.  
  171.  The final field, 'Next', is assigned by 'RegisterType' (see below) and not
  172.  by the programmer.  It involves an internal linked list of stream
  173.  registration records.
  174.  
  175.  Examples of registration records for graphical objects are shown in the
  176.  programs TVGUID21.PAS AND TVGUID22.PAS, which write a stream to disk and
  177.  read the stream from disk, respectively.  Since the type TStreamRec is
  178.  already defined in OBJECTS.TPU, the registration record is a record
  179.  constant, for example:
  180.  
  181.       CONST
  182.       RGraphPoint: TStreamRec = (
  183.            ObjType: 150;
  184.            VmtLink: Ofs(TypeOf(TGraphPoint)^);
  185.            Load: @TGraphPoint.Load;
  186.            Store: @TGraphPoint.Store;
  187.  
  188.  After the construction of the stream registration record, the standard
  189.  procedure 'RegisterType' (p 364) is called with the record as its
  190.  parameter.  Thus in TVGUID21.PAS there are statements like:
  191.  
  192.       RegisterType(RGraphPoint);
  193.  
  194.  The actual reading and writing of objects to the stream is handled by
  195.  methods called Load and Store.  Each object must have these methods to be
  196.  usable by streams, but they are not called directly.  They are called by
  197.  the Get and Put methods of TStream (pp 296-7).
  198.  
  199.  Thus in the demonstration programs TVGUID21.PAS and TVGUID22.PAS the
  200.  variable declarations are:
  201.  
  202.       VAR
  203.       GraphicsList: PCollection;
  204.       GraphicsStream: TBufStream;
  205.  
  206.  TBufStream inherits the static method 'Put' from TStream, but has its own
  207.  Init method:
  208.  
  209.       CONSTRUCTOR Init(FileName: FNameStr; Mode, Size: Word);
  210.  
  211.  So the appropriate statements for putting the stream on disk are:
  212.  
  213.       GraphicsStream.Init('GRAPHICS.STM', stCreate, 1024);
  214.       GraphicsStream.Put(GraphicsList);
  215.       GraphicsStream.Done;
  216.  
  217.  Whilst for reading from the disk the statements are:
  218.  
  219.       WITH GraphicsStream DO
  220.       BEGIN
  221.       Init('GRAPHICS.STM', stOpen, 1024);
  222.       GraphicsList := PCollection(Get);
  223.       Done;
  224.       ...
  225.       END;
  226.  
  227.  
  228.  Both the two graphics demonstration programs mentioned above contain over
  229.  200 lines of statements, but most relate to graphical object programming
  230.  and the part relating to streams has been sufficiently described for the
  231.  complete understanding of these programs.
  232.  
  233.  As an exercise, the user is invited to add other graphical objects to the
  234.  program, such as a full line and an arc and to add these to the stream.
  235.  Another exercise could involve 'streaming' the objects of another program,
  236.  such as TVGUID17.PAS or any other object program.
  237.  
  238.  
  239.  STREAMS.TXT
  240.  25.3.91
  241.