Custom ES3Type Troubles

Discussion and help for Easy Save 3
User avatar
Cranktrain
Posts: 16
Joined: Thu Nov 09, 2017 7:15 pm

Custom ES3Type Troubles

Post by Cranktrain »

Hi - I'm working on upgrading my project from ES2 to ES3, so I'm migrating all my types from ES2Type to ES3Type. I've been reading the docs on the subject of custom types but a first pass at migrating my types has not gone so smoothly.

Here's the first error I'm encountering. I'm just going to go into too much detail so you can see what I'm attempting to accomplish: I start by saving some default settings about my game if there isn't a settings file, things like resolution, windowed mode, quality of shadows, etc.

So I call
ES3.Save<Settings>("Settings", this)
from my settings monobehaviour.

Here's my Settings ES3Type (still called ES2UserType_Settings because I'm migrating):
namespace ES3Types {
	public class ES2UserType_Settings : ES3Type {
		public override void Write(object obj, ES3Writer writer) {
			Settings data = (Settings)obj;
			// Add your writer.Write calls here.
			data.SaveData(writer);
		}

		public override object Read<T>(ES3Reader reader) {
			Settings data = Settings.Instantiate();
			ReadInto<T>(reader, data);
			return data;
		}

		public override void ReadInto<T>(ES3Reader reader, object c) {
			Settings data = (Settings)c;
			// Add your reader.Read calls here to read the data into the object.
			data.LoadData(reader);
		}
	}
}
My settings monobehaviour has SaveData and ReadData, and these look like:
public void SaveData(ES3Writer writer) {
		writer.Write(seenFirstSplash);
		writer.Write(soundEffectsVolume);
		writer.Write(musicVolume);
		writer.Write(currentLanguage);
		writer.Write(subtitles);
		writer.Write(currentAnimationQuality);
		writer.Write(fullscreen);
		writer.Write(resolutionWidth);
		writer.Write(resolutionHeight);
		writer.Write(currentShadowQuality);
		writer.Write(currentVSync);
		writer.Write(currentUIScale);
	}

	public void LoadData(ES3Reader reader) {
		seenFirstSplash = reader.Read<bool>();
		soundEffectsVolume = reader.Read<float>();
		musicVolume = reader.Read<float>();
		SetCurrentLanguage(reader.Read<Languages>());
		subtitles = reader.Read<bool>();
		currentAnimationQuality = reader.Read<AnimationQualities>();
		fullscreen = reader.Read<bool>();
		resolutionWidth = reader.Read<int>();
		resolutionHeight = reader.Read<int>();
		currentShadowQuality = reader.Read<ShadowQualities>();
		currentVSync = reader.Read<int>();
		currentUIScale = reader.Read<float>();

		SetupValues();  // Goes and applies all these values to the parts of the game that need them.
	}
Exciting stuff. Just a bunch of ES3Reader/ES3Writer calls. Previously this was all ES2Reader/ES3Writer, and was working alright.

But when I try and run the game, this is the stacktrace of the error I get:

Code: Select all

