@DATABASE "Reference"
@AUTHOR   "Paul Manias"
@NODE     "Main" "Object: Reference"

@{b}@{u}OBJECT DOCUMENTATION@{uu}@{ub}
Name:      @{"REFERENCE" LINK "Description"}
Date:      August 1998
Author:    Paul Manias
Copyright: DreamWorld Productions, 1996-1998.  All rights reserved.

@{b}@{u}CHANGES VERSION 2@{uu}@{ub}
Added:   Activate()
         Deactivate()
Removed: CheckFile()

@EndNode
---------------------------------------------------------------------------
@NODE  "Description" "Object: Reference"

@{b}@{u}OBJECT@{uu}@{ub}
Name:    Reference
Version: 2
ID:      ID_REFERENCE
Module:  @{"Kernel" LINK "GMSDev:AutoDocs/Kernel.guide/Main"}
Include: @{"system/misc.h" LINK "GMSDev:Includes/system/misc.h/Main"}
Type:    Simple
Note:    This object is mostly of a concern to object programmers and has
         no real use to normal programs.

@{b}@{u}DESCRIPTION@{uu}@{ub}
The  Reference object exists simply to save memory and resources.  A lot of
modules  exist in the system directory, but only a few are ever loaded into
memory  when  the  dpkernel  starts  up.  The rest stay on disk and are not
loaded unless a program asks for them.  You might have noticed that objects
such  as  Pictures  and  Sounds can be initialised without you ever telling
dpkernel to load the relevant modules.  How?

Whenever  FindSysObject() is called on an object that is not resident in the
system,  the  References will be searched for one that handles the required
object.   If  a  match is found, the Reference will be examined to find out
what  module  contains  the  required  object.   That module is then loaded
automatically  -  this  will  in  turn  make  the  object  available to all
programs.  Normal activity will then continue.

In  order  to  support  the  abstract  loading of objects, Load() also uses
Referenced objects to find out who recognises a particular file best.  This
is done through CheckFile() support (more on this later).

Last  of  all  is the most important point:  References are not initialised
into  the  system  using the normal methods.  Although the Reference object
supports actions like Get(), Init() and Free(), this is mainly for internal
purposes.   If  you think about it, a module that creates its own Reference
objects is actually quite pointless.

So  how are References initialised into the system?  If you get a file list
of  the  "System/References/" directory you will see a number of files with
object   names  and  a  ".ref"  extension.   These  files  are  loaded  and
initialised by the dpkernel when it loads up for the first time.  Each file
contains  specifications  for  a Reference object, and that is how they get
into  the  system.   To create your own reference file, read the "Writing a
Module" section in the general documentation.

@{b}@{u}ACTIONS@{ub}@{uu}
The Reference object supports the following actions:

   * @{"Activate()" LINK "REF_Activate()"}   - Load the referenced module/object.
     @{"Deactivate()" LINK "GMSDev:AutoDocs/Kernel.guide/Deactivate()"} - Unload the referenced module/object.
     @{"Free()" LINK "GMSDev:AutoDocs/Kernel.guide/Free()"}       - Free a Reference object.
     @{"Get()" LINK "GMSDev:AutoDocs/Kernel.guide/Get()"}        - Get a new Reference structure.
     @{"Init()" LINK "GMSDev:AutoDocs/Kernel.guide/Init()"}       - Initialise a Reference object.

@{b}@{u}STRUCTURE@{uu}@{ub}
The Reference structure consists of the following public fields:

     @{"ClassID" LINK "REF_ClassID"}   - The class that this object reference represents.
     @{"ClassName" LINK "REF_ClassName"} - Name of the class that is represented by the object.
     @{"ModName" LINK "REF_ModName"}   - Name of the module containing the object.
     @{"ModNumber" LINK "REF_ModNumber"} - Module ID number.
     @{"Next" LINK "REF_Next"}      - Next reference in the system chain.
     @{"Prev" LINK "REF_Prev"}      - Previous reference in the system chain.

@EndNode
---------------------------------------------------------------------------
@NODE "REF_ClassID" "Object: Reference"

@{b}@{u}FIELD@{uu}@{ub}
Name:   ClassID
Type:   WORD
Status: Read/Init

@{b}@{u}DESCRIPTION@{uu}@{ub}
This  field identifies the class that your object belongs to.  Examples are
ID_SCREEN, ID_PICTURE, ID_FILE and so on.  If your object is for an all-new
class then you have to register with us to obtain an ID.

This field is specified in conjunction with the ClassName field.

@{b}@{u}SEE ALSO@{uu}@{ub}
Field: @{"ClassName" LINK "REF_ClassName"}

@EndNode
---------------------------------------------------------------------------
@NODE "REF_ClassName" "Object: Reference"

