Best practices for distributing content files if too big to embed in plugin's dll on Windows?


#1

Hello fellow JUCErs,

How do you usually distribute files that are too big to embed in the dll of the plugin, for example content like samples?

Where do you usually store these external to the dll files? I think on Mac OS X, I would probably use the Resource’s dir in the plugin’s bundle, but what should I do on Windows?

Cheers,
Nikolay


Locating sound files ressources in a generic way
#2

Content like samples which are very large you should let your customer decide where to install them to. Smaller resources:

C:\Users<USERNAME>\AppData\Roaming\Your Co. Name\

Rail


#3

Makes sense. Thanks Rail.


#4

Rail, I have a question for you - what do you do in your Debug builds? Do you (for example on Windows) still copy content to the AppData, or do you refer to it being in your project dir (or if you keep content away from the source repo - the content dir)?


#5

I have some functions to handle getting the paths for the resources…

File getAppSupportPath()
{
    File fAppSupportPath = File::getSpecialLocation (File::userApplicationDataDirectory);

    if (! isWindows())
        fAppSupportPath = fAppSupportPath.getChildFile ("Application Support");

    return fAppSupportPath;
}

 File getProductSupportPath()
{
    return getAppSupportPath().getChildFile (g_szCompanyName).getChildFile (g_szProductName);
}

etc…

The resources are kept externally in the Roaming location for testing as well… since at this point I rarely need to change them in my dev cycle. You could have a post build step to copy the resources folder.

My sample data isn’t kept near the repos or the AppData since it’s gigs worth of data.

Rail


#6

Thanks. I guess you mean BinaryData by “AppData”.
Here is what puzzles me, though - I know the data shouldn’t be in the repository, but I need to know where it is in order to copy it during PostBuild. Doesn’t this mean, that I need to hardcode a location to the content dir and with this complicate my setup for development? I guess there is no way around it, other than having a script for each OS you develop on, to setup the dependency content, or just hardcode that path in the debug code and just write a procedure for development setup specifying that you should get the content in that and such directory before you build.


#7

No, I mean: C:\Users\AppData\Roaming\Your Co. Name\ (File::userApplicationDataDirectory)

When you’re referring to “data”… are you talking about sample content or resources for the plugin? You need to consider them as separate items if you are going to have additional content available for your plugin. If you only have a fixed set of data then you can put that in your AppData\Roaming path with the rest of the plugin’s resources and simply use File::userApplicationDataDirectory to get the path.

If you’re going to have expandable content then you need a mechanism to have the installer let your plugin know where the data was installed to… and it could be in multiple different locations… and for that I use a database to keep track of all the content… It also adds much more complexity to the whole plugin since you need to handle reloading presets from different users where one may not have the same content installed as another and you need to be able to resolve a saved sample to it’s file location on any system.

I personally don’t use BinaryData for my resources so that our graphic artist can easily change the resources without needing me to recompile.

Oh, and if your content is > 8GB you’ll need a custom installer for MacOS.

Rail


#8

I meant binary data that is outside of the dll and I didn’t make any distinction.

And I was asking how do you know where the samples are during development - you just hardcode a path to your external to the project dir, or? (I mean when you build for Debug and have to copy that content to where the plugin expects it to be)

If it is samples, I am thinking of having a default location as the path above for the install, and additional user-selected location (but just one) for everything else. That way the user can select another place during installation of new content and then select that path in the plugin.


#9

My plugin knows where the samples are regardless of Debug or Release because the path(s) is/are in the Database.

If I had them as being in the Users\AppData location then I would use that path for both Debug and Release build which is what I do for my other resources. Since you can use

File::getSpecialLocation (File::userApplicationDataDirectory)

which is a constant for your test system – then you can use that path in a post-build script to copy your resources (or manually update them when required).

For MacOS I use:

File::getSpecialLocation (File::currentApplicationFile);

so basically:

     if (isWindows())
            {
            File fResourcePath = getProductSupportPath().getChildFile ("Resources");
            :
            } 
     else
            {
              File fResourcePath = File::getSpecialLocation (File::currentApplicationFile);

              fResourcePath = fResourcePath.getChildFile ("Contents").getChildFile ("Resources");
            :
            }

Rail


#10

That seems like a good approach. Never thought of keeping the files in the same location as when they are in Release.

I guess the only downside is that installing your plugin, would overwrite these binary resources?
Do you install it only on different user accounts on your development system?

Also, do you use versioning for samples?

Thanks Rail.


#11

I have a custom installer I wrote - with it’s own script – so the script defines what gets installed and which options are available on each platform… normally the resources would get replaced during a basic install… but they can also be added to by a library which can add it’s own set of resources and skin. What you decide to do depends upon your design.

We have our own proprietary monolithic file format for our samples which includes versioning.

The data can be installed to separate accounts… but the plug-ins get installed to the system root account.

Rail