home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / util / macsnd_dt-1.7.lha / MacSND_dt / Source / LibCode.c < prev    next >
C/C++ Source or Header  |  1994-11-25  |  6KB  |  347 lines

  1. /*
  2. **    MacSND DataType
  3. **
  4. **    Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
  5. **        Public domain
  6. **
  7. ** :ts=4
  8. */
  9.  
  10. #include "Global.h"
  11.  
  12.     // Library header data, defined in "RomTag.asm"
  13.  
  14. extern UWORD __far    LibVersion,
  15.                     LibRevision;
  16. extern UBYTE __far    LibName[],
  17.                     LibID[];
  18.  
  19.     // Vector initialization table
  20.  
  21. APTR LibVectors[] =
  22. {
  23.     LibOpen,
  24.     LibClose,
  25.     LibExpunge,
  26.     LibNull,
  27.  
  28.     GetClassEngine,
  29.  
  30.     (APTR)-1
  31. };
  32.  
  33.     // Library initialization table for MakeLibrary()
  34.  
  35. struct { ULONG DataSize; APTR Table; APTR Data; struct ClassBase * (*Init)(); } __aligned LibInitTab =
  36. {
  37.     sizeof(struct ClassBase),
  38.     LibVectors,
  39.     NULL,
  40.     LibInit
  41. };
  42.  
  43.     /* LibInit():
  44.      *
  45.      *    Initialize the library.
  46.      */
  47.  
  48. struct ClassBase * __asm __saveds
  49. LibInit(register __a0 BPTR LibSegment,register __d0 struct ClassBase *ClassBase,register __a6 struct ExecBase *ExecBase)
  50. {
  51.         // Set up the header data
  52.  
  53.     ClassBase -> LibNode . lib_Node . ln_Type    = NT_LIBRARY;
  54.     ClassBase -> LibNode . lib_Node . ln_Name    = LibName;
  55.     ClassBase -> LibNode . lib_Flags            = LIBF_CHANGED | LIBF_SUMUSED;
  56.     ClassBase -> LibNode . lib_Version            = LibVersion;
  57.     ClassBase -> LibNode . lib_Revision            = LibRevision;
  58.     ClassBase -> LibNode . lib_IdString            = LibID;
  59.  
  60.         // Remember the segment pointer
  61.  
  62.     Segment = LibSegment;
  63.  
  64.         // Remember the exec library base pointer
  65.  
  66.     SysBase = ExecBase;
  67.  
  68.         // Initialize the shared data access semaphore
  69.  
  70.     InitSemaphore(&LockSemaphore);
  71.  
  72.     return(ClassBase);
  73. }
  74.  
  75.     /* LibOpen(register __a6 struct ClassBase *ClassBase):
  76.      *
  77.      *    Open the library, as called via OpenLibrary()
  78.      */
  79.  
  80. struct ClassBase * __asm __saveds
  81. LibOpen(register __a6 struct ClassBase *ClassBase)
  82. {
  83.         // Increment usage count
  84.  
  85.     ClassBase -> LibNode . lib_OpenCnt++;
  86.  
  87.         // Prevent delayed expunge
  88.  
  89.     ClassBase -> LibNode . lib_Flags &= ~LIBF_DELEXP;
  90.  
  91.         // Is this the first initialization?
  92.  
  93.     if(ClassBase -> LibNode . lib_OpenCnt == 1)
  94.     {
  95.             // We are going to modify data while in multitasking,
  96.             // so watch out
  97.  
  98.         ObtainSemaphore(&LockSemaphore);
  99.  
  100.             // Open libraries & classes
  101.  
  102.         if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",39))
  103.         {
  104.             if(IntuitionBase = OpenLibrary("intuition.library",39))
  105.             {
  106.                 if(UtilityBase = OpenLibrary("utility.library",39))
  107.                 {
  108.                     if(IFFParseBase = OpenLibrary("iffparse.library",39))
  109.                     {
  110.                         if(DataTypesBase = OpenLibrary("datatypes.library",39))
  111.                         {
  112.                             if(SuperClassBase = OpenLibrary("datatypes/sound.datatype",39))
  113.                             {
  114.                                     // Create a new class
  115.  
  116.                                 if(SoundClass = MakeClass(ClassBase -> LibNode . lib_Node . ln_Name,SOUNDDTCLASS,NULL,NULL,NULL))
  117.                                 {
  118.                                         // Link the class dispatcher into it
  119.                                         // and keep a pointer to the library
  120.                                         // base
  121.  
  122.                                     SoundClass -> cl_Dispatcher . h_Entry    = (HOOKFUNC)ClassDispatch;
  123.                                     SoundClass -> cl_UserData                = (ULONG)ClassBase;
  124.  
  125.                                         // Make the class publicly available
  126.  
  127.                                     AddClass(SoundClass);
  128.  
  129.                                         // Release the lock
  130.  
  131.                                     ReleaseSemaphore(&LockSemaphore);
  132.  
  133.                                         // Return the library base pointer
  134.  
  135.                                     return(ClassBase);
  136.                                 }
  137.  
  138.                                     // Clean up...
  139.  
  140.                                 CloseLibrary(SuperClassBase);
  141.  
  142.                                 SuperClassBase = NULL;
  143.                             }
  144.  
  145.                             CloseLibrary(DataTypesBase);
  146.  
  147.                             DataTypesBase = NULL;
  148.                         }
  149.  
  150.                         CloseLibrary(IFFParseBase);
  151.  
  152.                         IFFParseBase = NULL;
  153.                     }
  154.  
  155.                     CloseLibrary(UtilityBase);
  156.  
  157.                     UtilityBase = NULL;
  158.                 }
  159.  
  160.                 CloseLibrary(IntuitionBase);
  161.  
  162.                 IntuitionBase = NULL;
  163.             }
  164.  
  165.             CloseLibrary(DOSBase);
  166.  
  167.             DOSBase = NULL;
  168.         }
  169.  
  170.             // Release the lock
  171.  
  172.         ReleaseSemaphore(&LockSemaphore);
  173.  
  174.             // No success
  175.  
  176.         return(NULL);
  177.     }
  178.     else
  179.         return(ClassBase);
  180. }
  181.  
  182.     /* LibExpunge(register __a6 struct ClassBase *ClassBase):
  183.      *
  184.      *    Expunge the library, remove it from memory
  185.      */
  186.  
  187. BPTR __asm __saveds
  188. LibExpunge(register __a6 struct ClassBase *ClassBase)
  189. {
  190.         // No more callers have the library open?
  191.  
  192.     if(!ClassBase -> LibNode . lib_OpenCnt && Segment)
  193.     {
  194.             // Remember the segment pointer, so it can be unloaded
  195.  
  196.         BPTR TempSegment = Segment;
  197.  
  198.             // Remove the library from the public list
  199.  
  200.         Remove(ClassBase);
  201.  
  202.             // Free the vector table and the library data
  203.  
  204.         FreeMem((BYTE *)ClassBase - ClassBase -> LibNode . lib_NegSize,ClassBase -> LibNode . lib_NegSize + ClassBase -> LibNode . lib_PosSize);
  205.  
  206.             // Return the segment pointer
  207.  
  208.         return(TempSegment);
  209.     }
  210.     else
  211.     {
  212.             // Expunge it later
  213.  
  214.         ClassBase -> LibNode . lib_Flags |= LIBF_DELEXP;
  215.  
  216.             // Can't close yet...
  217.  
  218.         return(NULL);
  219.     }
  220. }
  221.  
  222.     /* LibClose(register __a6 struct ClassBase *ClassBase):
  223.      *
  224.      *    Close the library, as called by CloseLibrary()
  225.      */
  226.  
  227. BPTR __asm __saveds
  228. LibClose(register __a6 struct ClassBase *ClassBase)
  229. {
  230.         // Decrement usage count
  231.  
  232.     if(ClassBase -> LibNode . lib_OpenCnt)
  233.         ClassBase -> LibNode . lib_OpenCnt--;
  234.  
  235.         // No more users?
  236.  
  237.     if(!ClassBase -> LibNode . lib_OpenCnt && SysBase)
  238.     {
  239.             // We are going to modify shared data,
  240.             // so watch out
  241.  
  242.         ObtainSemaphore(&LockSemaphore);
  243.  
  244.             // Clean up...
  245.  
  246.         if(SoundClass)
  247.         {
  248.             RemoveClass(SoundClass);
  249.  
  250.             FreeClass(SoundClass);
  251.  
  252.             SoundClass = NULL;
  253.         }
  254.  
  255.         if(SuperClassBase)
  256.         {
  257.             CloseLibrary(SuperClassBase);
  258.  
  259.             SuperClassBase = NULL;
  260.         }
  261.  
  262.         if(DataTypesBase)
  263.         {
  264.             CloseLibrary(DataTypesBase);
  265.  
  266.             DataTypesBase = NULL;
  267.         }
  268.  
  269.         if(UtilityBase)
  270.         {
  271.             CloseLibrary(UtilityBase);
  272.  
  273.             UtilityBase = NULL;
  274.         }
  275.  
  276.         if(IFFParseBase)
  277.         {
  278.             CloseLibrary(IFFParseBase);
  279.  
  280.             IFFParseBase = NULL;
  281.         }
  282.  
  283.         if(IntuitionBase)
  284.         {
  285.             CloseLibrary(IntuitionBase);
  286.  
  287.             IntuitionBase = NULL;
  288.         }
  289.  
  290.         if(DOSBase)
  291.         {
  292.             CloseLibrary(DOSBase);
  293.  
  294.             DOSBase = NULL;
  295.         }
  296.  
  297.             // Release the lock
  298.  
  299.         ReleaseSemaphore(&LockSemaphore);
  300.  
  301.             // Can we remove ourselves?
  302.  
  303.         if(ClassBase -> LibNode . lib_Flags & LIBF_DELEXP)
  304.             return(LibExpunge(ClassBase));
  305.     }
  306.  
  307.     return(NULL);
  308. }
  309.  
  310.     /* LibNull(register __a6 struct ClassBase *ClassBase):
  311.      *
  312.      *    Mandatory dummy function
  313.      */
  314.  
  315. LONG __asm __saveds
  316. LibNull(register __a6 struct ClassBase *ClassBase)
  317. {
  318.     return(NULL);
  319. }
  320.  
  321.     /* GetClassEngine(register __a6 struct ClassBase *ClassBase):
  322.      *
  323.      *    Get access to the class this library implements.
  324.      */
  325.  
  326. Class * __asm __saveds
  327. GetClassEngine(register __a6 struct ClassBase *ClassBase)
  328. {
  329.     Class *class;
  330.  
  331.         // Access shared data
  332.  
  333.     ObtainSemaphore(&LockSemaphore);
  334.  
  335.         // Remember the class pointer
  336.  
  337.     class = SoundClass;
  338.  
  339.         // Release the lock
  340.  
  341.     ReleaseSemaphore(&LockSemaphore);
  342.  
  343.         // Return the pointer
  344.  
  345.     return(class);
  346. }
  347.