Skip to content

Commit b64d05f

Browse files
committed
Merge feature/PersistingData to develop
2 parents 90cb220 + c1e3e82 commit b64d05f

File tree

13 files changed

+2162
-1
lines changed

13 files changed

+2162
-1
lines changed

Examples/FrameworkExamples.sln

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MBWindow", "MBWindow\MBWind
99
EndProject
1010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkinsAhoy", "SkinsAhoy\SkinsAhoy.csproj", "{7F951034-ADE7-4175-9B3C-11DEACBA542D}"
1111
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PersistingData", "PersistingData\PersistingData.csproj", "{9F08B7B7-6A43-4B49-8C35-FB0BED4B4E55}"
13+
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PersistingDataErrors", "PersistingDataErrors\PersistingDataErrors.csproj", "{B5A3C5F6-8121-4781-981F-EE3C24DA6026}"
15+
EndProject
1216
Global
1317
GlobalSection(TeamFoundationVersionControl) = preSolution
14-
SccNumberOfProjects = 4
18+
SccNumberOfProjects = 6
1519
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
1620
SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs34
1721
SccLocalPath0 = .
@@ -24,6 +28,12 @@ Global
2428
SccProjectUniqueName3 = SkinsAhoy\\SkinsAhoy.csproj
2529
SccProjectName3 = SkinsAhoy
2630
SccLocalPath3 = SkinsAhoy
31+
SccProjectUniqueName4 = PersistingData\\PersistingData.csproj
32+
SccProjectName4 = PersistingData
33+
SccLocalPath4 = PersistingData
34+
SccProjectUniqueName5 = PersistingDataErrors\\PersistingDataErrors.csproj
35+
SccProjectName5 = PersistingDataErrors
36+
SccLocalPath5 = PersistingDataErrors
2737
EndGlobalSection
2838
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2939
Debug|Any CPU = Debug|Any CPU
@@ -42,6 +52,14 @@ Global
4252
{7F951034-ADE7-4175-9B3C-11DEACBA542D}.Debug|Any CPU.Build.0 = Debug|Any CPU
4353
{7F951034-ADE7-4175-9B3C-11DEACBA542D}.Release|Any CPU.ActiveCfg = Release|Any CPU
4454
{7F951034-ADE7-4175-9B3C-11DEACBA542D}.Release|Any CPU.Build.0 = Release|Any CPU
55+
{9F08B7B7-6A43-4B49-8C35-FB0BED4B4E55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
56+
{9F08B7B7-6A43-4B49-8C35-FB0BED4B4E55}.Debug|Any CPU.Build.0 = Debug|Any CPU
57+
{9F08B7B7-6A43-4B49-8C35-FB0BED4B4E55}.Release|Any CPU.ActiveCfg = Release|Any CPU
58+
{9F08B7B7-6A43-4B49-8C35-FB0BED4B4E55}.Release|Any CPU.Build.0 = Release|Any CPU
59+
{B5A3C5F6-8121-4781-981F-EE3C24DA6026}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
60+
{B5A3C5F6-8121-4781-981F-EE3C24DA6026}.Debug|Any CPU.Build.0 = Debug|Any CPU
61+
{B5A3C5F6-8121-4781-981F-EE3C24DA6026}.Release|Any CPU.ActiveCfg = Release|Any CPU
62+
{B5A3C5F6-8121-4781-981F-EE3C24DA6026}.Release|Any CPU.Build.0 = Release|Any CPU
4563
EndGlobalSection
4664
GlobalSection(SolutionProperties) = preSolution
4765
HideSolutionNode = FALSE
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
using KSP;
7+
using UnityEngine;
8+
9+
public abstract class ConfigNodeStorage : IPersistenceLoad, IPersistenceSave
10+
{
11+
#region Constructors
12+
/// <summary>
13+
/// Class Constructor
14+
/// </summary>
15+
public ConfigNodeStorage() { }
16+
/// <summary>
17+
/// Class Constructor
18+
/// </summary>
19+
/// <param name="FilePath">Set the path for saving and loading. This can be an absolute path (eg c:\test.cfg) or a relative path from the location of the assembly dll (eg. ../config/test)</param>
20+
public ConfigNodeStorage(String FilePath) { this.FilePath = FilePath; }
21+
#endregion
22+
23+
#region Properties
24+
private String _FilePath;
25+
/// <summary>
26+
/// Location of file for saving and loading methods
27+
///
28+
/// This can be an absolute path (eg c:\test.cfg) or a relative path from the location of the assembly dll (eg. ../config/test)
29+
/// </summary>
30+
public String FilePath
31+
{
32+
get { return _FilePath; }
33+
set
34+
{
35+
//Combine the Location of the assembly and the provided string. This means we can use relative or absolute paths
36+
_FilePath = System.IO.Path.Combine(_AssemblyFolder, value).Replace("\\","/");
37+
}
38+
}
39+
40+
/// <summary>
41+
/// Gets the filename portion of the FullPath
42+
/// </summary>
43+
public String FileName
44+
{
45+
get { return System.IO.Path.GetFileName(FilePath); }
46+
}
47+
#endregion
48+
49+
#region Interface Methods
50+
/// <summary>
51+
/// Wrapper for our overridable functions
52+
/// </summary>
53+
void IPersistenceLoad.PersistenceLoad()
54+
{
55+
OnDecodeFromConfigNode();
56+
}
57+
/// <summary>
58+
/// Wrapper for our overridable functions
59+
/// </summary>
60+
void IPersistenceSave.PersistenceSave()
61+
{
62+
OnEncodeToConfigNode();
63+
}
64+
65+
/// <summary>
66+
/// This overridable function executes whenever the object is loaded from a config node structure. Use this for complex classes that need decoding from simple confignode values
67+
/// </summary>
68+
public virtual void OnDecodeFromConfigNode() { }
69+
/// <summary>
70+
/// This overridable function executes whenever the object is encoded to a config node structure. Use this for complex classes that need encoding into simple confignode values
71+
/// </summary>
72+
public virtual void OnEncodeToConfigNode() { }
73+
#endregion
74+
75+
/// <summary>
76+
/// Test whether the configured FilePath exists
77+
/// </summary>
78+
/// <returns>True if its there</returns>
79+
public Boolean FileExists
80+
{
81+
get
82+
{
83+
return System.IO.File.Exists(FilePath);
84+
}
85+
}
86+
87+
/// <summary>
88+
/// Loads the object from the ConfigNode structure in the previously supplied file
89+
/// </summary>
90+
/// <returns>Succes of Load</returns>
91+
public Boolean Load()
92+
{
93+
return this.Load(FilePath);
94+
}
95+
/// <summary>
96+
/// Loads the object from the ConfigNode structure in a file
97+
/// </summary>
98+
/// <param name="fileFullName">Absolute Path to the file to load the ConfigNode structure from</param>
99+
/// <returns>Success of Load</returns>
100+
public Boolean Load(String fileFullName)
101+
{
102+
Boolean blnReturn = false;
103+
try
104+
{
105+
if (FileExists)
106+
{
107+
//Load the file into a config node
108+
ConfigNode cnToLoad = ConfigNode.Load(fileFullName);
109+
//remove the wrapper node that names the class stored
110+
ConfigNode cnUnwrapped = cnToLoad.GetNode(this.GetType().Name);
111+
//plug it in to the object
112+
ConfigNode.LoadObjectFromConfig(this, cnUnwrapped);
113+
blnReturn = true;
114+
}
115+
else
116+
{
117+
LogFormatted("File could not be found to load({0})", fileFullName);
118+
blnReturn = false;
119+
}
120+
}
121+
catch (Exception ex)
122+
{
123+
LogFormatted("Failed to Load ConfigNode from file({0})-Error:{1}", fileFullName, ex.Message);
124+
blnReturn = false;
125+
}
126+
return blnReturn;
127+
}
128+
129+
/// <summary>
130+
/// Saves the object to a ConfigNode structure in the previously supplied file
131+
/// </summary>
132+
/// <returns>Succes of Save</returns>
133+
public Boolean Save()
134+
{
135+
return this.Save(FilePath);
136+
}
137+
138+
/// <summary>
139+
/// Saves the object to a ConfigNode structure in a file
140+
/// </summary>
141+
/// <param name="fileFullName">Absolute Path to the file to load the ConfigNode structure from</param>
142+
/// <returns>Success of Save</returns>
143+
public Boolean Save(String fileFullName)
144+
{
145+
Boolean blnReturn = false;
146+
try
147+
{
148+
//Encode the current object
149+
ConfigNode cnToSave = this.AsConfigNode;
150+
//Wrap it in a node with a name of the class
151+
ConfigNode cnSaveWrapper = new ConfigNode(this.GetType().Name);
152+
cnSaveWrapper.AddNode(cnToSave);
153+
//Save it to the file
154+
cnSaveWrapper.Save(fileFullName);
155+
blnReturn = true;
156+
}
157+
catch (Exception ex)
158+
{
159+
LogFormatted("Failed to Save ConfigNode to file({0})-Error:{1}", fileFullName, ex.Message);
160+
blnReturn = false;
161+
}
162+
return blnReturn;
163+
}
164+
165+
/// <summary>
166+
/// Returns the current object as a ConfigNode
167+
/// </summary>
168+
public ConfigNode AsConfigNode
169+
{
170+
get
171+
{
172+
try
173+
{
174+
//Create a new Empty Node with the class name
175+
ConfigNode cnTemp = new ConfigNode(this.GetType().Name);
176+
//Load the current object in there
177+
cnTemp = ConfigNode.CreateConfigFromObject(this, cnTemp);
178+
return cnTemp;
179+
}
180+
catch (Exception ex)
181+
{
182+
LogFormatted("Failed to generate ConfigNode-Error;{0}", ex.Message);
183+
//Logging and return value?
184+
return new ConfigNode(this.GetType().Name);
185+
}
186+
}
187+
}
188+
189+
190+
#region Assembly/Class Information
191+
/// <summary>
192+
/// Name of the Assembly that is running this MonoBehaviour
193+
/// </summary>
194+
internal static String _AssemblyName
195+
{ get { return System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; } }
196+
197+
/// <summary>
198+
/// Full Path of the executing Assembly
199+
/// </summary>
200+
internal static String _AssemblyLocation
201+
{ get { return System.Reflection.Assembly.GetExecutingAssembly().Location; } }
202+
203+
/// <summary>
204+
/// Folder containing the executing Assembly
205+
/// </summary>
206+
internal static String _AssemblyFolder
207+
{ get { return System.IO.Path.GetDirectoryName(_AssemblyLocation); } }
208+
209+
#endregion
210+
211+
#region Logging
212+
/// <summary>
213+
/// Some Structured logging to the debug file - ONLY RUNS WHEN DLL COMPILED IN DEBUG MODE
214+
/// </summary>
215+
/// <param name="Message">Text to be printed - can be formatted as per String.format</param>
216+
/// <param name="strParams">Objects to feed into a String.format</param>
217+
[System.Diagnostics.Conditional("DEBUG")]
218+
internal static void LogFormatted_DebugOnly(String Message, params object[] strParams)
219+
{
220+
LogFormatted(Message, strParams);
221+
}
222+
223+
/// <summary>
224+
/// Some Structured logging to the debug file
225+
/// </summary>
226+
/// <param name="Message">Text to be printed - can be formatted as per String.format</param>
227+
/// <param name="strParams">Objects to feed into a String.format</param>
228+
internal static void LogFormatted(String Message, params object[] strParams)
229+
{
230+
Message = String.Format(Message, strParams); // This fills the params into the message
231+
String strMessageLine = String.Format("{0},{2},{1}",
232+
DateTime.Now, Message,
233+
_AssemblyName); // This adds our standardised wrapper to each line
234+
UnityEngine.Debug.Log(strMessageLine); // And this puts it in the log
235+
}
236+
237+
#endregion
238+
239+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
using KSP;
7+
using UnityEngine;
8+
9+
/// <summary>
10+
/// CLass containing some extension methods for Unity Objects
11+
/// </summary>
12+
public static class UnityExtensions
13+
{
14+
/// <summary>
15+
/// Ensure that the Rect remains within the screen bounds
16+
/// </summary>
17+
public static Rect ClampToScreen(this Rect r)
18+
{
19+
return r.ClampToScreen(new RectOffset(0,0,0,0));
20+
}
21+
22+
/// <summary>
23+
/// Ensure that the Rect remains within the screen bounds
24+
/// </summary>
25+
/// <param name="ScreenBorder">A Border to the screen bounds that the Rect will be clamped inside (can be negative)</param>
26+
public static Rect ClampToScreen(this Rect r, RectOffset ScreenBorder)
27+
{
28+
r.x = Mathf.Clamp(r.x, ScreenBorder.left, Screen.width - r.width - ScreenBorder.right);
29+
r.y = Mathf.Clamp(r.y, ScreenBorder.top, Screen.height - r.height -ScreenBorder.bottom);
30+
return r;
31+
}
32+
}

0 commit comments

Comments
 (0)