home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / OBJFUNCS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-05  |  6.6 KB  |  235 lines

  1. /*
  2.     objfuncs.c    7/29/88
  3.  
  4.     % Object primitive definitions.
  5.     Also contains common object dispatch function.
  6.  
  7.     by Ted.
  8.  
  9.     OWL 1.2
  10.     Copyright (c) 1988, by Oakland Group, Inc.
  11.     ALL RIGHTS RESERVED.
  12.  
  13.     Revision History:
  14.     -----------------
  15.      8/09/88 jmd    Rewrote with new scheme
  16.      9/12/88 jmd    Added in and out data to objects
  17.     10/14/88 jdc    Now passes opendata along in the OBJM_GETDATASIZE
  18.                         message, this allows for varible size obj_od!
  19.     11/20/88 jmd    Added ID to obj struct
  20.     11/30/88 jmd    Added 0 preload to obj_Open
  21.      3/23/89 ted    Added xdata stuff
  22.      7/07/89 gam    Changed NULL to FNULL where necessary
  23.      8/06/89 ted    Changed omalloc to ocalloc for object alloc.
  24.  
  25.     11/06/89 jmd    removed DoRaw macros
  26.     12/12/89 jmd    added object names
  27.      1/21/89 jdc    changed oslist stuff
  28.      3/28/90 jmd    ansi-fied
  29.      6/22/90 ted    added "void" to no-parameter function per ansii.
  30.      7/29/90 jmd    added auxiliary func to objects, added objDoAux, obj_SetAux
  31.      9/07/90 jmd    renamed oslist stuff
  32.     12/05/90 jmd    now sends the AUX_END message before closing the object
  33. */
  34.  
  35. #include "oakhead.h"
  36. #include "commonod.h"
  37.  
  38. /* -------------------------------------------------------------------------- */
  39. /* the object name list */
  40. OGLOBAL    oslist_type objnamelist = NULL;
  41.  
  42. void oak_Close(void)
  43. /*
  44.     Close down the object name list, if there is one.
  45. */
  46. {
  47.     if (objnamelist != NULL) {
  48.         oslist_Close(objnamelist);
  49.         objnamelist = NULL;
  50.     }
  51. }
  52.  
  53. /* -------------------------------------------------------------------------- */
  54.  
  55. obj_type obj_Open(class_fptr dispatch, VOID *opendata)
  56. /*
  57.     Create a new object.
  58.     dispatch is the object's dispatch function
  59.     opendata is creation data that is passed to the dispatch function
  60.     (opendta may be removed in the future, it is not advised to use it)
  61.     Uses the object ID as an omalloc tag.
  62. */
  63. {
  64.     obj_type     obj;
  65.     ogds_struct ogds;
  66.  
  67.     /* Get size of object data (preload it to -1 for safety check) */
  68.     ogds.xdsize = (unsigned) -1;
  69.     ogds.odsize = (unsigned) -1;
  70.     ogds.id = 0;
  71.  
  72.     /* we don't have an object yet, call the dispatch function directly */
  73.     if ((*dispatch)(NULL, OBJM_GETDATASIZE, opendata, &ogds) == FALSE) {
  74.         return(NULL);
  75.     }
  76.  
  77.     /* Make sure both xdsize and odsize were initialized */
  78.     owl_Assert((ogds.odsize != (unsigned) -1), OE_OO_ODSIZE);
  79.     owl_Assert((ogds.xdsize != (unsigned) -1), OE_OO_XDSIZE);
  80.     owl_Assert((ogds.id != 0), OE_OO_ID);
  81.  
  82.     /* Allocate object and object data */
  83.     obj = (obj_type) ocalloc(ogds.id,
  84.                         sizeof(struct obj_struct) + ogds.xdsize + ogds.odsize,
  85.                         sizeof(byte));
  86.     if (obj == NULL) {
  87.         return(NULL);
  88.     }
  89.     /* Initialize object elements */
  90.     obj->dispatch = dispatch;
  91.  
  92.     obj->od = (VOID *) (((char *) obj_getxd(obj)) + ogds.xdsize);
  93.     /* Initialize object xdata (= id) */
  94.     /* NOTE: This line assumes that the common_xd is first in the nested _xd */
  95.     /* structures. Memory trashing will occur if this is not the case. */
  96.     /* This is the idea the xdata scheme is based on anyway. */
  97.     obj_setid(obj, ogds.id);
  98.  
  99.     /* init object to no name */
  100.     obj_SetNameHandle(obj, -1);
  101.  
  102.     /* Initialize object odata (= self) */
  103.     /* NOTE: This line assumes that the common_od is first in the nested _od */
  104.     /* structures. Memory trashing will occur if this is not the case. */
  105.     ((common_od *) obj->od)->self = obj;
  106.  
  107.     /* Call object's OPEN message */
  108.     /* NOTE: ogds is passed in place of outdata because outdata is not needed, */
  109.     /* and ogds can be used to kluge variable-size xd/od's with inheritance. */
  110.     /* (Implicit here is that opendata is not touched between GETDATASIZE and */
  111.     /*  OPEN so that each level in OPEN can re-compute the variable data it  */
  112.     /*  requested in GETDATASIZE.) */
  113.  
  114.     if (obj_Do(obj, OBJM_OPEN, opendata, &ogds) == FALSE) {
  115.         ofree(OA_OBJ, (VOID *) obj);
  116.         return(NULL);
  117.     }
  118.     return(obj);
  119. }
  120. /* -------------------------------------------------------------------------- */
  121.  
  122. void obj_Close(obj_type obj)
  123. /*
  124.     Destroy an object.
  125. */
  126. {
  127.     /* remove object from the name list */
  128.     obj_RemoveName(obj);
  129.  
  130.     /* close the aux function (send the AUX_END message) */
  131.     obj_SetAux(obj, FNULL);
  132.  
  133.     /* call object's CLOSE message */
  134.     obj_Do(obj, OBJM_CLOSE, NULL, NULL);
  135.  
  136.     /* set object elements to bad values
  137.        in case someone accidentally tries to use it after it gets closed */
  138.     obj->dispatch = FNULL;
  139.     obj_setid(obj, OA_NOTAG - 1);
  140.  
  141.     /* release storage */
  142.     ofree(OA_OBJ, (VOID *) obj);
  143. }
  144.  
  145. /* -------------------------------------------------------------------------- */
  146.  
  147. boolean obj_Who(obj_type obj, int type)
  148. /*
  149.     Returns TRUE if the object is of the given type
  150. */
  151. {
  152.     return((obj == NULL) ? 
  153.         FALSE : (boolean) obj_Do(obj, OBJM_WHO, &type, NULL));
  154. }
  155.  
  156. /* -------------------------------------------------------------------------- */
  157.  
  158. int objreq_Null(VOID *objdata, int msg, VOID *indata, VOID *outdata)
  159. /*
  160.     Empty object request message handler. Used for initializing function
  161.     pointers so they can point somewhere.
  162. */
  163. {
  164.     oak_notused(objdata);
  165.     oak_notused(msg);
  166.     oak_notused(indata);
  167.     oak_notused(outdata);
  168.  
  169.     return(FALSE);
  170. }
  171.  
  172. /* -------------------------------------------------------------------------- */
  173.  
  174. void obj_RemoveName(obj_type obj)
  175. /*
  176.     Removes an object name.
  177.     Removes the object name from the name list.
  178.     If the name is used by another object, doesn't remove the object,
  179.     instead it decrements the hit count for the name.
  180. */
  181. {
  182.     objname_struct *oldname;
  183.  
  184.     oldname = (objname_struct *)oslist_GetData(objnamelist, obj_GetNameHandle(obj));
  185.  
  186.     if (oldname != NULL) {
  187.         if (oldname->hits <= 1) {        /* only instance, delete old name */ 
  188.             oslist_Delete(objnamelist, obj_GetNameHandle(obj));
  189.         }    
  190.         else {
  191.             oldname->hits--;            /* reduce hit count */
  192.             oldname->obj = NULL;        /* reset name data */
  193.         }
  194.     }
  195.  
  196.     obj_SetNameHandle(obj, -1);
  197. }
  198.  
  199. /* -------------------------------------------------------------------------- */
  200.  
  201. int obj_DoAux(obj_type obj, int msg, VOID *indata, VOID *outdata)
  202. /*
  203.     Call the obj's auxillary function.
  204.     Returns 1 if there is no auxillary function
  205.     else it returns the auxillary function's return value.
  206. */
  207. {
  208.     if (obj == NULL || obj_GetAux(obj) == FNULL) {
  209.         return(1);
  210.     }
  211.  
  212.     return((*(obj_GetAux(obj)))(obj, msg, indata, outdata));
  213. }
  214.  
  215. /* -------------------------------------------------------------------------- */
  216.  
  217. void obj_SetAux(obj_type obj, aux_fptr aux)
  218. /*
  219.     sets the obj's auxiliary function
  220.     sends appropriate AUXSTART and AUXEND messages
  221.     call with aux == FNULL to end aux function action
  222. */
  223. {
  224.     if (obj_GetAux(obj) != FNULL) {
  225.         obj_DoAux(obj, AUX_END, NULL, NULL);
  226.         obj_setox(obj, FNULL);
  227.     }
  228.  
  229.     if (aux != FNULL) {
  230.         obj_setox(obj, aux);
  231.         obj_DoAux(obj, AUX_START, NULL, NULL);
  232.     }        
  233. }
  234.  
  235.