#Save Load Docs
##Overview
The __Runtime Save & Load__ (RTSL) subsystem is required for saving and managing scenes, assets and projects at runtime and consists of three main parts:
* [Persistent Classes](#persistent-classes) - this part allows you to choose what to serialize and generate persistent classes for serialization.
* [Asset Libraries](#asset-library) - this part allows you to create and manage assets, as well as provide information to the RTSL to identify these assets.
* [Project](#project) - this part provides api to interact with RTSL.
!!! note
RTSL use [protobuf.net](https://github.com/mgravell/protobuf-net) for serialization.

##Getting Started
After importing RTSL you will see the configuration window:

After clicking "Build All", several folders will be created under __/Battlehub/RTSL_Data__

* __Scripts__ for [serializable persistent classes](#persistent-classes).
* __Custom Implementation__ for user defined persistent classes.
* __Mappings__ for mappings between types that must be stored and serializable persistent types.
* __Libraries__ for [asset libraries and shader profiles](#asset-library).
!!! note
__RTSLTypeModel.dll__ contains [protobuf-net](https://github.com/mgravell/protobuf-net) type model. Due to [unity scripting restrictions](https://docs.unity3d.com/Manual/ScriptingRestrictions.html), runtime type model need to be pre-complied before
using at runtime.
1. Create new scene
2. Drag and Drop __Assets/Battlehub/RTDemoGame/Prefabs/Game.prefab__ to hierarchy.

3. Click Tools->Runtime SaveLoad->Libraries->__Collect Scene Dependencies__

4. Create Game Object, then add Assets/Battlehub/RTSL/Interface/__Project__ and Assets/Battlehub/RTSL/Interface/__RTSLIgnore__ components.

5. Create __RTSLTest__ script.
6. Hit play.
7. Save scene using 'M' key.
8. Load scene using 'L' key.
``` C#
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using Battlehub.RTCommon;
using Battlehub.RTSL.Interface;
public class RTSLTest : MonoBehaviour
{
IProject m_project;
IEnumerator Start()
{
m_project = IOC.Resolve();
yield return m_project.OpenProject("My Project");
yield return m_project.CreateFolder("Scenes/Demo");
}
IEnumerator SaveScene()
{
ProjectAsyncOperation ao = m_project.Save("Scenes/Demo/Scene", SceneManager.GetActiveScene());
yield return ao;
if(ao.Error.HasError)
{
Debug.LogError(ao.Error.ToString());
}
}
IEnumerator LoadScene()
{
ProjectAsyncOperation ao = m_project.Load("Scenes/Demo/Scene");
yield return ao;
if (ao.Error.HasError)
{
Debug.LogError(ao.Error.ToString());
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.M))
{
StartCoroutine(SaveScene());
}
if (Input.GetKeyDown(KeyCode.L))
{
if (m_project.Exist("Scenes/Demo/Scene"))
{
StartCoroutine(LoadScene());
}
}
}
}
```
Saved scene can be found in [__PersistentDataPath__](https://docs.unity3d.com/ScriptReference/Application-persistentDataPath.html)__/My Project/Assets/Scenes/Demo folder__.
!!! note
Only few persistent classes enabled and could be saved by default. Use [Persistent Classes Editor Window](#persistent-classes) to enable more.
!!! note
Demo scene can be found in __Assets/Battlehub/RTSL/Demo__ folder.
##Persistent Classes
__Persistent Class__ is a class derived from __Persistent Surrogate__ and having the __[ProtoContract]__ attribute. The main purpose of the persistent classes is to give you full control over what and how to save, without having to use reflection and without writing a lot of code.
To open persistent classes editor, click Tools->Runtime SaveLoad->__Persistent Classes->Edit__.

Here is the persistent classes editor window:

This window allow you:
* Search for types you want to save.
* Select properties you want to save.
* Generate C# code of persistent classes.
After clicking the __"Create Persistent Classes"__ button the following will occur:
1. Persistent classes will be created in
__Assets/Battlehub/RTSL_Data/Scripts/PersistentClasses__.

2. The editor window state will be saved in
__Assets/Battlehub/RTSL_Data/Mappings/Editor__.

3. Custom Implementation will be created in __.../RTSL_Data/Scripts/CustomImplementation__.

!!! note
To ensure forward compatibility of saved files, never delete the __ClassMappingStorage__ and __SurrogatesMappingsStorage__ prefabs !!!
##How To: Create Custom Persistent Class
In some cases, it is not possible to get all the data to be saved using public properties and fields. For example, data can only be obtained using the methods.
If you have to write your own code to save and load data, follow these steps:
1. Open Persistent Classes Editor.
2. Find and select required type.
3. Select __"Custom Implementation"__

6. You should see following:
``` C#
#if !RTSL_MAINTENANCE
using Battlehub.RTSL;
namespace UnityEngine.Battlehub.SL2
{
[CustomImplementation]
public partial class PersistentJoint
{
/*
public override void ReadFrom(object obj)
{
base.ReadFrom(obj);
}
public override object WriteTo(object obj)
{
return base.WriteTo(obj);
}
public override void GetDeps(GetDepsContext context)
{
base.GetDeps(context);
}
public override void GetDepsFrom(object obj, GetDepsFromContext context)
{
base.GetDepsFrom(obj, context);
}
*/
}
}
#endif
```
There are four methods that can be implemented:
* `void ReadFrom(object obj)` - invoked before serialization. Read the data from obj and save it to the fields of the persistent object.
* `object WriteTo(object obj)` - invoked after deserialization. Write stored data to obj.
* `void GetDeps(GetDepsContext context)` - return identifiers of dependencies.
* `void GetDepsFrom(object obj, GetDepsFromContext context)` - get dependencies from obj.
Implementation of PersistentJoint may look like this:
``` C#
#if !RTSL_MAINTENANCE
using Battlehub.RTSL;
namespace UnityEngine.Battlehub.SL2
{
[CustomImplementation]
public partial class PersistentJoint
{
[ProtoBuf.ProtoMember(1)]
private long m_connectedBody;
[ProtoBuf.ProtoMember(2)]
private PersistentVector3 m_anchor;
//..... more fields
public override void ReadFrom(object obj)
{
base.ReadFrom(obj);
Joint joint = (Joint)obj;
if(joint == null)
{
return;
}
m_connectedBody = ToID(joint.connectedBody);
m_anchor = joint.anchor;
//... read other fields
}
public override object WriteTo(object obj)
{
obj = base.WriteTo(obj);
Joint joint = (Joint)obj;
if (joint == null)
{
return obj;
}
joint.connectedBody = FromID(m_connectedBody);
joint.anchor = m_anchor;
//... write other fields
return joint;
}
public override void GetDeps(GetDepsContext context)
{
base.GetDeps(context);
AddDep(m_connectedBody, context);
//... get other dependencies
}
public override void GetDepsFrom(object obj, GetDepsFromContext context)
{
base.GetDepsFrom(obj, context);
Joint joint = (Joint)obj;
if (joint == null)
{
return;
}
AddDep(joint.connectedBody, context);
//... get other dependencies
}
}
}
#endif
```
!!! note
Click __Tools-> Runtime SaveLoad-> Build All__ each time you have finished making changes to persistent classes and are ready to build the application.
##Asset Library
Game objects in any scene refer assets such as materials, meshes, textures, etc.
Identifiers of these assets obtained using GetInstanceID() method do not remain constant and can change.
In contrast, __Asset libraries__ are used to store unique asset identifiers that never change.
There are two special asset libraries:
* Built-in asset library - contains Unity build-in assets.
* Scene asset library - contains assets referenced by scene Game Objects.
The former library created automatically by clicking __Tools->Runtime SaveLoad->Libraries->Update Built-In Asset Library__
The latter created by opening scene and clicking __Tools->Runtime SaveLoad->Libraries->Collect Scene Dependencies__

!!! note
Scene asset libraries are referenced using the scene name. This means that scenes must have unique names.
!!! note
Click __Tools->Runtime SaveLoad->Libraries->Collect Scene Dependencies__ each time you have finished making changes to scene and are ready to run the application.
##How To: Create Asset Library
If the built-in asset library and scene dependency library are not sufficient,
and the new resources must be [Resource.Loaded](https://docs.unity3d.com/ScriptReference/Resources.Load.html) at runtime, you can create
a new asset library by clicking
__Create-> Runtime Asset Library__ in the context menu.

!!! note
An asset library must be created inside the __Resources__ folder.
Use drag & drop to add assets to asset library

!!! note
One asset library can contain no more than __65535__ assets.
If you change one or more prefabs, you will be asked to synchronize the assets library. Do it by clicking __Synchronize__ button.

##Project Item & Asset Item
__Project Items__ are used to create tree structures representing the project tree.
``` C#
[ProtoContract]
[ProtoInclude(1, typeof(AssetItem))]
public class ProjectItem
{
[ProtoMember(2)]
public long ItemID;
public string Name;
public string Ext;
public ProjectItem Parent;
public List Children;
// ...
```
__Asset Items__ are meta representations of assets in a project. They are stored in *.rtmeta files.
``` C#
[ProtoContract]
public class AssetItem : ProjectItem
{
public event EventHandler PreviewDataChanged;
[ProtoMember(1)]
public Guid TypeGuid;
[ProtoMember(2)]
public PrefabPart[] Parts;
[ProtoMember(3)]
public long[] Dependencies;
private Preview m_preview;
public Preview Preview
{
get { return m_preview; }
set
{
if (m_preview != value)
{
m_preview = value;
if (PreviewDataChanged != null)
{
PreviewDataChanged(this, EventArgs.Empty);
}
}
}
}
public override bool IsFolder
{
get { return false; }
}
}
```
##Project
__IProject__ is the main interface of the RTSL library. Here is how to access it:
``` C#
using Battlehub.RTCommon;
using Battlehub.RTSL.Interface;
void Awake()
{
IProject project = IOC.Resolve();
}
```
Open project:
``` C#
using System.Collections;
using Battlehub.RTCommon;
using Battlehub.RTSL.Interface;
IEnumerator Start()
{
IProject project = IOC.Resolve();
yield return project.OpenProject("My Project");
}
```
Close project:
``` C#
m_project.CloseProject();
```
Delete project:
``` C#
yield return project.DeleteProject("My Project");
```
Create folder:
``` C#
yield return project.CreateFolder("My Scenes");
```
Delete folder:
``` C#
yield return project.DeleteFolder("My Scenes");
```
Save scene:
``` C#
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using Battlehub.RTCommon;
using Battlehub.RTSL.Interface;
IEnumerator Start()
{
//...
ProjectAsyncOperation ao = project.Save("My Scenes/Scene 1", SceneManager.GetActiveScene());
yield return ao;
if (ao.Error.HasError)
{
Debug.LogError(ao.Error.ToString());
}
}
```
Load scene:
``` C#
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using Battlehub.RTCommon;
using Battlehub.RTSL.Interface;
IEnumerator Start()
{
//...
ProjectAsyncOperation ao = project.Load("My Scenes/Scene 1");
yield return ao;
if (ao.Error.HasError)
{
Debug.LogError(ao.Error.ToString());
}
}
```
Delete scene:
``` C#
yield return project.Delete("My Scenes/Scene 1");
```
Find objects of type:
``` C#
foreach(string scene in project.Find("Scene 1"))
{
Debug.Log(scene);
}
```
Create Prefab:
``` C#
GameObject primitive = GameObject.CreatePrimitive(PrimitiveType.Capsule);
yield return project.Save("Capsule", primitive);
Destroy(primitive);
```
Load and instantiate Prefab:
``` C#
ProjectAsyncOperation