ArgumentNullException: Value cannot be null.
Parameter name: key
System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
System.Collections.Generic.Dictionary`2[TKey,TValue].set_Item (TKey key, TValue value) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
ES3Internal.ES3TypeMgr.Init () (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:124)
ES3Internal.ES3TypeMgr.GetOrCreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:17)
ES3Writer.Write (System.Object value, ES3+ReferenceMode memberReferenceMode) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:128)
ES3Internal.ES3JSONWriter.StartWriteProperty (System.String name) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3JSONWriter.cs:126)
ES3Writer.Write[T] (System.String key, System.Object value) (at Assets/Plugins/Easy Save 3/Scripts/Writers/ES3Writer.cs:84)
ES3.Save[T] (System.String key, System.Object value) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:27)
Settings.SaveSettings () (at Assets/Scripts/Game/Meta/Settings.cs:165)
Settings.SetResolution (UnityEngine.Resolution newResolution) (at Assets/Scripts/Game/Meta/Settings.cs:287)
Settings.SetupValues () (at Assets/Scripts/Game/Meta/Settings.cs:228)
Settings.SetDefaults () (at Assets/Scripts/Game/Meta/Settings.cs:190)
Settings.LoadSettings () (at Assets/Scripts/Game/Meta/Settings.cs:171)
Settings.Awake () (at Assets/Scripts/Game/Meta/Settings.cs:198)
Looking at ES3Internal.ES3TypeMgr.Init() I see:
internal static void Init()
		{
			var typeList = ES3Reflection.GetInstances<ES3Type>();
			types = new Dictionary<Type, ES3Type>(typeList.Count);

			for(int i=0; i<typeList.Count; i++)
				types[typeList.type] = typeList;

			// Check that the type list was initialised correctly.
			if(types == null || types.Count == 0)
				throw new TypeLoadException("Type list could not be initialised. Please contact Easy Save developers on mail@moodkie.com.");
		}


The thing I'm missing is how ES3 knows what types associate with what ES3Type? Clearly the magic is tripping up here because I'm not using the ES3 Custom Type creator from the Ease Save 3 window in Unity, I'm instead migrating my old types to the new ones. In ES2 I'd add a line in the ES2Type list and it was all explicitly defined there, what associates with what, but clearly there's a new way of doing things here.

When I type "settings" in the Easy Save 3 window, it doesn't appear. If I type a single letter and scroll down the enormous list of types till I do see Settings, and click on it, I get this error in the editor:

Code: Select all

TypeLoadException: ES3Type for primitive could not be found, and the type list is empty. Please contact Easy Save developers at http://www.moodkie.com/contact
ES3Internal.ES3TypeMgr.CreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:86)
ES3Internal.ES3TypeMgr.GetOrCreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:23)
ES3Types.ES3DictionaryType..ctor (System.Type type) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3DictionaryType.cs:20)
ES3Internal.ES3TypeMgr.CreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:71)
ES3Internal.ES3TypeMgr.GetOrCreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:23)
ES3Internal.ES3Reflection.TypeIsSerializable (System.Type type) (at Assets/Plugins/Easy Save 3/Scripts/ES3Reflection.cs:178)
ES3Internal.ES3Reflection.GetSerializableFields (System.Type type, System.Boolean safe, System.String[] memberNames) (at Assets/Plugins/Easy Save 3/Scripts/ES3Reflection.cs:90)
Again, ES3 reflexion magic doesn't seem to know what to do with the Type. The error message "contact Ease Save developers at..." isn't the most helpful!

The most helpful thing would be to have an outline as to what my ES2UserType_Settings ES3Type should actually look like - I'm sure the Types panel in the Easy Save 3 window could help me there, but as discussed above, I'm having errors there too.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Custom ES3Type Troubles

Post by Joel »

Hi there,

ES3Writer/Reader and ES3Types work very differently to ES2Types, so you will not be able to replace the methods in your ES2Types with the equivalent ES3Types. Instead you will need to use the Types window to generate new ES3Types. Be aware that the search bar in the Types pane is case-sensitive, so you will need to type "Settings" rather than "settings".

In addition, ES3Writer/Reader should not be used outside of ES3Types. Instead we provide ES3Files for those wanting to benefit from data caching: https://docs.moodkie.com/easy-save-3/es3-guides/caching-using-es3file/.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
User avatar
Cranktrain
Posts: 16
Joined: Thu Nov 09, 2017 7:15 pm

Re: Custom ES3Type Troubles

Post by Cranktrain »

Thanks Joel, didn't know about the case-sensitivity on the ES3 window.

But when I click "Create ES3Type Script" I still get the ArgumentNullException, as well as the TypeLoadException.

Error one:

Code: Select all

ArgumentNullException: Value cannot be null.
Parameter name: key
System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
System.Collections.Generic.Dictionary`2[TKey,TValue].set_Item (TKey key, TValue value) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
ES3Internal.ES3TypeMgr.Init () (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:124)
ES3Internal.ES3TypeMgr.GetES3Type (System.Type type) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:29)
ES3Editor.TypesWindow.HasExplicitES3Type (System.Type type) (at Assets/Plugins/Easy Save 3/Editor/TypesWindow.cs:651)
ES3Editor.TypesWindow.Init () (at Assets/Plugins/Easy Save 3/Editor/TypesWindow.cs:449)
ES3Editor.TypesWindow.OnGUI () (at Assets/Plugins/Easy Save 3/Editor/TypesWindow.cs:49)
ES3Editor.ES3Window.OnGUI () (at Assets/Plugins/Easy Save 3/Editor/ES3Window.cs:89)
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
UnityEditor.HostView.Invoke (System.String methodName, System.Object obj) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:291)
UnityEditor.HostView.Invoke (System.String methodName) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:284)
UnityEditor.HostView.InvokeOnGUI (UnityEngine.Rect onGUIPosition) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:257)
UnityEditor.DockArea.OldOnGUI () (at C:/buildslave/unity/build/Editor/Mono/GUI/DockArea.cs:386)
UnityEngine.Experimental.UIElements.IMGUIContainer.DoOnGUI (UnityEngine.Event evt) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:211)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
Error 2: (what I assume to be a less important GUI error)

