Browse Source

Added 'Dispose' capabilities to Result

Brian Fiete 6 years ago
parent
commit
f5cc8190ef

+ 75 - 0
BeefLibs/corlib/src/System/Result.bf

@@ -59,10 +59,37 @@ namespace System
 			return default(T);
 		}
 
+		[SkipCall]
+		public void Dispose()
+		{
+
+		}
+
+		[SkipCall]
+		static void NoDispose<TVal>()
+		{
+
+		}
+
+		static void NoDispose<TVal>() where TVal : IDisposable
+		{
+			Internal.FatalError("Result must be disposed", 1);
+		}
+
 		public void ReturnValueDiscarded()
 		{
 		    if (this case .Err(let err))
 				Internal.FatalError("Unhandled error in result", 1);
+			NoDispose<T>();
+		}
+	}
+
+	extension Result<T> where T : IDisposable
+	{
+		public void Dispose()
+		{
+			if (this case .Ok(var val))
+				val.Dispose();
 		}
 	}
 
@@ -116,12 +143,60 @@ namespace System
 			return default(T);
 		}
 
+		[SkipCall]
+		public void Dispose()
+		{
+
+		}
+
+		[SkipCall]
+		static void NoDispose<TVal>()
+		{
+
+		}
+
+		static void NoDispose<TVal>() where TVal : IDisposable
+		{
+			Internal.FatalError("Result must be disposed", 1);
+		}
+
 		public void ReturnValueDiscarded()
 		{
 		    if (this case .Err(var err))
 			{
 				Internal.FatalError(scope String()..AppendF("Unhandled error in result:\n ", err), 1);
 			}
+			NoDispose<T>();
+			NoDispose<TErr>();
+		}
+	}
+
+	extension Result<T, TErr> where T : IDisposable
+	{
+		public void Dispose()
+		{
+			if (this case .Ok(var val))
+				val.Dispose();
+		}
+	}
+
+	extension Result<T, TErr> where TErr : IDisposable
+	{
+		public void Dispose()
+		{
+			if (this case .Err(var err))
+				err.Dispose();
+		}
+	}
+
+	extension Result<T, TErr> where T : IDisposable where TErr : IDisposable
+	{
+		public void Dispose()
+		{
+			if (this case .Ok(var val))
+				val.Dispose();
+			else if (this case .Err(var err))
+				err.Dispose();
 		}
 	}
 }

+ 37 - 4
BeefLibs/corlib/src/System/Windows.bf

