Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use duality serializers for EditorUserData #860

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Source/Core/Duality/Utility/SettingsContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Duality
public class SettingsContainer<TSettings> : ISettingsContainer
where TSettings : class, new()
{
private readonly string path;
public string Path { get; }

/// <summary>
/// Fired when <see cref="Instance"/> has changed.
Expand All @@ -28,15 +28,15 @@ public class SettingsContainer<TSettings> : ISettingsContainer
/// <param name="path"></param>
public SettingsContainer(string path)
{
this.path = path;
this.Path = path;
}

/// <summary>
/// Loads the data of <typeparamref name="TSettings"/> from file.
/// </summary>
public void Load()
{
this.Instance = Serializer.TryReadObject<TSettings>(this.path, typeof(XmlSerializer)) ?? new TSettings();
this.Instance = Serializer.TryReadObject<TSettings>(this.Path, typeof(XmlSerializer)) ?? new TSettings();
this.Changed?.Invoke(this, EventArgs.Empty);
}

Expand All @@ -45,7 +45,7 @@ public void Load()
/// </summary>
public void Save()
{
Serializer.WriteObject(this.Instance, this.path, typeof(XmlSerializer));
Serializer.WriteObject(this.Instance, this.Path, typeof(XmlSerializer));
}
}
}
102 changes: 8 additions & 94 deletions Source/Editor/DualityEditor/DesignTimeObjectData.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.IO;

using Duality;
using Duality.Serialization;
using Duality.Resources;

namespace Duality.Editor
Expand Down Expand Up @@ -77,42 +73,20 @@ public bool Equals(DataContainer other)
}
}

private static DesignTimeObjectDataManager manager = new DesignTimeObjectDataManager();

internal static void Init()
{
Load(DualityEditorApp.DesignTimeDataFile);
Scene.Leaving += Scene_Leaving;
}
internal static void Terminate()
{
Scene.Leaving -= Scene_Leaving;
Save(DualityEditorApp.DesignTimeDataFile);
}

public static DesignTimeObjectData Get(Guid objId)
{
return manager.RequestDesignTimeData(objId);
}
public static DesignTimeObjectData Get(GameObject obj)
{
return manager.RequestDesignTimeData(obj.Id);
}

private static void Save(string filePath)
{
Serializer.WriteObject(manager, filePath, typeof(BinarySerializer));
}
private static void Load(string filePath)
{
manager = Serializer.TryReadObject<DesignTimeObjectDataManager>(filePath) ?? new DesignTimeObjectDataManager();
}
private static void Scene_Leaving(object sender, EventArgs e)
{
manager.CleanupDesignTimeData();
DualityEditorApp.DualityEditorUserData.Instance?.DesignTimeObjectDataManager.CleanupDesignTimeData();
}


public static readonly DesignTimeObjectData Default = new DesignTimeObjectData();

private Guid objId = Guid.Empty;
Expand Down Expand Up @@ -184,6 +158,11 @@ public DesignTimeObjectData(Guid parentId, DesignTimeObjectData baseData)
this.attached = true;
}

public static DesignTimeObjectData Get(GameObject obj)
{
return DualityEditorApp.DualityEditorUserData.Instance.DesignTimeObjectDataManager.RequestDesignTimeData(obj.Id);
}

public T RequestCustomData<T>() where T : new()
{
this.Detach();
Expand Down Expand Up @@ -231,14 +210,10 @@ private void Detach()
}
}

internal class DesignTimeObjectDataManager : ISerializeExplicit
public class DesignTimeObjectDataManager
{
private static readonly int GuidByteLength = Guid.Empty.ToByteArray().Length;
private const int Version_First = 1;

private Dictionary<Guid,DesignTimeObjectData> dataStore = new Dictionary<Guid,DesignTimeObjectData>();



public DesignTimeObjectData RequestDesignTimeData(Guid objId)
{
DesignTimeObjectData data;
Expand Down Expand Up @@ -273,66 +248,5 @@ public void OptimizeDesignTimeData()
shareValues.RemoveAt(shareValues.Count - 1);
}
}

