[futurebasic] PlugIns 102 - repost

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : November 1998 : Group Archive : Group : All Groups

From: jonathan <jonathan@...>
Date: Sam, 21 Nov 98 23:05:14 +0100
'------- this is a repost with apologies to all -------
Episode 2 - In which Pooh pays a visit to Rabbit
            and the consequences of that visit

As we noted in the previous post, we are going to have to 
do a lot of different things with the plugIns. Rather than have 
code splattered around the app, we're going to keep all the 
calls in one place. So first, let's have a look at the way 
that we get in there. This is like a small local switchboard. 
Programmed in this way, the plugIn code that makes up this INCL 
file can easily be adapted and transported from project to project. 
It's not 'plugIn' code for FB, in the same way that FLTR files 
can be for PG, but it's getting close.

(In "Zombies" each INCL file is an autonomous file with a FN like 
this as the entry point. I call them 'manager' files.)

CLEAR LOCAL MODE
LOCAL FN plugInManager( cmd%, theHndl&, adrPtr&)
DIM result%

SELECT cmd%
CASE _initPlugIn
'   this will initialize initial memory needed for the plugIns
result% = FN myInitPlugIn( theHndl&)
'------------------------>
CASE _scanPlugIn
'   this finds the plugIn folder, and loads the names and
'   and references of the plugIns into the handle
result% = FN myScanPlugIn( theHndl&)
'------------------------>
CASE _loadPlugIn
'   this loads a plugIn to memory and opens it so that
'   its resources are available to the app
result% = FN myLoadPlugIn( theHndl&, adrPtr&)
'------------------------>
CASE _listPlugIn
'   this places a list of the found plugIns into a STR#
'   resource
result% = FN myListPlugIn( theHndl&, adrPtr&)
'------------------------>
CASE _namePlugIn
'   this has the name in the address pointer, it returns the
'   plugIn ref number - used when a plugIn is chosen in the list
'   by name - to translate to the ID number:
'   adrPtr& in fact points to a simple record
'   DIM RECORD npliRec
'    DIM npliRefNum%
'    DIM 31 npliName$
'   DIM END RECORD .npliRec
'   which is only declared in order to obtain the constants
'   the plugIn number is returned in npliRefNum%, of course
result% = FN myNamedPlugIn( theHndl&, adrPtr&)
'------------------------>
CASE _closePlugIn
'   this releases & disposes of the resources from the plugIns
result% = FN myClosePlugIn( theHndl&, adrPtr&)
'------------------------>
CASE _killPlugIn
'   this is the symetrical call to _initPlugIn
'   it frees up the memory grabbed at start up
result% = FN myKillPlugIn( theHndl&)
'------------------------>
END SELECT

END FN = result%

This is called from the core of the application in the following manner:
CLEAR LOCAL
LOCAL FN doInit
 DIM result%

 result% = FN plugInManager( _initPlugIn, gPlugInHndl&, 0)
 IF result% THEN GOTO "doInit:END"
...
...
...

 "doInit:END"
END FN = result%

(Of course, the calling app should react in the appropriate 
manner if result% comes back different from zero.) 

Here we can look at some items that would need to be in the 
GLOBALS file:

"constants"
'=== for PlugInManager ===
_initPlugIn  = 1
_scanPlugIn  = 2
_loadPlugIn  = 3
_listPlugIn  = 4
_namePlugIn  = 5
_closePlugIn = 6
_killPlugIn  = 7
"variables"
'=== for PlugInManager ===
DIM gPlugInHndl&

There will more lines for the GLOBALS file next time.

Let's finish today with the first function from the plugInManager
(BTW, this episode is a bit short as the following two are going 
to be a bit long, I'm also thinking about making the code available 
separately in order reduce the size.)

CLEAR LOCAL MODE
LOCAL FN myInitPlugIn( theHndl&)
 DIM result%, temp%
 DIM tempHndl&
 '
 '   This should make the handle and any other initialisation needed
 '   On leaving, the handle should be pushed into the address of the 
calling
 '   address, so that it can be referred to and called from elsewhere
 '   temp% is set large, as I don't yet allow 99 plug-ins, I can come 
back 
 '   later and resize the handle or do something else with it
 temp% = 99 *_piRec  'piRec is the length of my 'false' plugIn record
 tempHndl& = FN NEWHANDLE( temp%)
 LONG IF( SYSERROR = _noErr)
  '   zero the memory in handle
  DEF CLEARHANDLE( tempHndl&) 'clean out the memory
   & theHndl&, tempHndl&      'push the address back
 XELSE
  '   failed to create handle
 result% = _true
 END IF
END FN = result%

I'll leave it as an exercise for the reader to write the 
'myKillPlugIn' function which is the symmetrical call to the 
one just presented. (Send it to me privately please, and the 
best will be posted.)

jonathan