Code: Select all

ArgumentException: Getting control 1's position in a group with only 1 controls when doing repaint
Aborting
UnityEngine.GUILayoutGroup.GetNext () (at C:/buildslave/unity/build/Modules/IMGUI/LayoutGroup.cs:117)
UnityEngine.GUILayoutUtility.BeginLayoutGroup (UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options, System.Type layoutType) (at C:/buildslave/unity/build/Modules/IMGUI/GUILayoutUtility.cs:309)
UnityEditor.EditorGUILayout.BeginHorizontal (UnityEngine.GUIContent content, UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options) (at C:/buildslave/unity/build/Editor/Mono/EditorGUI.cs:7798)
UnityEditor.EditorGUILayout.BeginHorizontal (UnityEngine.GUILayoutOption[] options) (at C:/buildslave/unity/build/Editor/Mono/EditorGUI.cs:7778)
ES3Editor.TypesWindow.OnGUI () (at Assets/Plugins/Easy Save 3/Editor/TypesWindow.cs:51)
ES3Editor.ES3Window.OnGUI () (at Assets/Plugins/Easy Save 3/Editor/ES3Window.cs:89)
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
UnityEditor.HostView.Invoke (System.String methodName, System.Object obj) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:291)
UnityEditor.HostView.Invoke (System.String methodName) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:284)
UnityEditor.HostView.InvokeOnGUI (UnityEngine.Rect onGUIPosition) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:257)
UnityEditor.DockArea.OldOnGUI () (at C:/buildslave/unity/build/Editor/Mono/GUI/DockArea.cs:386)
UnityEngine.Experimental.UIElements.IMGUIContainer.DoOnGUI (UnityEngine.Event evt) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:228)
UnityEngine.Experimental.UIElements.IMGUIContainer.HandleIMGUIEvent (UnityEngine.Event e) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:366)
UnityEngine.Experimental.UIElements.IMGUIContainer.DoRepaint (UnityEngine.IStylePainter painter) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:70)
UnityEngine.Experimental.UIElements.Panel.PaintSubTree (UnityEngine.Event e, UnityEngine.Experimental.UIElements.VisualElement root, UnityEngine.Matrix4x4 offset, UnityEngine.Rect currentGlobalClip) (at C:/buildslave/unity/build/Modules/UIElements/Panel.cs:677)
UnityEngine.Experimental.UIElements.Panel.PaintSubTreeChildren (UnityEngine.Event e, UnityEngine.Experimental.UIElements.VisualElement root, UnityEngine.Matrix4x4 offset, UnityEngine.Rect textureClip) (at C:/buildslave/unity/build/Modules/UIElements/Panel.cs:693)
UnityEngine.Experimental.UIElements.Panel.PaintSubTree (UnityEngine.Event e, UnityEngine.Experimental.UIElements.VisualElement root, UnityEngine.Matrix4x4 offset, UnityEngine.Rect currentGlobalClip) (at C:/buildslave/unity/build/Modules/UIElements/Panel.cs:681)
UnityEngine.Experimental.UIElements.Panel.Repaint (UnityEngine.Event e) (at C:/buildslave/unity/build/Modules/UIElements/Panel.cs:722)
UnityEngine.Experimental.UIElements.UIElementsUtility.DoDispatch (UnityEngine.Experimental.UIElements.BaseVisualElementPanel panel) (at C:/buildslave/unity/build/Modules/UIElements/UIElementsUtility.cs:208)
UnityEngine.Experimental.UIElements.UIElementsUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at C:/buildslave/unity/build/Modules/UIElements/UIElementsUtility.cs:77)
UnityEngine.GUIUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at C:/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:184)
and error 3:

Code: Select all