void ISerializeExplicit.WriteData(IDataWriter writer)
{
this.CleanupDesignTimeData();
this.OptimizeDesignTimeData();

Guid[] guidArray = dataStore.Keys.ToArray();
byte[] data = new byte[guidArray.Length * GuidByteLength];
for (int i = 0; i < guidArray.Length; i++)
{
Array.Copy(
guidArray[i].ToByteArray(), 0,
data, i * GuidByteLength, GuidByteLength);
}
DesignTimeObjectData.DataContainer[] objData = dataStore.Values.Select(d => d.Data).ToArray();
bool[] objDataDirty = dataStore.Values.Select(d => d.IsAttached).ToArray();

writer.WriteValue("version", Version_First);
writer.WriteValue("dataStoreKeys", data);
writer.WriteValue("dataStoreValues", objData);
writer.WriteValue("dataStoreDirtyFlag", objDataDirty);
}
void ISerializeExplicit.ReadData(IDataReader reader)
{
int version;
reader.ReadValue("version", out version);

if (this.dataStore == null)
this.dataStore = new Dictionary<Guid,DesignTimeObjectData>();
else
this.dataStore.Clear();

if (version == Version_First)
{
byte[] data;
DesignTimeObjectData.DataContainer[] objData;
bool[] objDataDirty;
reader.ReadValue("dataStoreKeys", out data);
reader.ReadValue("dataStoreValues", out objData);
reader.ReadValue("dataStoreDirtyFlag", out objDataDirty);

Guid[] guidArray = new Guid[data.Length / GuidByteLength];
byte[] guidData = new byte[GuidByteLength];
for (int i = 0; i < guidArray.Length; i++)
{
Array.Copy(
data, i * GuidByteLength,
guidData, 0, GuidByteLength);
guidArray[i] = new Guid(guidData);
}

for (int i = 0; i < objData.Length; i++)
{
this.dataStore.Add(guidArray[i], new DesignTimeObjectData(guidArray[i], objData[i], objDataDirty[i]));
}
}
else
{
// Unknown format
}
}
}
}
159 changes: 8 additions & 151 deletions Source/Editor/DualityEditor/DualityEditorApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Windows.Forms;
using System.Drawing;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;

using Duality;
using Duality.IO;
using Duality.Components;
using Duality.Resources;
Expand All @@ -22,7 +17,6 @@
using Duality.Editor.UndoRedoActions;
using Duality.Editor.AssetManagement;

using WeifenLuo.WinFormsUI.Docking;
using Duality.Launcher;

namespace Duality.Editor
Expand All @@ -32,9 +26,6 @@ public static class DualityEditorApp
public const string EditorLogfilePath = "logfile_editor.txt";
public const string EditorPrevLogfileName = "logfile_editor_{0}.txt";
public const string EditorPrevLogfileDir = "Temp";
public const string DesignTimeDataFile = "DesignTimeData.dat";
public const string UserDataFile = "EditorUserData.dat";
private const string UserDataDockSeparator = "<!-- DockPanel Data -->";

public const string ActionContextMenu = "ContextMenu";
public const string ActionContextOpenRes = "OpenRes";
Expand Down Expand Up @@ -131,6 +122,11 @@ public static bool IsFirstEditorSession
get { return firstEditorSession; }
}

/// <summary>
/// [GET] Provides access to Duality's current <see cref="DualityEditorUserData">user data</see>. This is never null.
/// </summary>
public static SettingsContainer<DualityEditorUserData> DualityEditorUserData { get; } = new SettingsContainer<DualityEditorUserData>("EditorUserData.xml");

/// <summary>
/// [GET] Provides access to Duality's current <see cref="EditorAppData">application data</see>. This is never null.
/// </summary>
Expand Down Expand Up @@ -216,11 +212,12 @@ public static void Init(MainForm mainForm, bool recover)
DualityApp.InitPostWindow();

EditorAppData.Load();
EditorAppData.Save();

mainForm.UpdateLaunchAppActions();

LoadUserData();
DualityEditorUserData.Load();
mainForm.LoadDockPanelData(DualityEditorUserData.Instance.DockPanelState);
PluginManager.LoadUserData(DualityEditorUserData.Instance.PluginSettings);
pluginManager.InitPlugins();


Expand Down Expand Up @@ -407,146 +404,6 @@ public static IEnumerable<IEditorAction> GetEditorActions(Type subjectType, IEnu
}
}