@@ -55,6 +55,12 @@ namespace System
 			{
 				case OK;
 
+				public const HResult NOERROR = (.)0;
+				public const HResult E_INVALIDARG = (.)0x80000003L;
+				public const HResult E_ABORT = (.)0x80004004L;
+				public const HResult E_FAIL = (.)0x80004005L;
+				public const HResult E_ACCESSDENIED = (.)0x80070005L;
+
 				public bool Failed
 				{
 					get
@@ -186,6 +192,10 @@ namespace System
 		public const int32 REG_QWORD             = 11; // 64-bit number
 		public const int32 REG_QWORD_LITTLE_ENDIAN = 11; // 64-bit number (same as REG_QWORD)
 
+		public const int32 REG_OPTION_NON_VOLATILE = 0;
+
+		public const int32 KEY_ALL_ACCESS = 0x000f003f;
+
 		public const int32 MB_YESNO 			= 4;
 		public const int32 MB_ICONHAND 			= 0x10;
 		public const int32 MB_ICONQUESTION		= 0x20;
@@ -338,7 +348,7 @@ namespace System
 			public Result<void> GetValue(StringView name, String outData)
 			{
 				bool gotData = false;
-				GetValue(name, scope [&] (regType, regData) =>
+				Try!(GetValue(name, scope [&] (regType, regData) =>
 					{
 						if ((regType == Windows.REG_SZ) || (regType == Windows.REG_EXPAND_SZ))
 						{
@@ -348,7 +358,7 @@ namespace System
 								span.RemoveFromEnd(1);
 							outData.Append(span);
 						}
-					});
+					}));
 				if (!gotData)
 					return .Err;
 				return .Ok;
@@ -358,14 +368,14 @@ namespace System
 			{
 				bool gotData = false;
 				int sizeofT = sizeof(T);
-				GetValue(name, scope [&] (regType, regData) =>
+				Try!(GetValue(name, scope [&] (regType, regData) =>
 					{
 						if ((regType == Windows.REG_BINARY) && (regData.Length == sizeofT))
 						{
 							Internal.MemCpy(&data, regData.Ptr, sizeofT);
 							gotData = true;
 						}
-					});
+					}));
 				if (!gotData)
 					return .Err;
 				return .Ok;
@@ -421,6 +431,15 @@ namespace System
 				//return Variant.Create<int>(1234);
 			}
 
+			public Result<void> SetValue(StringView name, uint32 val)
+			{
+				var val;
+				let result = Windows.RegSetValueExA(this, name.ToScopeCStr!(), 0,  Windows.REG_DWORD, &val, 4);
+				if (result != 0)
+					return .Err;
+				return .Ok;
+			}
+
 			public Result<void> SetValue(StringView name, StringView strValue)
 			{
 				let result = Windows.RegSetValueExA(this, name.ToScopeCStr!(), 0,  Windows.REG_SZ, strValue.ToScopeCStr!(), (uint32)strValue.Length + 1);
@@ -831,6 +850,7 @@ namespace System
 		public const int32 ERROR_INVALID_FUNCTION = 0x1;
 		public const int32 ERROR_FILE_NOT_FOUND = 0x2;
 		public const int32 ERROR_PATH_NOT_FOUND = 0x3;
+		public const int32 ERROR_ACCESS_DENIED = 0x5;
 		public const int32 ERROR_INVALID_HANDLE = 0x6;
 		public const int32 ERROR_NOT_ENOUGH_MEMORY = 0x8;
 		public const int32 ERROR_INVALID_DATA = 0xd;
@@ -1107,9 +1127,19 @@ namespace System
 		[Import("advapi32.lib"), CLink, StdCall]
 		public static extern int32 RegOpenKeyExA(HKey hKey, char8* lpSubKey, uint32 ulOptions, uint32 samDesired, out HKey phkResult);
 
+		[Import("advapi32.lib"), CLink, StdCall]
+		public static extern int32 RegCreateKeyExW(HKey hKey, char16* lpSubKey, uint32 reserved, char16* lpClass, uint32 dwOptions, uint32 samDesired,
+			SecurityAttributes* lpSecurityAttributes, out HKey phkResult, uint32* lpdwDisposition);
+
 		[Import("advapi32.lib"), CLink, StdCall]
 		public static extern int32 RegCloseKey(HKey hKey);
 
+		[Import("advapi32.lib"), CLink, StdCall]
+		public static extern int32 RegDeleteKeyA(HKey hKey, char8* lpSubKey);
+
+		[Import("advapi32.lib"), CLink, StdCall]
+		public static extern int32 RegDeleteValueA(HKey hKey, char8* lpSubKey);
+
 		[Import("advapi32.lib"), CLink, StdCall]
 		public static extern int32 RegQueryValueExW(HKey hKey, char16* lpValueName, uint32* lpReserved, uint32* lpType, void* lpData, uint32* lpcbData);
 
@@ -1421,6 +1451,9 @@ namespace System
 		public static extern IntBool GetFileMUIPath(uint32 dwFlags, char16* pcwszFilePath, char16* pwszLanguage, uint32* pcchLanguage,
 			char16* pwszFileMUIPath, uint32* pcchFileMUIPath, uint64* pululEnumerator);
 
+		[CLink, StdCall]
+		public static extern IntBool SetDllDirectoryW(char16* libFileName);
+
 		[CLink, StdCall]
 		public static extern HInstance LoadLibraryW(char16* libFileName);
 

+ 5 - 2
BeefySysLib/platform/PlatformInterface.h

@@ -45,7 +45,8 @@ enum BfpResult
 	BfpResult_AccessError,	
 	BfpResult_PartialData,	
 	BfpResult_TempFileError,	
-	BfpResult_Timeout
+	BfpResult_Timeout,
+	BfpResult_NotEmpty
 };
 
 enum BfpSystemResult
@@ -67,7 +68,8 @@ enum BfpFileResult
 	BfpFileResult_AccessError = BfpResult_AccessError,	
 	BfpFileResult_PartialData = BfpResult_PartialData,
 	BfpFileResult_InsufficientBuffer = BfpResult_InsufficientBuffer,	
-	BfpFileResult_Timeout = BfpResult_Timeout
+	BfpFileResult_Timeout = BfpResult_Timeout,
+	BfpFileResult_NotEmpty = BfpResult_NotEmpty
 };
 
 typedef void(*BfpCrashInfoFunc)();
