7.9 Loaders and adapters

Many Hollywood functions support loaders and adapters. The difference between a loader and an adapter is the following: A loader adds support for additional image, sound, video, icon, font, or animation formats while an adapter replaces certain parts of Hollywood with an own implementation. For example, there are display adapters which can be used to replace Hollywood's inbuilt display handler with a custom one (e.g. displays managed by SDL or OpenGL), there are network adapters which allow plugins to override Hollywood's inbuilt network implementation and of course there are file adapters.

File adapters can, for example, be used to add support for a new container formats. They can be tied to loaders in a way that the adapter provides the raw data which is then interpreted by a loader later in the process. For example, an adapter could provide support for reading files compressed by gzip. The data thus extracted by an adapter could then be handled by a loader. For example, there could be a BMP picture inside a file compressed by gzip: Hollywood would then first ask the adapter to provide the uncompressed data of the gzip file and then ask the loader to load the actual BMP picture. A file adapter could also implement data streaming from a random source, e.g. from HTTP server or other sources.

Starting with Hollywood 6.0 almost all functions that deal with files allow you to specify a loader and/or an adapter in their optional table argument. The idea behind this design is to speed up loading of external data. If you do not specify a loader or an adapter, Hollywood will ask all loaders and all adapters that are currently installed whether or not they want to open this file. Depending on how many plugins you have installed, this can slow down things quite considerably when many files need to be loaded. If you know the loader that should load your external data or the adapter that should handle it, you can pass its name to the loading function to speed up the loading process.

The string you pass to the Loader or Adapter tags accepted by the optional table argument of almost all functions that deal with files needs to be composed of at least a single loader or adapter name, or a reserved keyword describing a special loader or adapter. Multiple names and keywords have to be separated by a vertical bar character (|). The following reserved keywords are currently recognized:

Default:
This is the default operation mode. This cannot be combined with any other keywords or loader and adapter names. It must always be used independently of the others. In default operation mode, Hollywood will first ask all the loaders and adapters made available by plugins whether or not they want to handle a file. If there is no plugin which wants to handle the file, Hollywood's inbuilt handlers will be asked to deal with it. If no inbuilt handlers recognize the file, native loaders of the host OS loaders will be asked to load the file.

Inbuilt:
If this keyword is specified, Hollywood's inbuilt loaders will be asked whether or not they want to load the file. Hollywood's inbuilt loaders support the following file formats:

Inbuilt image loaders:
IFF ILBM, JPEG, PNG, GIF, and BMP.

Inbuilt anim loaders:
IFF ANIM, GIF ANIM, and AVI MJPEG.

Inbuilt sound loaders:
IFF 8SVX, IFF 16SV, RIFF WAVE, and Protracker.

Inbuilt video loaders:
CDXL video.

Native:
If this keyword is specified, Hollywood will ask the host OS to try to load the file. This is only supported for certain types and operating systems. Here is an overview:

AmigaOS:
Passing Native as the loader will use datatypes to load images, animations, and sounds. There is no native video loader.

Windows:
There are native sound and video loaders based on DirectShow and Media Foundation and native image and anim loaders based on the Windows Imaging Component.

macOS:
There are native sound, video, and image loaders based on macOS technologies. There is no native anim loader.

Linux:
There are no native loaders at all.

iOS:
There are native sound, video, and image loaders based on iOS technologies. There is no native anim loader.

Android:
There are no native loaders at all.

Plugin:
If this keyword is specified, Hollywood will ask all plugins whether they want to handle the file. Plugins will be asked in the order they were loaded by Hollywood which is rather random because it depends on the order they are returned to Hollywood by the file system. If you want to make sure a certain plugin is asked to handle a file before another plugin, you need to explicitly include the name of this plugin in the string instead of using the generic Plugin keyword.

If you use a general keyword like Plugin and you need to find out which loader or adapter was used to load a file, you can query the #ATTRLOADER or #ATTRADAPTER attributes using GetAttribute() to find out which loader or adapter opted to handle the file. Loaders and adapters may also provide a format name for the file they loaded. You can get this by querying the #ATTRFORMAT attribute.