public static void SaveUserData()
{
Logs.Editor.Write("Saving user data...");
Logs.Editor.PushIndent();

using (FileStream str = File.Create(UserDataFile))
{
Encoding encoding = Encoding.Default;
using (StreamWriter writer = new StreamWriter(str.NonClosing()))
{
encoding = writer.Encoding;

XDocument xmlDoc = new XDocument();
XElement rootElement = new XElement("UserData");
{
XElement editorAppElement = new XElement("EditorApp");
{
editorAppElement.SetElementValue("Backups", backupsEnabled);
editorAppElement.SetElementValue("Autosaves", autosaveFrequency);
editorAppElement.SetElementValue("LauncherPath", launcherApp);
editorAppElement.SetElementValue("FirstSession", false);
editorAppElement.SetElementValue("ActiveDocumentIndex", mainForm.ActiveDocumentIndex);
editorAppElement.SetElementValue("LastOpenScene", lastOpenScene.Path);
editorAppElement.SetElementValue("StartWithLastScene", startWithLastScene);
}
if (!editorAppElement.IsEmpty)
rootElement.Add(editorAppElement);

XElement pluginsElement = new XElement("Plugins");
pluginManager.SaveUserData(pluginsElement);
if (!pluginsElement.IsEmpty)
rootElement.Add(pluginsElement);
}
xmlDoc.Add(rootElement);
xmlDoc.Save(writer.BaseStream);

writer.WriteLine();
writer.WriteLine(UserDataDockSeparator);
writer.Flush();
}
mainForm.MainDockPanel.SaveAsXml(str, encoding);
}

Logs.Editor.PopIndent();
}
private static void LoadUserData()
{
if (!File.Exists(UserDataFile))
{
File.WriteAllText(UserDataFile, Properties.GeneralRes.DefaultEditorUserData);
if (!File.Exists(UserDataFile)) return;
}

Logs.Editor.Write("Loading user data...");
Logs.Editor.PushIndent();

Encoding encoding = Encoding.Default;
StringBuilder editorData = new StringBuilder();
StringBuilder dockPanelData = new StringBuilder();
using (StreamReader reader = new StreamReader(UserDataFile))
{
encoding = reader.CurrentEncoding;
string line;

// Retrieve pre-DockPanel section
while ((line = reader.ReadLine()) != null && line.Trim() != UserDataDockSeparator)
editorData.AppendLine(line);

// Retrieve DockPanel section
while ((line = reader.ReadLine()) != null)
dockPanelData.AppendLine(line);
}

// Load DockPanel Data
{
Logs.Editor.Write("Loading DockPanel data...");
Logs.Editor.PushIndent();
MemoryStream dockPanelDataStream = new MemoryStream(encoding.GetBytes(dockPanelData.ToString()));
try
{
mainForm.MainDockPanel.LoadFromXml(dockPanelDataStream, DeserializeDockContent);
}
catch (Exception e)
{
Logs.Editor.WriteError("Cannot load DockPanel data due to malformed or non-existent Xml: {0}", LogFormat.Exception(e));
}
Logs.Editor.PopIndent();
}

// Load editor userdata
{
Logs.Editor.Write("Loading editor user data...");
Logs.Editor.PushIndent();
try
{
int activeDocumentIndex = 0;

// Load main editor data
XDocument xmlDoc = XDocument.Parse(editorData.ToString());
XElement rootElement = xmlDoc.Root;
XElement editorAppElement = rootElement.Elements("EditorApp").FirstOrDefault();
if (editorAppElement != null)
{
editorAppElement.TryGetElementValue("Backups", ref backupsEnabled);
editorAppElement.TryGetElementValue("Autosaves", ref autosaveFrequency);
editorAppElement.TryGetElementValue("LauncherPath", ref launcherApp);
editorAppElement.TryGetElementValue("FirstSession", ref firstEditorSession);
editorAppElement.TryGetElementValue("ActiveDocumentIndex", ref activeDocumentIndex);

string scenePath;
editorAppElement.GetElementValue("LastOpenScene", out scenePath);
if (scenePath != null) lastOpenScene = new ContentRef<Scene>(null, scenePath);

editorAppElement.TryGetElementValue("StartWithLastScene", ref startWithLastScene);
}

// Load plugin editor data
XElement pluginsElement = rootElement.Elements("Plugins").FirstOrDefault();
if (pluginsElement != null)
pluginManager.LoadUserData(pluginsElement);

// Set the active document as loaded from user data
mainForm.ActiveDocumentIndex = activeDocumentIndex;
}
catch (Exception e)
{
Logs.Editor.WriteError("Error loading editor user data: {0}", LogFormat.Exception(e));
}
Logs.Editor.PopIndent();
}

Logs.Editor.PopIndent();
return;
}
private static IDockContent DeserializeDockContent(string persistName)
{
Logs.Editor.Write("Deserializing layout: '" + persistName + "'");
return pluginManager.DeserializeDockContent(persistName);
}

private static void InitMainGraphicsContext()
{
if (mainGraphicsContext != null) return;
Expand Down
Loading