@{b}@{u}FIELD@{uu}@{ub}
Name:   ClassName
Type:   BYTE *
Status: Read/Init

@{b}@{u}DESCRIPTION@{uu}@{ub}
The  ClassName  specifies  the  official  name  of  the  class that you are
representing.    The   name  of  the  class  is  closely  tied  to  the  ID
specifications.   For  example,  ID_SCREEN  has  a  class name of "Screen".
Pretty straight forward stuff.

@{b}@{u}SEE ALSO@{uu}@{ub}
Field: @{"ClassID" LINK "REF_ClassID"}

@EndNode
---------------------------------------------------------------------------
@NODE "REF_ModName" "Object: Reference"

@{b}@{u}FIELD@{uu}@{ub}
Name:   ModName
Type:   BYTE *
Status: Read/Init

@{b}@{u}DESCRIPTION@{uu}@{ub}
Setting  this  field  is only necessary if you have not specified or do not
know the ModNumber.  If you are going to set this field, make sure that you
type  the  name  correctly.   Any  module  in  the System/ directory may be
specified, e.g.  "screens.mod", so long as the module actually contains the
code for your referenced object.

@{b}@{u}SEE ALSO@{uu}@{ub}
Field: @{"ModNumber" LINK "REF_ModNumber"}

@EndNode
---------------------------------------------------------------------------
@NODE "REF_ModNumber" "Object: Reference"

@{b}@{u}FIELD@{uu}@{ub}
Name:   ModNumber
Type:   WORD
Status: Read/Init

@{b}@{u}DESCRIPTION@{uu}@{ub}
The  module  that  contains  the  code  for  your referenced object must be
specified   here.   Valid  module  numbers  are  MOD_SCREENS,  MOD_PICTURE,
MOD_SOUND    etc.    These   module   ID's   are   all   located   in   the
"system/register.h" include file.

If  the  module  does  not have a MOD number, you can use the ModName field
instead.

@{b}@{u}SEE ALSO@{uu}@{ub}
Field: @{"ModName" LINK "REF_ModName"}

@EndNode
---------------------------------------------------------------------------
@NODE "REF_Next" "Object: Reference"

@{b}@{u}FIELD@{uu}@{ub}
Name:   Next
Type:   struct Reference *
Status: Read Only.

@{b}@{u}DESCRIPTION@{uu}@{ub}
This  field  points  to  the next Reference object in the system chain.  If
there  are  no  more  objects  left,  then  this field will be set to NULL.
Generally  this  field  has  no usefulness except to the system, unless you
need  to  traverse  the  available  references for information or debugging
purposes.

@{b}@{u}SEE ALSO@{uu}@{ub}
Field: @{"Prev" LINK "REF_Prev"}

@EndNode
---------------------------------------------------------------------------
@NODE "REF_Prev" "Object: Reference"

@{b}@{u}FIELD@{uu}@{ub}
Name:   Prev
Type:   struct Reference *
Status: Read Only.

@{b}@{u}DESCRIPTION@{uu}@{ub}
This field points to the previous Reference object in the system chain.  If
this  is  the  first Reference on the chain, then this field will be set to
NULL.   Generally this field has no usefulness except to the system, unless
you  need to traverse the available references for information or debugging
purposes.

@{b}@{u}SEE ALSO@{uu}@{ub}
Field: @{"Next" LINK "REF_Next"}

@EndNode
---------------------------------------------------------------------------
@NODE "REF_Activate()" "Action: Activate(Reference)"

@{b}@{u}ACTION@{uu}@{ub}
Name:     Activate()
Synopsis: LONG Activate(*Reference)
Short:    Activating a Reference will load its related Module/Object.

@{b}@{u}DESCRIPTION@{uu}@{ub}
If  you  want  to  load  the  object  that  is associated with a particular
Reference,  you  can  Activate() it to have the system load it for you.  So
long  as this action returns successfully, the referenced object will be in
the system for future calls like Get() etc.

It is extremely important that at some point you Deactivate() the Reference
when  you  no  longer  require the object you are using.  If you fail to do
this, the module will permanently reside within system memory and may never
be expunged.  If necessary, you may do this:

  if (Activate(Reference) IS ERR_OK) {
     Object = Get(ID_OBJECT);
     Deactivate(Reference);

     ...Keep using Object...

     Free(Object);
  }

Even  though  you  have  deactivated  the  Reference  after Get(), the code
necessary   to   use  the  Object  will  stay  in  memory  until  you  call
Free(Object).

@{b}@{u}SEE ALSO@{uu}@{ub}
Kernel: @{"Activate()" LINK "GMSDev:AutoDocs/Kernel.guide/Activate()"}
        @{"Deactivate()" LINK "GMSDev:AutoDocs/Kernel.guide/Deactivate()"}

@EndNode
---------------------------------------------------------------------------