@@ -283,6 +285,7 @@ enum BfpSysDirectoryKind
 	BfpSysDirectoryKind_Home,
 	BfpSysDirectoryKind_System,
 	BfpSysDirectoryKind_Desktop,
+	BfpSysDirectoryKind_Desktop_Common,
 	BfpSysDirectoryKind_AppData_Local,
 	BfpSysDirectoryKind_AppData_LocalLow,
 	BfpSysDirectoryKind_AppData_Roaming,

+ 74 - 0
IDE/mintest/minlib/src/System/Result.bf

@@ -50,10 +50,37 @@ namespace System
 			return default(T);
 		}
 
+		[SkipCall]
+		public void Dispose()
+		{
+
+		}
+
+		[SkipCall]
+		public static void NoDispose<TVal>()
+		{
+
+		}
+
+		public static void NoDispose<TVal>() where TVal : IDisposable
+		{
+			Internal.FatalError("Result must be disposed", 1);
+		}
+
 		public void ReturnValueDiscarded()
 		{
 		    if (this case .Err)
 				Internal.FatalError("Unhandled error in result", 1);
+			NoDispose<T>();
+		}
+	}
+
+	extension Result<T> where T : IDisposable
+	{
+		public void Dispose()
+		{
+			if (this case .Ok(var val))
+				val.Dispose();
 		}
 	}
 
@@ -111,6 +138,23 @@ namespace System
 			return default(T);
 		}
 
+		[SkipCall]
+		public void Dispose()
+		{
+
+		}
+
+		[SkipCall]
+		public static void NoDispose<TVal>()
+		{
+
+		}
+
+		public static void NoDispose<TVal>() where TVal : IDisposable
+		{
+			Internal.FatalError("Result must be disposed", 1);
+		}
+
 		public void ReturnValueDiscarded()
 		{
 		    if (this case .Err(var err))
@@ -121,6 +165,36 @@ namespace System
 				showErr.ConcatInto("Unhandled error in result:\n ", errStr);
 				Internal.FatalError(showErr, 1);
 			}
+			NoDispose<T>();
+		}
+	}
+
+	extension Result<T, TErr> where T : IDisposable
+	{
+		public void Dispose()
+		{
+			if (this case .Ok(var val))
+				val.Dispose();
+		}
+	}
+
+	extension Result<T, TErr> where TErr : IDisposable
+	{
+		public void Dispose()
+		{
+			if (this case .Err(var err))
+				err.Dispose();
+		}
+	}
+
+	extension Result<T, TErr> where T : IDisposable where TErr : IDisposable
+	{
+		public void Dispose()
+		{
+			if (this case .Ok(var val))
+				val.Dispose();
+			else if (this case .Err(var err))
+				err.Dispose();
 		}
 	}
 }