Here are some example specifications:

 
LoadBrush(1, "test.png", {Loader = "inbuilt"})

The code above will load the specified file using the inbuilt PNG image loader. Neither image plugins nor host OS loaders will ever be asked whether they want to load this file.

 
LoadBrush(1, "test.png", {Loader = "myplugin"})

The code above will ask myplugin.hwp to load the file test.png. If myplugin.hwp fails to load the file, LoadBrush() will fail as well. It will not fall back to the inbuilt image loader. If you want LoadBrush() to fall back to the inbuilt image loader, you will have to add it to the string you pass in the Loader tag, e.g.:

 
LoadBrush(1, "test.png", {Loader = "myplugin|inbuilt"})

In that case, LoadBrush() will use the inbuilt image loader in case the loader provided by myplugin.hwp fails. The following code will work on AmigaOS, Windows and macOS but will fail on all the other platforms since they do not have a native image loader (see above):

 
LoadBrush(1, "test.png", {Loader = "native"})

On AmigaOS, test.png will be loaded via datatypes, on Windows using the Windows Imaging Component and on macOS and iOS it will be loaded via CoreGraphics. On Linux and Android, however, it will fail because Hollywood does not have a native image loader on these platforms.

You can also use the Adapter and Loader tags together, for example like this:

 
LoadBrush(1, "test.bmp.gz", {Adapter = "gzip", Loader = "inbuilt"})

The code above will first pass the file test.png.gz to gzip.hwp so that it can unzip it and then the unzipped BMP picture will be loaded using the inbuilt image loader. Of course, you could also just write the following code and it would work as well:

 
LoadBrush(1, "test.bmp.gz")

However, there is some overhead here because Hollywood will first ask all file adapters whether they want to handle test.bmp.gz and after that Hollywood will ask all image loader plugins whether they want to load the file or not. Depending on how many plugins you have installed, this can take quite some time. So if you know which adapter and loader you want to use, it will increase the loading speed if you specify loader and adapter names directly.

Also note that if you pass multiple loaders or adapters to a Hollywood function and separate them using a vertical bar character (|), the order of the individual loaders and adapters will matter. For example, the following code will first ask the plugin digibooster.hwp to open the file, and then it will ask the plugin xmp.hwp to open it:

 
OpenMusic(1, "shades.dbm", {Loader = "digibooster|xmp"})

This also allows you to prioritize certain generic loaders like Native, Inbuilt and Plugin. As described above, by default Hollywood will first ask plugin loaders, then inbuilt loaders, then native loaders to open a file. If you want native and inbuilt loaders to be asked before ones provided by plugins, you could pass the string native|inbuilt|plugin to achieve that. With such a loader string, native loaders would be asked first and plugin loaders would be asked last. You could also change the default order globally by using the SetDefaultLoader() and SetDefaultAdapter() functions, respectively. See SetDefaultLoader for details.

Another advantage of directly specifying a loader or an adapter is that it allows you to access loaders and adapters which are hidden from general usage. Plugin authors can decide to write loader or adapter plugins that are not automatically available once Hollywood has loaded the plugin but can only be used either by explicitly calling @REQUIRE on the plugin or by directly passing the plugin's name to the Loader or Adapter tags. So these two tags can also be used to address hidden plugins directly.

Starting with version 8.0, Hollywood also supports network adapters now. Those adapters follow the same principle as file and directory adapters, i.e. they can be used to route the functions of Hollywood's network library through custom handlers implemented as Hollywood plugins. Network adapters, for example, can enhance the functionality of DownloadFile() and UploadFile() to support TLS/SSL connections as well. They could also be used to implement support for completely different network types and protocols because Hollywood's network adapter interface is completely abstracted from any kind of specific networking API, which makes it very flexible to adapt to new environments.

Starting with version 10.0, Hollywood also supports filesystem adapters. Filesystem adapters can be used to replace core filesystem features like renaming files and directories, creating directories, moving files and directories, etc. with customized ones. Several Hollywood functions support filesystem adapters, e.g. CopyFile(), MakeDirectory(), or DeleteFile().


Show TOC