TypeLoadException: ES3Type for primitive could not be found, and the type list is empty. Please contact Easy Save developers at http://www.moodkie.com/contact
ES3Internal.ES3TypeMgr.CreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:86)
ES3Internal.ES3TypeMgr.GetOrCreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:23)
ES3Types.ES3DictionaryType..ctor (System.Type type) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3DictionaryType.cs:20)
ES3Internal.ES3TypeMgr.CreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:71)
ES3Internal.ES3TypeMgr.GetOrCreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:23)
ES3Internal.ES3Reflection.TypeIsSerializable (System.Type type) (at Assets/Plugins/Easy Save 3/Scripts/ES3Reflection.cs:178)
ES3Internal.ES3Reflection.GetSerializableFields (System.Type type, System.Boolean safe, System.String[] memberNames) (at Assets/Plugins/Easy Save 3/Scripts/ES3Reflection.cs:90)
ES3Internal.ES3Reflection.GetSerializableMembers (System.Type type, System.Boolean safe, System.String[] memberNames) (at Assets/Plugins/Easy Save 3/Scripts/ES3Reflection.cs:233)
ES3Editor.TypesWindow.SelectType (System.Int32 typeIndex) (at Assets/Plugins/Easy Save 3/Editor/TypesWindow.cs:360)
ES3Editor.TypesWindow.TypeButton (System.Int32 i) (at Assets/Plugins/Easy Save 3/Editor/TypesWindow.cs:313)
ES3Editor.TypesWindow.TypeList () (at Assets/Plugins/Easy Save 3/Editor/TypesWindow.cs:116)
ES3Editor.TypesWindow.OnGUI () (at Assets/Plugins/Easy Save 3/Editor/TypesWindow.cs:55)
ES3Editor.ES3Window.OnGUI () (at Assets/Plugins/Easy Save 3/Editor/ES3Window.cs:89)
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
UnityEditor.HostView.Invoke (System.String methodName, System.Object obj) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:291)
UnityEditor.HostView.Invoke (System.String methodName) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:284)
UnityEditor.HostView.InvokeOnGUI (UnityEngine.Rect onGUIPosition) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:257)
UnityEditor.DockArea.OldOnGUI () (at C:/buildslave/unity/build/Editor/Mono/GUI/DockArea.cs:386)
UnityEngine.Experimental.UIElements.IMGUIContainer.DoOnGUI (UnityEngine.Event evt) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:228)
UnityEngine.Experimental.UIElements.IMGUIContainer.HandleIMGUIEvent (UnityEngine.Event e) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:366)
UnityEngine.Experimental.UIElements.IMGUIContainer.HandleEvent (UnityEngine.Experimental.UIElements.EventBase evt) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:350)
UnityEngine.Experimental.UIElements.EventDispatcher.DispatchEvent (UnityEngine.Experimental.UIElements.EventBase evt, UnityEngine.Experimental.UIElements.IPanel panel) (at C:/buildslave/unity/build/Modules/UIElements/EventDispatcher.cs:215)
UnityEngine.Experimental.UIElements.UIElementsUtility.DoDispatch (UnityEngine.Experimental.UIElements.BaseVisualElementPanel panel) (at C:/buildslave/unity/build/Modules/UIElements/UIElementsUtility.cs:224)
UnityEngine.Experimental.UIElements.UIElementsUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at C:/buildslave/unity/build/Modules/UIElements/UIElementsUtility.cs:77)
UnityEngine.GUIUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at C:/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:184)
User avatar
Cranktrain
Posts: 16
Joined: Thu Nov 09, 2017 7:15 pm

Re: Custom ES3Type Troubles

Post by Cranktrain »

A follow-up query regarding what you're saying about ES3Reader/ES3Writer. In upgrading to ES3 I'm trying to solve another of issues with my saving and loading, the first I posted about a few weeks back here, and your main suggestion was to upgrade to ES3.

The second problem I have is that saving and loading takes an incredibly long time. I was going to address this problem after upgrading to ES3, but I suppose it's worth talking about now if I can save myself some trouble. Having read this ES2 doc my issue of 30+ save/load times seems to be calling ES2.Save and ES2.Load a lot during the saving and loading routines, as you say:
If you are looking for extra performance when saving and loading, or extra flexibility in general, then we advise that you use ES2Writer and ES2Reader. This is faster than making multiple ES2.Save and ES2.Load calls because it keeps the file open between calls.
So each time I call ES2 Save and Load using tags, the file opens and closes? I have thousands of objects that I'm saving this way, so that would be the reason me <1Mb save file takes 30 seconds to create. Am I right in assuming the same behaviour occurs with ES3.Save and ES3.Load? But if, as you say, "ES3Writer/Reader should not be used outside of ES3Types" then will ES3Files clean up my performance issues as well?

