home *** CD-ROM | disk | FTP | other *** search
/ Millennium Time Capsule / AC2000.BIN / disks / hbasic_1 / ooplib / ooplib.txt < prev    next >
Text File  |  1994-06-12  |  15KB  |  421 lines

  1. OOPLIB v0.01 
  2. HiSoft Basic Object Oriented Programming Library 
  3. ©1994, Data Uncertain Software - the authors of MODLIB. 
  4. Written by Craig Graham
  5.  
  6. Introduction 
  7. =============
  8.  
  9. OOPLIB provides support for dynamic class & object manipulation from HiSoft Basic2. 
  10. The facility is very limited at the moment, but will improve rapidly.
  11.  
  12. OOPLIB  runs on any atari machine up to and including the Falcon, and has a very 
  13. minimal code overhead (<2Kbytes for the library code).
  14.  
  15. Currently, the features implemented are:
  16.  
  17. o Class declaration 
  18.    - Attributes are specified in the class declaration 
  19.    - Only long int (32bit) attributes are supported at the moment. 
  20.    - Any number of attributes for a given class.
  21.  
  22. o Object instatiation 
  23.    - Create an object of a class
  24.  
  25. o Object deletion 
  26.    - Get rid of an object that you are finished with
  27.  
  28. o Attribute manipulation 
  29.    - You can set the values of an object's attributes. 
  30.    - You can read those values again.
  31.  
  32. o Services 
  33.    - These are still under developement, so at the monoment there aren't any, 
  34.      I have however, included the syntax that I intend to use for them here in 
  35.      readiness.
  36.  
  37. If this seems a little limiting, take a look at some of the example code to see 
  38. the possible applications of OOPLIB as it stands.
  39.  
  40. Classes and objects are declared & created at run time, so a class could be 
  41. created 'on-the-fly' by an application (eg. a database program could create 
  42. a record class with attributes for each record, and the class could be defined 
  43. by the user whilst the program is running depending of what file is loaded).
  44.  
  45.  
  46. INSTALLING OOPLIB 
  47. ==================
  48.  
  49. You need all the library building stuff from the HiSoft Basic distribution 
  50. discs, put it all in a directory along with the file oop.bin, then:
  51.  
  52.    buildlib.ttp gemvdi gemaes gemdos xbios bios menu oop
  53.  
  54. on a command line (I use mupfel from the gemini distribution). 
  55. This will create a new HBASIC.LIB file, which you can copy into your HiSoft 
  56. WORKING directory.....don't overwrite your original HiSoft disc's - that may be 
  57. a bad move :)
  58.  
  59.  
  60. USING OOPLIB 
  61. ==============
  62.  
  63. OOPLIB is used in the same way as the aes,vdi and xbios libraries, ie. you have 
  64. a LIBRARY statement at the start of your program. The name of the library is 
  65. OOP:
  66.  
  67. eg. 
  68.    LIBRARY "OOP"
  69.  
  70. You must also include the OOPLIB header file OOPLIB.BH at the start of your 
  71. program in order to use services. This can be omitted if you are only using 
  72. the data grouping (attributes) and ignoring the service facilities.
  73.  
  74. CREATING CLASSES 
  75. ==================
  76.  
  77. Classes are created using the following syntax:
  78.  
  79.    class "<class name>","<attribute list>", "<service list>"
  80.  
  81. Where <class name> is a name for the class :) 
  82. and <attribute list> is a comma seperated list of attribute names for the class.
  83.  
  84. eg. 
  85.    class "person","age,weight,height", ""
  86.  
  87. would declare a class called person, where each person has attributes age,weight 
  88. and height which may have values assigned to them.
  89.  
  90.  
  91. CREATING OBJECTS 
  92. ==================
  93.  
  94. You create an object (an instance of a class) using the following syntax:
  95.  
  96.    p&=object&("<class name>")
  97.  
  98. The function object&() returns a pointer to an object of type <class name>.
  99.  
  100. eg. 
  101.    craig&=object&("person")
  102.  
  103. would create an object of type person. The variable craig& would be a pointer to 
  104. the object.
  105.  
  106.  
  107. DELETING OBJECTS 
  108. ==================
  109.  
  110. An object can be disposed of when you don't need it anymore, returning the 
  111. storage it was using to the system. The syntax for this is:
  112.  
  113.    delete_object <object>&
  114.  
  115. where <object>& is a pointer to the object which you want to delete (as returned 
  116. by the object&() call).
  117.  
  118. eg. 
  119.    craig&=object&("person")      'create an object of class person 
  120.    delete_object craig&          'get rid of the object again.
  121.  
  122.  
  123. SETTING ATTRIBUTES 
  124. ====================
  125.  
  126. Once you have created an object, you can set the values of it's attributes using 
  127. the following syntax:
  128.  
  129.    o_iset <object>&, "<attribute name>", <value>
  130.  
  131. Where <object>& is a pointer to an object (as returned by the object&() call). 
  132. <attribute name> is the name of an attribute (one of the ones you specified when 
  133. you created the class). 
  134. <value> is an integer or long_integer value.
  135.  
  136. eg. 
  137.    craig&=object&("person") 
  138.    o_iset craig&,"age", 22
  139.  
  140. would set the age attribute of the object pointed to by craig& to be 22
  141.  
  142.  
  143. READING ATTRIBUTES 
  144. ====================
  145.  
  146. The value of an objects attributes may be read using the following syntax:
  147.  
  148.    v=o_iget&(<object>&, "<attribute name>")
  149.  
  150. Where <object>& is a pointer to an object (as returned by the object&() call, 
  151. and previously used in o_iset). 
  152. <attribute name> is the name of an attribute (one of the ones you specified when 
  153. you created the class).
  154.  
  155. eg. 
  156.    craigs_age=o_iget&(craig&,"age")
  157.  
  158. would read the age attribute of the object pointed to by craig& (following on 
  159. from the previous example, this would return the value 22).
  160.  
  161.  
  162. ASSIGMENTS 
  163. ============
  164.  
  165. It is important to note that the assignment '=' in HBASIC does not have the same 
  166. meaning when dealing with objects.
  167.  
  168. eg. 
  169.    a$="person" 
  170.    b$=a$
  171.  
  172. Both a$ and b$ are strings with the value of "person". Changing one string will 
  173. not affect the other at all, as the assignment operation made a copy of the 
  174. string. This is not what happens with objects.
  175.  
  176.    a&=object("person") 
  177.    b&=a&
  178.  
  179. Now a& and b& both refer to an object of class person, but in this case, they 
  180. both refer to the SAME object. So changing a attribute of b& will change the 
  181. same attribute of a&. Deleting one of them will dispose of the object, and leave 
  182. them both as invalid pointers, so care must be taken when performing this type 
  183. of manipulation.
  184.  
  185. Also, note that
  186.  
  187.    a&=object("person")        'create one object, pointed to by a& 
  188.    a&=object("person")        'create another object, and use a& to point to 
  189.                               'this one instead.
  190.  
  191. will create two objects, and the first one will continue to exist, even though 
  192. you can no longer access it via a basic variable. This fact is useful for 
  193. creating linked lists, where you only need to have a pointer to the start of the 
  194. list, and each element has a 'nextitem' attribute which points to the next 
  195. element of the list.
  196.  
  197. Objects with common attributes can be processed by the same routine 
  198. eg. two different types of linked list, both of which have a 'nextitem' attribute 
  199. which points to the next element in the list. The same routine could be used to 
  200. add a new element to the start of the list.
  201.  
  202.    LIBRARY "OOP"
  203.  
  204.    class "list1","value1,age,nextitem" ,"" 
  205.    class "list2","zap,pow,kerblam,nextitem,spam" ,""
  206.  
  207.    list1_start&=object&("list1") 
  208.    list2_start&=object&("list2")
  209.  
  210.    e1&=object&("list1") 
  211.    add_element e1&,list1_start& 
  212.    e2&=object&("list2") 
  213.    add_element e1&,list2_start&     'notice that the same routine is called to 
  214.                                     'add an element to a different class.
  215.  
  216.    END
  217.  
  218.    SUB add_element(element&, list_start&) 
  219.       o_iset element&, "nextitem", list_start& 
  220.       list_start&=element& 
  221.    END SUB
  222.  
  223. The above example would work for any class which has a nextitem attribute (in 
  224. fact you could have mixed class linked lists as well!!!).
  225.  
  226.  
  227. SERVICES 
  228. ==========
  229.  
  230. 1) SPECIFYING SERVICES 
  231. ----------------------- 
  232. Services are operations associated with an object - conceptually a service is 
  233. part of an object, and is stored together with it.
  234.  
  235. Services for a type are specified as follows:
  236.  
  237.    class "<classname>","<attrib list>", "<service list>" 
  238.    service "<classname>","<service name>", service_address&
  239.  
  240. Note that a service line is required for each service in a class.
  241.  
  242. EG.
  243.  
  244.    class "list1","value1,age,nextitem" ,"addnew" 
  245.    service "add", VARPTRS(add_element)
  246.  
  247. This example makes adding a new element to the list class from the previous 
  248. example, into a service.
  249.  
  250. 2) CALLING SERVICES 
  251. -------------------- 
  252. A service of a specific object is called using the syntax:
  253.  
  254.    use object&, "<service name>"
  255.  
  256. EG. 
  257.    a&=object("list1") 
  258.    use a&,"addnew"
  259.  
  260. 3) WRITING SERVICES 
  261. -------------------- 
  262. Inside a service routine, you have access to one object by default. The name of 
  263. this object is this&. this& is an alias for whichever object the service routine 
  264. is working for. For example, in the above example, inside the "addnew" service 
  265. call, this& would be an alias for a&, and would be of class "list1".
  266.  
  267. EG. 
  268.   LIBRARY "OOP"                                    'use the OOP library 
  269.   REM $include OOPLIB.BH                           'include the OOPLIB services 
  270.                                                    ' header
  271.  
  272.    class "list","value1,age,nextitem" ,"addnew"    'define the list class 
  273.    service "list","addnew", VARPTRS(add_element)   'specify the service
  274.  
  275.    mylist&=object&("list")                         'create a list object
  276.  
  277.    use mylist&,"addnew"                            'use the addnew service to 
  278.                                                     add another element onto the 
  279.                                                     list
  280.  
  281.    END
  282.  
  283.    SUB add_element                                 'The addnew service routine. 
  284.    STATIC n& 
  285.       n&=object("list")                               'create a new list object
  286.  
  287.       o_iset n&,"nextitem",o_iget&(this&,"nextitem")  'tack the old list onto 
  288.                                                        the new list -notice the 
  289.                                                        use of this& to 
  290.                                                        refferance the current 
  291.                                                        object. 
  292.       o_iset this&, "nextitem", n&                    'stick the new list onto 
  293.                                                        the head of the old list. 
  294.    END SUB
  295.  
  296. A good example of the use of this would be storing vector graphic objects. 
  297. You could have services which performed display, rotation, moving, warping, etc.
  298.  
  299.  
  300. FUTURES & TECHNICAL 
  301. =====================
  302.  
  303. This  section  lays  out  the  eventual  aims  of OOPLIB, and the direction I am 
  304. currently going in, and how I get there.
  305.  
  306. This is the current state of play: (example code coming up)
  307.  
  308. ============================================================================= 
  309.    DEFINT a-z
  310.  
  311.    LIBRARY "OOP"
  312.  
  313.    declare_objects 100           'initial number of objects, grows dynamicly but 
  314.                                  'better to set a bigish number here as each 
  315.                                  'dynamic grow (50 objects) eats into the OS pool.
  316.  
  317.    'Define a linked list class (the simplest dynamic structure you can get). 
  318.    ' each object has a number and a pointer to the next element in the list. 
  319.    class "linked_list", "next, number", ""
  320.  
  321.    a&=object("linked_list")      'instance of the linked list object 
  322.    o_iset a&,"number",20          'Set the value of an object attribute. 
  323.                                  'o_vset = object value set
  324.  
  325.    b&=object("linked_list")      'another instance of a linked list element 
  326.    o_iset b&,"number",30
  327.  
  328.    o_iset a&,"next",b&           'link object a to object b
  329.  
  330.    value_b=o_iget(o_vget(a&,"next"),"value") 
  331.    print value_b
  332.  
  333. ===============================================================================
  334.  
  335. Ok, not a particularly thrilling example, but you get the idea. At the moment 
  336. all that I really have is a dynamic implementation of pointers to records (PASCAL) or 
  337. pointers to structures (C). This is more reminiscent of the classes in smalltalk 
  338. which are dynamic as well.
  339.  
  340. This does allow a greater degree of expression than HB does normally, but I'd 
  341. like to add methods to the objects as well - but haven't got a clue how to call 
  342. a HB function from assembly. I could use the syntax:
  343.  
  344. service "class name", "service name", varptrs(sub name), "parameters list"
  345.  
  346. but this presents some problems with parameter passing. For the service to 
  347. address the object is fairly straight forward (set a global 'this&' with the 
  348. current object like in c++), but passing parameters to perform the equivalent of 
  349. a c++
  350.  
  351.    object.service(parameter);
  352.  
  353. is giving me a headache......what do you think ?
  354.  
  355. INTERNALS 
  356. =========== 
  357. All the OOP library code is in assembler, and doesn't do auto garbage collect to 
  358. speed things up. When an object is disposed of (delete_object a&) it leaves a 
  359. hole in the object store - a count of store usage & remaining is kept & the 
  360. garbage is taken out when storage runs out, or is forced explicitly using 
  361. 'flush_objects'.
  362.  
  363. The objects are accessed via an indirection table:
  364.  
  365.  BASIC            OBJECT      OBJECT 
  366.  VARIABLE         TABLE       STORE 
  367. +--------+     +----------+  +-------+ 
  368. |        |     |          |  |       | 
  369. |  a&    |---->| object1& |->|  O1   | 
  370. |        | +-->|          |  |       | 
  371. +--------+ |   +----------+  +-------+ 
  372. |        | |   |          |  |       | 
  373. |  b&    |-+   | object2& |->|  O2   | 
  374. |        |  +->|          |  |       | 
  375. +--------+  |  +----------+  +-------+ 
  376. |        |  |  |          |  |       | 
  377. |  c&    |-++  | object3& |  |  O3   | 
  378. |        |     |          |  |       | 
  379. +--------+     +----------+  +-------+ etc
  380.  
  381. In the example above, a& and b& both reffer to the same object. The indirection 
  382. table allows objects to move in memory transparently to the HB program using 
  383. them as the OBJECT TABLE will handle all that.
  384.  
  385. IDEALS 
  386. =======
  387.  
  388. Ideally, the eventual aim would be to provide windows style complex objects as 
  389. well by identifying the object type with an application or accessory which can 
  390. provide the services for them.
  391.  
  392. eg. Metafile object display
  393.  
  394.    class "metafile", "x,y,w,h,image", "display" 
  395.    service "metafile","display:external[kadinsky.app]","x,y,w,h"
  396.  
  397. would associate the display service for an object class "metafile" with 
  398. the program kandinsky.app so if you wanted to display a metafile at a location, 
  399. (quick switch to c++ syntax)
  400.  
  401.    // mymeta is a metafile object. 
  402.    mymeta.display(10,10,200,200);
  403.  
  404. This would call kandinsky, passing it either the metafile object or a pointer to 
  405. it, and requesting that it displayed it at (10,10) with a size of (200,200).
  406.  
  407. I am about to field a proposal on the NET & the GEM Interface mailing list about 
  408. agreeing a standard for this type of request (either derived from gemini av, or 
  409. the more advanced Xacc2 standard). Anyway, that's outside of what I originally 
  410. began talking about....views on the HB OOP library first, specificly a syntax 
  411. for specifying services (of course, a better idea would be for HiSoft to include 
  412. composite types, pointers & objects as part of the main HB language).
  413.  
  414.  
  415. Regards. 
  416. Craig Graham 
  417. (still using HB 2.0)
  418.  
  419. craig.graham@newcastle.ac.uk
  420.  
  421.