Some ViRSE worlds will require large data files that are too big or too frequently updated to be distributed as part of the world itself. These might include datasets for visualisation (e.g, fluid dynamics scenarios), or data generated by the world itself (e.g. video output from an internal virtual camera).
<aside> ℹ️ Small files (<5k in size) holding data such as settings are better handled with the alternative Small File Transfer System, which simply saves and retrieves data to/from the server, without involving the local file system.
</aside>
Worlds have access to dedicated local storage, and can work with files stored there using normal C# file handling facilities. Each world has a dedicated storage folder within local storage - the correct file path for this store can be obtained thus:
string myFileStorePath = Plugin_Home.virseAPI.LargeFile_GetLocalPath();
This local storage is just local – files placed there will persist between sessions on that computer, but will not be visible to other users of the world.
Where there is a requirement for files to be shared to more than one user of a world, ViRSE provides facilities for world developers to copy files in their local storage folder to/from a central server. This system is known as the Large File Transfer System.
<aside> ⚠️ If you change your world-name (the name of the Unity scene containing your world), this will also change (a) the local storage path for your world, and (b) the path used by the remote server to store your world files. This could result in your files appearing to vanish! This is one reason why it’s not a good idea to change your world name unless you really have to, but if you do do this and want to find old and apparently lost files, please contact the ViRSE team for assistance.
</aside>
Methods to interact with this system are accessed through Plugin_Home.virseAPI., and all begin with LargeFile_.
<aside> ℹ️ The system does not support subfolders within the storage folder. There is nothing stopping you creating these in your code, but you will not be able to synchronise them, so don’t!
</aside>
To upload a file from local storage to the central server, use LargeFile_StartUpload(filename), e.g.
string myFileName= "datafile.bin";
Plugin_Home.virseAPI.LargeFile_StartUpload(myFileName);
… and to download a file from the central server to local storage, use LargeFile_StartDownload(filename), e.g.
Plugin_Home.virseAPI.LargeFile_StartDownload("datafile2.bin");
Uploads and downloads are asynchronous – calling these LargeFile_Start methods begins the upload or download process, which may take some time to complete. Your code will carry on running in the meantime, and ViRSE can be setup to notify you when the transfer is complete. You can issue as many upload or download commands as you like without waiting, but these will be queued – only one will take place at once, but the next will automatically start when the last one finishes.
If your world wants to provide a progress bar to show an upload or download, use LargeFile_GetPercentProgress(filename) to determine how far the transfer has got (as an integer 0-100). For example:
private bool completed = false;
private bool started = false;
private void Update()
{
if (!started && Plugin_Home.virseAPI.LargeFile_IsSystemReady())
{
Plugin_Home.virseAPI.LargeFile_StartDownload("vitalfile.txt");
started = true;
}
if (started && !completed)
{
int progress =
Plugin_Home.virseAPI.LargeFile_GetPercentProgress("vitalfile.txt");
myProgressBar.SetValue(progress); //pass value to a visualisation system
if (progress == 100)
completed = true;
}
}
You can determine whether a transfer is complete by checking the percent progress every frame - when it reaches 100%, the file transfer has completed. Alternatively, you can set ViRSE up to notify your code when a transfer completes - see below.
<aside> ℹ️ Important - note the check of LargeFile_IsSystemReady() in the code above. The Large File Transfer System fetches a list of available files from the remote server when your world starts, and until this arrives the system is not available and will give errors if you try to use it. Ensure your code does not try to do so by avoiding calls in Start methods, and/or checking for readiness, where necessary, as shown above.
</aside>