home *** CD-ROM | disk | FTP | other *** search
- OOPLIB v0.01
- HiSoft Basic Object Oriented Programming Library
- ©1994, Data Uncertain Software - the authors of MODLIB.
- Written by Craig Graham
-
- Introduction
- =============
-
- OOPLIB provides support for dynamic class & object manipulation from HiSoft Basic2.
- The facility is very limited at the moment, but will improve rapidly.
-
- OOPLIB runs on any atari machine up to and including the Falcon, and has a very
- minimal code overhead (<2Kbytes for the library code).
-
- Currently, the features implemented are:
-
- o Class declaration
- - Attributes are specified in the class declaration
- - Only long int (32bit) attributes are supported at the moment.
- - Any number of attributes for a given class.
-
- o Object instatiation
- - Create an object of a class
-
- o Object deletion
- - Get rid of an object that you are finished with
-
- o Attribute manipulation
- - You can set the values of an object's attributes.
- - You can read those values again.
-
- o Services
- - These are still under developement, so at the monoment there aren't any,
- I have however, included the syntax that I intend to use for them here in
- readiness.
-
- If this seems a little limiting, take a look at some of the example code to see
- the possible applications of OOPLIB as it stands.
-
- Classes and objects are declared & created at run time, so a class could be
- created 'on-the-fly' by an application (eg. a database program could create
- a record class with attributes for each record, and the class could be defined
- by the user whilst the program is running depending of what file is loaded).
-
-
- INSTALLING OOPLIB
- ==================
-
- You need all the library building stuff from the HiSoft Basic distribution
- discs, put it all in a directory along with the file oop.bin, then:
-
- buildlib.ttp gemvdi gemaes gemdos xbios bios menu oop
-
- on a command line (I use mupfel from the gemini distribution).
- This will create a new HBASIC.LIB file, which you can copy into your HiSoft
- WORKING directory.....don't overwrite your original HiSoft disc's - that may be
- a bad move :)
-
-
- USING OOPLIB
- ==============
-
- OOPLIB is used in the same way as the aes,vdi and xbios libraries, ie. you have
- a LIBRARY statement at the start of your program. The name of the library is
- OOP:
-
- eg.
- LIBRARY "OOP"
-
- You must also include the OOPLIB header file OOPLIB.BH at the start of your
- program in order to use services. This can be omitted if you are only using
- the data grouping (attributes) and ignoring the service facilities.
-
- CREATING CLASSES
- ==================
-
- Classes are created using the following syntax:
-
- class "<class name>","<attribute list>", "<service list>"
-
- Where <class name> is a name for the class :)
- and <attribute list> is a comma seperated list of attribute names for the class.
-
- eg.
- class "person","age,weight,height", ""
-
- would declare a class called person, where each person has attributes age,weight
- and height which may have values assigned to them.
-
-
- CREATING OBJECTS
- ==================
-
- You create an object (an instance of a class) using the following syntax:
-
- p&=object&("<class name>")
-
- The function object&() returns a pointer to an object of type <class name>.
-
- eg.
- craig&=object&("person")
-
- would create an object of type person. The variable craig& would be a pointer to
- the object.
-
-
- DELETING OBJECTS
- ==================
-
- An object can be disposed of when you don't need it anymore, returning the
- storage it was using to the system. The syntax for this is:
-
- delete_object <object>&
-
- where <object>& is a pointer to the object which you want to delete (as returned
- by the object&() call).
-
- eg.
- craig&=object&("person") 'create an object of class person
- delete_object craig& 'get rid of the object again.
-
-
- SETTING ATTRIBUTES
- ====================
-
- Once you have created an object, you can set the values of it's attributes using
- the following syntax:
-
- o_iset <object>&, "<attribute name>", <value>
-
- Where <object>& is a pointer to an object (as returned by the object&() call).
- <attribute name> is the name of an attribute (one of the ones you specified when
- you created the class).
- <value> is an integer or long_integer value.
-
- eg.
- craig&=object&("person")
- o_iset craig&,"age", 22
-
- would set the age attribute of the object pointed to by craig& to be 22
-
-
- READING ATTRIBUTES
- ====================
-
- The value of an objects attributes may be read using the following syntax:
-
- v=o_iget&(<object>&, "<attribute name>")
-
- Where <object>& is a pointer to an object (as returned by the object&() call,
- and previously used in o_iset).
- <attribute name> is the name of an attribute (one of the ones you specified when
- you created the class).
-
- eg.
- craigs_age=o_iget&(craig&,"age")
-
- would read the age attribute of the object pointed to by craig& (following on
- from the previous example, this would return the value 22).
-
-
- ASSIGMENTS
- ============
-
- It is important to note that the assignment '=' in HBASIC does not have the same
- meaning when dealing with objects.
-
- eg.
- a$="person"
- b$=a$
-
- Both a$ and b$ are strings with the value of "person". Changing one string will
- not affect the other at all, as the assignment operation made a copy of the
- string. This is not what happens with objects.
-
- a&=object("person")
- b&=a&
-
- Now a& and b& both refer to an object of class person, but in this case, they
- both refer to the SAME object. So changing a attribute of b& will change the
- same attribute of a&. Deleting one of them will dispose of the object, and leave
- them both as invalid pointers, so care must be taken when performing this type
- of manipulation.
-
- Also, note that
-
- a&=object("person") 'create one object, pointed to by a&
- a&=object("person") 'create another object, and use a& to point to
- 'this one instead.
-
- will create two objects, and the first one will continue to exist, even though
- you can no longer access it via a basic variable. This fact is useful for
- creating linked lists, where you only need to have a pointer to the start of the
- list, and each element has a 'nextitem' attribute which points to the next
- element of the list.
-
- Objects with common attributes can be processed by the same routine
- eg. two different types of linked list, both of which have a 'nextitem' attribute
- which points to the next element in the list. The same routine could be used to
- add a new element to the start of the list.
-
- LIBRARY "OOP"
-
- class "list1","value1,age,nextitem" ,""
- class "list2","zap,pow,kerblam,nextitem,spam" ,""
-
- list1_start&=object&("list1")
- list2_start&=object&("list2")
-
- e1&=object&("list1")
- add_element e1&,list1_start&
- e2&=object&("list2")
- add_element e1&,list2_start& 'notice that the same routine is called to
- 'add an element to a different class.
-
- END
-
- SUB add_element(element&, list_start&)
- o_iset element&, "nextitem", list_start&
- list_start&=element&
- END SUB
-
- The above example would work for any class which has a nextitem attribute (in
- fact you could have mixed class linked lists as well!!!).
-
-
- SERVICES
- ==========
-
- 1) SPECIFYING SERVICES
- -----------------------
- Services are operations associated with an object - conceptually a service is
- part of an object, and is stored together with it.
-
- Services for a type are specified as follows:
-
- class "<classname>","<attrib list>", "<service list>"
- service "<classname>","<service name>", service_address&
-
- Note that a service line is required for each service in a class.
-
- EG.
-
- class "list1","value1,age,nextitem" ,"addnew"
- service "add", VARPTRS(add_element)
-
- This example makes adding a new element to the list class from the previous
- example, into a service.
-
- 2) CALLING SERVICES
- --------------------
- A service of a specific object is called using the syntax:
-
- use object&, "<service name>"
-
- EG.
- a&=object("list1")
- use a&,"addnew"
-
- 3) WRITING SERVICES
- --------------------
- Inside a service routine, you have access to one object by default. The name of
- this object is this&. this& is an alias for whichever object the service routine
- is working for. For example, in the above example, inside the "addnew" service
- call, this& would be an alias for a&, and would be of class "list1".
-
- EG.
- LIBRARY "OOP" 'use the OOP library
- REM $include OOPLIB.BH 'include the OOPLIB services
- ' header
-
- class "list","value1,age,nextitem" ,"addnew" 'define the list class
- service "list","addnew", VARPTRS(add_element) 'specify the service
-
- mylist&=object&("list") 'create a list object
-
- use mylist&,"addnew" 'use the addnew service to
- add another element onto the
- list
-
- END
-
- SUB add_element 'The addnew service routine.
- STATIC n&
- n&=object("list") 'create a new list object
-
- o_iset n&,"nextitem",o_iget&(this&,"nextitem") 'tack the old list onto
- the new list -notice the
- use of this& to
- refferance the current
- object.
- o_iset this&, "nextitem", n& 'stick the new list onto
- the head of the old list.
- END SUB
-
- A good example of the use of this would be storing vector graphic objects.
- You could have services which performed display, rotation, moving, warping, etc.
-
-
- FUTURES & TECHNICAL
- =====================
-
- This section lays out the eventual aims of OOPLIB, and the direction I am
- currently going in, and how I get there.
-
- This is the current state of play: (example code coming up)
-
- =============================================================================
- DEFINT a-z
-
- LIBRARY "OOP"
-
- declare_objects 100 'initial number of objects, grows dynamicly but
- 'better to set a bigish number here as each
- 'dynamic grow (50 objects) eats into the OS pool.
-
- 'Define a linked list class (the simplest dynamic structure you can get).
- ' each object has a number and a pointer to the next element in the list.
- class "linked_list", "next, number", ""
-
- a&=object("linked_list") 'instance of the linked list object
- o_iset a&,"number",20 'Set the value of an object attribute.
- 'o_vset = object value set
-
- b&=object("linked_list") 'another instance of a linked list element
- o_iset b&,"number",30
-
- o_iset a&,"next",b& 'link object a to object b
-
- value_b=o_iget(o_vget(a&,"next"),"value")
- print value_b
-
- ===============================================================================
-
- Ok, not a particularly thrilling example, but you get the idea. At the moment
- all that I really have is a dynamic implementation of pointers to records (PASCAL) or
- pointers to structures (C). This is more reminiscent of the classes in smalltalk
- which are dynamic as well.
-
- This does allow a greater degree of expression than HB does normally, but I'd
- like to add methods to the objects as well - but haven't got a clue how to call
- a HB function from assembly. I could use the syntax:
-
- service "class name", "service name", varptrs(sub name), "parameters list"
-
- but this presents some problems with parameter passing. For the service to
- address the object is fairly straight forward (set a global 'this&' with the
- current object like in c++), but passing parameters to perform the equivalent of
- a c++
-
- object.service(parameter);
-
- is giving me a headache......what do you think ?
-
- INTERNALS
- ===========
- All the OOP library code is in assembler, and doesn't do auto garbage collect to
- speed things up. When an object is disposed of (delete_object a&) it leaves a
- hole in the object store - a count of store usage & remaining is kept & the
- garbage is taken out when storage runs out, or is forced explicitly using
- 'flush_objects'.
-
- The objects are accessed via an indirection table:
-
- BASIC OBJECT OBJECT
- VARIABLE TABLE STORE
- +--------+ +----------+ +-------+
- | | | | | |
- | a& |---->| object1& |->| O1 |
- | | +-->| | | |
- +--------+ | +----------+ +-------+
- | | | | | | |
- | b& |-+ | object2& |->| O2 |
- | | +->| | | |
- +--------+ | +----------+ +-------+
- | | | | | | |
- | c& |-++ | object3& | | O3 |
- | | | | | |
- +--------+ +----------+ +-------+ etc
-
- In the example above, a& and b& both reffer to the same object. The indirection
- table allows objects to move in memory transparently to the HB program using
- them as the OBJECT TABLE will handle all that.
-
- IDEALS
- =======
-
- Ideally, the eventual aim would be to provide windows style complex objects as
- well by identifying the object type with an application or accessory which can
- provide the services for them.
-
- eg. Metafile object display
-
- class "metafile", "x,y,w,h,image", "display"
- service "metafile","display:external[kadinsky.app]","x,y,w,h"
-
- would associate the display service for an object class "metafile" with
- the program kandinsky.app so if you wanted to display a metafile at a location,
- (quick switch to c++ syntax)
-
- // mymeta is a metafile object.
- mymeta.display(10,10,200,200);
-
- This would call kandinsky, passing it either the metafile object or a pointer to
- it, and requesting that it displayed it at (10,10) with a size of (200,200).
-
- I am about to field a proposal on the NET & the GEM Interface mailing list about
- agreeing a standard for this type of request (either derived from gemini av, or
- the more advanced Xacc2 standard). Anyway, that's outside of what I originally
- began talking about....views on the HB OOP library first, specificly a syntax
- for specifying services (of course, a better idea would be for HiSoft to include
- composite types, pointers & objects as part of the main HB language).
-
-
- Regards.
- Craig Graham
- (still using HB 2.0)
-
- craig.graham@newcastle.ac.uk
-
-