Of course, I can't start experimenting with ES3Files for myself untill I sort out the Primitive errors outlined in my last post.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Custom ES3Type Troubles

Post by Joel »

Hi there,

ES3File will indeed improve performance significantly over using ES2.Save and ES2.Load, because it caches calls and so only requires a single read/write, rather than one for each tag.

With regards to the errors you're getting, it looks like you might still have one of the ES2Types in your project which has been converted to an ES3Type, because it looks like a required variable is missing which is usually set in the ES3Type. However, if you PM me a project and instructions to replicate this, I can check whether this is the case.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
User avatar
Cranktrain
Posts: 16
Joined: Thu Nov 09, 2017 7:15 pm

Re: Custom ES3Type Troubles

Post by Cranktrain »

Thanks Joel, okay. I think I'm making some progress, I removed an ES3Type experiment I'd forgot about and these errors have gone away and I'm starting to create ES3Types.

One thing I was doing with ES2 was nesting ES2.Save calls. For example, I'm saving a TreeManager and it's various fields. But the TreeManager stores references to all the Trees, so I would iterate through that list and run ES2.Save on each tree, which worked well. (Edit: I say it worked well, it's probably the cause of the 30 second+ save/load times.)

I notice if I do this in ES3 I get an IOException? I see in the stack-trace that called ES3 immediately calls ES3Writer.Create, rather than making use of the existing ES3Writer to write to a different tag in the same file.

If nesting calls to ES3.Save isn't the appropriate pattern, what ought I be doing?
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Custom ES3Type Troubles

Post by Joel »

Hi there,

I'm not sure what you mean by "nesting" ES2.Save calls? Would you be able to clarify?

Note that it was unsafe in Easy Save 2 to open a stream on the same file in the same way that it is unsafe in Easy Save 3. The only difference is that Easy Save 3 will throw an error immediately, whereas Easy Save 2 will only throw an error when you attempt to store the second stream.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
User avatar
Cranktrain
Posts: 16
Joined: Thu Nov 09, 2017 7:15 pm

Re: Custom ES3Type Troubles

Post by Cranktrain »

By 'nesting' Save calls I mean, calling ES2.Save, and then within the ES2Type calling ES2.Save. For example:

Code: Select all

• Call ES2.Save<TreeManager>(...)
    • In the ES2UserType_TreeManager, save some higher level Manager-state stuff.
    • Oh, and while we're here and have access to all the Trees, iterate through all the trees:
        • For each tree call ES2.Save<Tree>(...)
Hope that clarifies what I was doing! Sounds like this wasn't the right practise, though I never had any problems saving or loading, each Tree was in a different Tag in the same file.

How should I be calling ES3.Save on all these different ES3 custom types, when objects that need to be saved reference other objects that need to be saved?
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Custom ES3Type Troubles

Post by Joel »

Hi there,

You should definitely not call ES2.Save or ES3.Save in an ES2Type/ES3Type. You should only use ES2/ES3Writer and ES2/ES3Reader calls in an ES3Type.

So in your example, you would call writer.WriteProperty<Trees[]>(...).

Information on writing ES3Types can be found here.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
User avatar
Cranktrain
Posts: 16
Joined: Thu Nov 09, 2017 7:15 pm

Re: Custom ES3Type Troubles

Post by Cranktrain »

Right, right, I see. Thanks for bearing with me.

In my game, I don't think I should be calling writer.WriteProperty<Trees[]>, those aren't properties or components attached to my TreeManager, these are separate game objects, with Colliders and probably other references.

Another higher-level question for you as I still work this all through: how do I load two objects that refer to one another? In my game any character might be holding an item (and the item in turn is held by the character). Both the item and the character need to be store pointers to the right one. I couldn't find any docs on this but that might be just because I don't know the right search terms.

(In my Frankensteinian ES2 method we've already discussed I was loading both objects and then creating some closure-based callbacks to hook up these objects by saved UUID string references. Again, this was working fine, but I want to know if there's a Right Way™ in ES3 to do this.)
Post Reply