From 463e26ff7596d9294a9ceb1c58f21971879c46fe Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 10 Sep 2019 11:25:53 -0700 Subject: [PATCH] Change to allow working in installer --- .../Beefy2D/src/theme/dark/DarkEditWidget.bf | 10 +- .../Beefy2D/src/widgets/ScrollableWidget.bf | 20 +- BeefLibs/Beefy2D/src/widgets/WidgetWindow.bf | 2 +- BeefLibs/MiniZ/BeefProj.toml | 6 + {IDE/src/util => BeefLibs/MiniZ/src}/Zip.bf | 84 ++++++-- BeefLibs/corlib/src/System/IO/Directory.bf | 6 +- BeefLibs/corlib/src/System/IO/FileStream.bf | 9 +- BeefLibs/corlib/src/System/IO/Shell.bf | 110 +++++++++++ BeefLibs/corlib/src/System/IO/Stream.bf | 16 ++ BeefLibs/corlib/src/System/IO/StreamWriter.bf | 19 ++ BeefLibs/corlib/src/System/IO/Substream.bf | 78 ++++++++ BeefLibs/corlib/src/System/Platform.bf | 2 + BeefLibs/corlib/src/System/Random.bf | 2 +- BeefLibs/corlib/src/System/String.bf | 67 +++++-- BeefLibs/corlib/src/System/Windows.bf | 182 +++++++++++++++++- BeefySysLib/platform/PlatformInterface.h | 2 + BeefySysLib/platform/win/Platform.cpp | 6 + IDE/dist/BeefConfig.toml | 6 +- IDE/src/ui/AutoComplete.bf | 1 - 19 files changed, 571 insertions(+), 57 deletions(-) create mode 100644 BeefLibs/MiniZ/BeefProj.toml rename {IDE/src/util => BeefLibs/MiniZ/src}/Zip.bf (98%) create mode 100644 BeefLibs/corlib/src/System/IO/Shell.bf create mode 100644 BeefLibs/corlib/src/System/IO/Substream.bf diff --git a/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf b/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf index 64f129fa..63c290e0 100644 --- a/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf +++ b/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf @@ -35,7 +35,7 @@ namespace Beefy.theme.dark mWidth = GS!(100); mHeight = GS!(24); mHorzJumpSize = GS!(40); - mFont = DarkTheme.sDarkTheme.mSmallFont; + mFont = DarkTheme.sDarkTheme?.mSmallFont; } public override void GetTextData() @@ -484,22 +484,24 @@ namespace Beefy.theme.dark if (mEditWidget.mVertPos.IsMoving) brightness = 0; // When we animate a pgup or pgdn, it's weird seeing the cursor scrolling around + Color cursorColor = mTextColors[0]; + if (mOverTypeMode) { if (mCharWidth <= 2) { - using (g.PushColor(Color.Get(brightness * 0.75f))) + using (g.PushColor(Color.Mult(cursorColor, Color.Get(brightness * 0.75f)))) g.FillRect(aX, curY, GS!(2), lineSpacing); } else { - using (g.PushColor(Color.Get(brightness * 0.30f))) + using (g.PushColor(Color.Mult(cursorColor, Color.Get(brightness * 0.30f)))) g.FillRect(aX, curY, mCharWidth, lineSpacing); } } else { - using (g.PushColor(Color.Get(brightness))) + using (g.PushColor(Color.Mult(cursorColor, Color.Get(brightness)))) g.FillRect(aX, curY, Math.Max(1.0f, GS!(1)), lineSpacing); } drewCursor = true; diff --git a/BeefLibs/Beefy2D/src/widgets/ScrollableWidget.bf b/BeefLibs/Beefy2D/src/widgets/ScrollableWidget.bf index 1c89ef41..5e9dc269 100644 --- a/BeefLibs/Beefy2D/src/widgets/ScrollableWidget.bf +++ b/BeefLibs/Beefy2D/src/widgets/ScrollableWidget.bf @@ -67,20 +67,28 @@ namespace Beefy.widgets if (mHorzScrollbar == null) { mHorzScrollbar = ThemeFactory.mDefault.CreateScrollbar(Scrollbar.Orientation.Horz); - mHorzScrollbar.Init(); - mHorzScrollbar.mOnScrollEvent.Add(new => ScrollEventHandler); - AddWidgetAtIndex(0, mHorzScrollbar); } + + if (mHorzScrollbar.mParent == null) + { + mHorzScrollbar.Init(); + mHorzScrollbar.mOnScrollEvent.Add(new => ScrollEventHandler); + AddWidgetAtIndex(0, mHorzScrollbar); + } } if (wantVert) { if (mVertScrollbar == null) { mVertScrollbar = ThemeFactory.mDefault.CreateScrollbar(Scrollbar.Orientation.Vert); - mVertScrollbar.Init(); - mVertScrollbar.mOnScrollEvent.Add(new => ScrollEventHandler); - AddWidgetAtIndex(0, mVertScrollbar); } + + if (mVertScrollbar.mParent == null) + { + mVertScrollbar.Init(); + mVertScrollbar.mOnScrollEvent.Add(new => ScrollEventHandler); + AddWidgetAtIndex(0, mVertScrollbar); + } } else { diff --git a/BeefLibs/Beefy2D/src/widgets/WidgetWindow.bf b/BeefLibs/Beefy2D/src/widgets/WidgetWindow.bf index 3c0b25de..87718912 100644 --- a/BeefLibs/Beefy2D/src/widgets/WidgetWindow.bf +++ b/BeefLibs/Beefy2D/src/widgets/WidgetWindow.bf @@ -429,7 +429,7 @@ namespace Beefy.widgets var result = mOnHitTest(x, y); if (result != HitTestResult.NotHandled) { - if (result == .Transparent) + if ((result == .Transparent) || (result == .Caption)) { if (mHasMouseInside) MouseLeave(); diff --git a/BeefLibs/MiniZ/BeefProj.toml b/BeefLibs/MiniZ/BeefProj.toml new file mode 100644 index 00000000..ea8b0b8f --- /dev/null +++ b/BeefLibs/MiniZ/BeefProj.toml @@ -0,0 +1,6 @@ +FileVersion = 1 + +[Project] +Name = "MiniZ" +TargetType = "BeefLib" +StartupObject = "Program" diff --git a/IDE/src/util/Zip.bf b/BeefLibs/MiniZ/src/Zip.bf similarity index 98% rename from IDE/src/util/Zip.bf rename to BeefLibs/MiniZ/src/Zip.bf index 568c2699..49f35c91 100644 --- a/IDE/src/util/Zip.bf +++ b/BeefLibs/MiniZ/src/Zip.bf @@ -76,6 +76,16 @@ namespace IDE.Util return i; } + public int GetCompressedSize() + { + return mFileStat.mCompSize; + } + + public int GetUncompressedSize() + { + return mFileStat.mUncompSize; + } + public Result GetFileName(String outFileName) { outFileName.Append(&mFileStat.mFilename, GetStrLen(&mFileStat.mFilename, mFileStat.mFilename.Count)); @@ -107,6 +117,15 @@ namespace IDE.Util return .Ok; } + public Result Init(Stream stream) + { + Debug.Assert(!mInitialized); + if (!MiniZ.ZipReaderInitStream(&mFile, stream, .None)) + return .Err; + mInitialized = true; + return .Ok; + } + public int GetNumFiles() { return MiniZ.ZipReaderGetNumFiles(&mFile); @@ -180,7 +199,7 @@ namespace IDE.Util } // Compression/decompression stream struct. - public struct Stream + public struct ZipStream { public uint8* mNextIn; // pointer to next byte to read public uint32 mAvailIn; // number of bytes available at next_in @@ -509,12 +528,12 @@ namespace IDE.Util return VERSION; } - static ReturnStatus DeflateInit(Stream* pStream, CompressionLevel level) + static ReturnStatus DeflateInit(ZipStream* pStream, CompressionLevel level) { return DeflateInit(pStream, level, DEFLATED, DEFAULT_WINDOW_BITS, 9, .DEFAULT_STRATEGY); } - static ReturnStatus DeflateInit(Stream* pStream, CompressionLevel level, int method, int window_bits, int mem_level, CompressionStrategy strategy) + static ReturnStatus DeflateInit(ZipStream* pStream, CompressionLevel level, int method, int window_bits, int mem_level, CompressionStrategy strategy) { tdefl_compressor* pComp; TDEFLFlags comp_flags = TDEFLFlags.TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); @@ -546,7 +565,7 @@ namespace IDE.Util return .OK; } - static ReturnStatus deflateReset(Stream* pStream) + static ReturnStatus deflateReset(ZipStream* pStream) { if ((pStream == null) || (pStream.mState == null) || (pStream.mZAlloc == null) || (pStream.mZFree == null)) return .STREAM_ERROR; pStream.mTotalIn = pStream.mTotalOut = 0; @@ -554,7 +573,7 @@ namespace IDE.Util return .OK; } - static ReturnStatus deflate(Stream* pStream, Flush flushIn) + static ReturnStatus deflate(ZipStream* pStream, Flush flushIn) { Flush flush = flushIn; int in_bytes, out_bytes; @@ -604,7 +623,7 @@ namespace IDE.Util return status; } - static ReturnStatus deflateEnd(Stream* pStream) + static ReturnStatus deflateEnd(ZipStream* pStream) { if (pStream == null) return .STREAM_ERROR; if (pStream.mState != null) @@ -615,7 +634,7 @@ namespace IDE.Util return .OK; } - static uint32 deflateBound(Stream* pStream, uint32 source_len) + static uint32 deflateBound(ZipStream* pStream, uint32 source_len) { // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) return Math.Max(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); @@ -624,8 +643,8 @@ namespace IDE.Util public static ReturnStatus Compress(uint8* pDest, ref int pDest_len, uint8* pSource, int source_len, CompressionLevel level) { ReturnStatus status; - Stream stream = ?; - Internal.MemSet(&stream, 0, sizeof(Stream)); + ZipStream stream = ?; + Internal.MemSet(&stream, 0, sizeof(ZipStream)); // In case uint32 is 64-bits (argh I hate longs). if ((source_len | pDest_len) > 0xFFFFFFFFU) return .PARAM_ERROR; @@ -669,7 +688,7 @@ namespace IDE.Util public TinflStatus m_last_status; } - static ReturnStatus inflateInit2(Stream* pStream, int window_bits) + static ReturnStatus inflateInit2(ZipStream* pStream, int window_bits) { inflate_state* pDecomp; if (pStream == null) return .STREAM_ERROR; @@ -700,12 +719,12 @@ namespace IDE.Util return .OK; } - static ReturnStatus inflateInit(Stream* pStream) + static ReturnStatus inflateInit(ZipStream* pStream) { return inflateInit2(pStream, DEFAULT_WINDOW_BITS); } - static ReturnStatus inflate(Stream* pStream, Flush flushIn) + static ReturnStatus inflate(ZipStream* pStream, Flush flushIn) { Flush flush = flushIn; inflate_state* pState; @@ -799,7 +818,7 @@ namespace IDE.Util return ((status == .Done) && (pState.m_dict_avail == 0)) ? .STREAM_END : .OK; } - static ReturnStatus inflateEnd(Stream* pStream) + static ReturnStatus inflateEnd(ZipStream* pStream) { if (pStream == null) return .STREAM_ERROR; @@ -813,9 +832,9 @@ namespace IDE.Util public static ReturnStatus Uncompress(uint8* pDest, ref int pDest_len, uint8* pSource, int source_len) { - Stream stream = default; + ZipStream stream = default; ReturnStatus status; - Internal.MemSet(&stream, 0, sizeof(Stream)); + Internal.MemSet(&stream, 0, sizeof(ZipStream)); // In case uint32 is 64-bits (argh I hate longs). if ((source_len | pDest_len) > 0xFFFFFFFFU) return .PARAM_ERROR; @@ -2751,6 +2770,7 @@ namespace IDE.Util public ZipArray m_central_dir_offsets; public ZipArray m_sorted_central_dir_offsets; public FILE* m_pFile; + public Stream mStream; public void* m_pMem; public int m_mem_size; public int m_mem_capacity; @@ -3147,6 +3167,40 @@ namespace IDE.Util return true; } + static int ZipFileStreamReadFunc(void* pOpaque, int64 file_ofs, void* pBuf, int n) + { + ZipArchive* pZip = (ZipArchive*)pOpaque; + int64 cur_ofs = pZip.m_pState.mStream.Position; + if (((int64)file_ofs < 0) || (((cur_ofs != (int64)file_ofs)) && (pZip.m_pState.mStream.Seek((int64)file_ofs) case .Err))) + return 0; + switch (pZip.m_pState.mStream.TryRead(.((uint8*)pBuf, n))) + { + case .Ok(let len): + return len; + case .Err: + return 0; + } + } + + public static bool ZipReaderInitStream(ZipArchive* pZip, Stream stream, ZipFlags flags) + { + int64 file_size = stream.Length; + if (!zip_reader_init_internal(pZip, flags)) + { + return false; + } + pZip.m_pRead = => ZipFileStreamReadFunc; + pZip.m_pIO_opaque = pZip; + pZip.m_pState.mStream = stream; + pZip.m_archive_size = file_size; + if (!zip_reader_read_central_dir(pZip, flags)) + { + ZipReaderEnd(pZip); + return false; + } + return true; + } + public static int ZipReaderGetNumFiles(ZipArchive* pZip) { return (pZip != null) ? pZip.m_total_files : 0; diff --git a/BeefLibs/corlib/src/System/IO/Directory.bf b/BeefLibs/corlib/src/System/IO/Directory.bf index 0e780d6f..3ba67b64 100644 --- a/BeefLibs/corlib/src/System/IO/Directory.bf +++ b/BeefLibs/corlib/src/System/IO/Directory.bf @@ -12,7 +12,7 @@ namespace System.IO return Exists(fileName.ToScopeCStr!()); } - public static Result CreateDirectory(StringView fullPath) + public static Result CreateDirectory(StringView fullPath) { for (int32 pass = 0; pass < 2; pass++) { @@ -34,7 +34,7 @@ namespace System.IO continue; } } - return .Err; + return .Err(result); } return .Ok; } @@ -48,7 +48,7 @@ namespace System.IO return .Ok; } - public static Result DelTree(String path) + public static Result DelTree(StringView path) { if (path.Length <= 2) return .Err; diff --git a/BeefLibs/corlib/src/System/IO/FileStream.bf b/BeefLibs/corlib/src/System/IO/FileStream.bf index bddfb44e..4c8258cc 100644 --- a/BeefLibs/corlib/src/System/IO/FileStream.bf +++ b/BeefLibs/corlib/src/System/IO/FileStream.bf @@ -8,13 +8,6 @@ namespace System.IO { protected Platform.BfpFile* mBfpFile; - public enum SeekKind - { - Absolute, - Relative, - FromEnd - }; - public override int64 Position { get @@ -41,7 +34,7 @@ namespace System.IO Close(); } - public Result Seek(int64 pos, SeekKind seekKind = .Absolute) + public override Result Seek(int64 pos, SeekKind seekKind = .Absolute) { int64 newPos = Platform.BfpFile_Seek(mBfpFile, pos, (Platform.BfpFileSeekKind)seekKind); // Ensure position is what was requested diff --git a/BeefLibs/corlib/src/System/IO/Shell.bf b/BeefLibs/corlib/src/System/IO/Shell.bf new file mode 100644 index 00000000..adba06c0 --- /dev/null +++ b/BeefLibs/corlib/src/System/IO/Shell.bf @@ -0,0 +1,110 @@ +#if BF_PLATFORM_WINDOWS + +namespace System.IO +{ + static class Shell + { + + public struct COM_IPersist : Windows.COM_IUnknown + { + public struct VTable : COM_IUnknown.VTable + { + public function HResult(COM_IPersistFile* self, Guid* pClassID) GetClassID; + } + } + + public struct COM_IPersistFile : COM_IPersist + { + public static Guid sIID = .(0x0000010b, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46); + + public struct VTable : COM_IPersist.VTable + { + public function HResult(COM_IPersistFile* self) IsDirty; + public function HResult(COM_IPersistFile* self, char16* pszFileName) Load; + public function HResult(COM_IPersistFile* self, char16* pszFileName, Windows.IntBool remember) Save; + public function HResult(COM_IPersistFile* self, char16* pszFileName) SaveCompleted; + public function HResult(COM_IPersistFile* self, char16* pszName) GetCurFile; + } + public new VTable* VT + { + get + { + return (.)mVT; + } + } + } + + public struct COM_IShellLink : Windows.COM_IUnknown + { + public static Guid sCLSID = .(0x00021401, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46); + public static Guid sIID = .(0x000214F9, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46); + + struct IDLIST; + + public struct VTable : Windows.COM_IUnknown.VTable + { + public function HResult(COM_IShellLink* self, char16* pszFile, int32 cch, Windows.NativeFindData* pfd, uint32 fFlags) GetPath; + public function HResult(COM_IShellLink* self, IDLIST** ppidl) GetIDList; + public function HResult(COM_IShellLink* self, IDLIST* pidl) SetIDList; + public function HResult(COM_IShellLink* self, char16* pszName, int32 cch) GetDescription; + public function HResult(COM_IShellLink* self, char16* pszName) SetDescription; + public function HResult(COM_IShellLink* self, char16* pszDir, int32 cch) GetWorkingDirectory; + public function HResult(COM_IShellLink* self, char16* pszDir) SetWorkingDirectory; + public function HResult(COM_IShellLink* self, char16* pszArgs, int32 cch) GetArguments; + public function HResult(COM_IShellLink* self, char16* pszArgs) SetArguments; + public function HResult(COM_IShellLink* self, uint16 *pwHotkey) GetHotkey; + public function HResult(COM_IShellLink* self, uint16 wHotkey) SetHotkey; + public function HResult(COM_IShellLink* self, int32 *piShowCmd) GetShowCmd; + public function HResult(COM_IShellLink* self, int32 iShowCmd) SetShowCmd; + public function HResult(COM_IShellLink* self, char16* pszIconPath, int32 cch, int32 *piIcon) GetIconLocation; + public function HResult(COM_IShellLink* self, char16* pszIconPath, int32 iIcon) SetIconLocation; + public function HResult(COM_IShellLink* self, char16* pszPathRel, uint32 dwReserved) SetRelativePath; + public function HResult(COM_IShellLink* self, Windows.HWnd hwnd, uint32 fFlags) Resolve; + public function HResult(COM_IShellLink* self, char16* pszFile) SetPath; + + } + public new VTable* VT + { + get + { + return (.)mVT; + } + } + } + + public static Result CreateShortcut(StringView linkPath, StringView targetPath, StringView arguments, StringView workingDirectory, StringView description) + { + COM_IShellLink* shellLink = null; + COM_IPersistFile* persistFile = null; + + defer + { + if (persistFile != null) + persistFile.VT.Release(persistFile); + if (shellLink != null) + shellLink.VT.Release(shellLink); + } + + mixin TryHR(Windows.COM_IUnknown.HResult result) + { + if (result != .OK) + return .Err; + } + + TryHR!(Windows.COM_IUnknown.CoCreateInstance(ref COM_IShellLink.sCLSID, null, .INPROC_SERVER, ref COM_IShellLink.sIID, (void**)&shellLink)); + TryHR!(shellLink.VT.SetPath(shellLink, targetPath.ToScopedNativeWChar!())); + if (!arguments.IsEmpty) + TryHR!(shellLink.VT.SetArguments(shellLink, arguments.ToScopedNativeWChar!())); + if (!workingDirectory.IsEmpty) + TryHR!(shellLink.VT.SetWorkingDirectory(shellLink, workingDirectory.ToScopedNativeWChar!())); + if (!description.IsEmpty) + TryHR!(shellLink.VT.SetDescription(shellLink, description.ToScopedNativeWChar!())); + TryHR!(shellLink.VT.QueryInterface(shellLink, ref COM_IPersistFile.sIID, (void**)&persistFile)); + TryHR!(persistFile.VT.Save(persistFile, linkPath.ToScopedNativeWChar!(), true)); + + return .Ok; + } + } +} + +#endif \ No newline at end of file diff --git a/BeefLibs/corlib/src/System/IO/Stream.bf b/BeefLibs/corlib/src/System/IO/Stream.bf index e8758825..8fd9ed2b 100644 --- a/BeefLibs/corlib/src/System/IO/Stream.bf +++ b/BeefLibs/corlib/src/System/IO/Stream.bf @@ -14,6 +14,13 @@ namespace System.IO private ReadWriteTask _activeReadWriteTask; private SemaphoreSlim _asyncActiveSemaphore; + public enum SeekKind + { + Absolute, + Relative, + FromEnd + } + public abstract int64 Position { get; @@ -43,6 +50,15 @@ namespace System.IO } } + public virtual Result Seek(int64 pos, SeekKind seekKind = .Absolute) + { + if (seekKind == .Absolute) + Position = pos; + else + Runtime.FatalError(); + return .Ok; + } + public abstract Result TryRead(Span data); public abstract Result TryWrite(Span data); public abstract void Close(); diff --git a/BeefLibs/corlib/src/System/IO/StreamWriter.bf b/BeefLibs/corlib/src/System/IO/StreamWriter.bf index b4387276..3e55e4e9 100644 --- a/BeefLibs/corlib/src/System/IO/StreamWriter.bf +++ b/BeefLibs/corlib/src/System/IO/StreamWriter.bf @@ -11,6 +11,10 @@ namespace System.IO public bool AutoFlush; + public this() + { + } + public this(Stream stream, Encoding encoding, int32 bufferSize, bool ownsStream = false) { Debug.Assert(encoding != null); @@ -19,6 +23,21 @@ namespace System.IO mOwnsStream = ownsStream; } + public Result Create(StringView fileName) + { + Debug.Assert(mStream == null); + + var fileStream = new FileStream(); + mStream = fileStream; + mEncoding = .UTF8; + mOwnsStream = true; + + if (fileStream.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite) case .Err(let err)) + return .Err(err); + + return .Ok; + } + public Result Write(Span data) { var spanLeft = data; diff --git a/BeefLibs/corlib/src/System/IO/Substream.bf b/BeefLibs/corlib/src/System/IO/Substream.bf new file mode 100644 index 00000000..dbc0dca7 --- /dev/null +++ b/BeefLibs/corlib/src/System/IO/Substream.bf @@ -0,0 +1,78 @@ +using System.IO; + +namespace System.IO +{ + class Substream : Stream + { + public bool mOwnsStream; + Stream mChildStream ~ { if (mOwnsStream) delete _; }; + int64 mOffset; + int64 mLength; + + public override int64 Position + { + get + { + return mChildStream.Position + mOffset; + } + + set + { + mChildStream.Position = value + mOffset; + } + } + + public override int64 Length + { + get + { + return mLength; + } + } + + public override bool CanRead + { + get + { + return mChildStream.CanRead; + } + } + + public override bool CanWrite + { + get + { + return mChildStream.CanWrite; + } + } + + + public this(Stream childStream, int64 offset, int64 length, bool ownsStream = false) + { + mChildStream = childStream; + mOffset = offset; + mLength = length; + mOwnsStream = ownsStream; + } + + public override Result TryRead(Span data) + { + return mChildStream.TryRead(data); + } + + public override Result TryWrite(Span data) + { + return mChildStream.TryWrite(data); + } + + public override void Close() + { + mChildStream.Close(); + } + + public override void Flush() + { + mChildStream.Flush(); + } + } +} diff --git a/BeefLibs/corlib/src/System/Platform.bf b/BeefLibs/corlib/src/System/Platform.bf index 93354eca..6836db17 100644 --- a/BeefLibs/corlib/src/System/Platform.bf +++ b/BeefLibs/corlib/src/System/Platform.bf @@ -400,6 +400,8 @@ namespace System AppData_Local, AppData_LocalLow, AppData_Roaming, + Programs, + Programs_Common } public static Result GetStrHelper(String outStr, delegate void (char8* outPtr, int32* outSize, Result* outResult) func) diff --git a/BeefLibs/corlib/src/System/Random.bf b/BeefLibs/corlib/src/System/Random.bf index 5c4a454c..b861cf13 100644 --- a/BeefLibs/corlib/src/System/Random.bf +++ b/BeefLibs/corlib/src/System/Random.bf @@ -40,7 +40,7 @@ namespace System private int32 inextp; private int32[] SeedArray = new int32[56] ~ delete _; - private int32 sSeed = (int32)Environment.TickCount; + private static int32 sSeed = (int32)Platform.BfpSystem_GetTimeStamp(); // // Public Constants diff --git a/BeefLibs/corlib/src/System/String.bf b/BeefLibs/corlib/src/System/String.bf index 104702e2..c5057000 100644 --- a/BeefLibs/corlib/src/System/String.bf +++ b/BeefLibs/corlib/src/System/String.bf @@ -2373,6 +2373,7 @@ namespace System struct StringSplitEnumerator : IEnumerator { StringSplitOptions mSplitOptions; + char8 mSplitChar0; char8[] mSplitChars; char8* mPtr; int_strsize mStrLen; @@ -2385,6 +2386,10 @@ namespace System { mPtr = ptr; mStrLen = (int_strsize)strLength; + if (splitChars.Count > 0) + mSplitChar0 = splitChars[0]; + else + mSplitChar0 = '\0'; mSplitChars = splitChars; mCurCount = 0; mMaxCount = (int32)count; @@ -2393,6 +2398,19 @@ namespace System mSplitOptions = splitOptions; } + public this(char8* ptr, int strLength, char8 splitChar, int count, StringSplitOptions splitOptions) + { + mPtr = ptr; + mStrLen = (int_strsize)strLength; + mSplitChar0 = splitChar; + mSplitChars = null; + mCurCount = 0; + mMaxCount = (int32)count; + mPos = 0; + mMatchPos = -1; + mSplitOptions = splitOptions; + } + public StringView Current { get @@ -2443,9 +2461,6 @@ namespace System return true; } - char8 splitChar0 = mSplitChars[0]; - int splitCharCount = mSplitChars.Count; - int endDiff = mStrLen - mMatchPos; if (endDiff == 0) return false; @@ -2461,13 +2476,13 @@ namespace System else { char8 c = mPtr[mMatchPos]; - if (c == splitChar0) + if (c == mSplitChar0) { foundMatch = true; } - else if (splitCharCount > 1) + else if (mSplitChars != null) { - for (int i = 1; i < splitCharCount; i++) + for (int i = 1; i < mSplitChars.Count; i++) if (c == mSplitChars[i]) foundMatch = true; } @@ -2478,6 +2493,8 @@ namespace System if ((mMatchPos > mPos + 1) || (!mSplitOptions.HasFlag(StringSplitOptions.RemoveEmptyEntries))) return true; mPos = mMatchPos + 1; + if (mPos >= mStrLen) + return false; } } } @@ -2585,6 +2602,17 @@ namespace System } } + public bool IsWhiteSpace + { + get + { + for (int i = 0; i < mLength; i++) + if (!mPtr[i].IsWhiteSpace) + return false; + return true; + } + } + public int GetHashCode() { return String.[Friend]GetHashCode(mPtr, mLength); @@ -2893,17 +2921,32 @@ namespace System return (c32, idx, len); } + public StringSplitEnumerator Split(char8 c) + { + return StringSplitEnumerator(Ptr, Length, c, Int32.MaxValue, StringSplitOptions.None); + } + + public StringSplitEnumerator Split(char8 separator, int count) + { + return StringSplitEnumerator(Ptr, Length, separator, count, StringSplitOptions.None); + } + + public StringSplitEnumerator Split(char8 separator, StringSplitOptions options) + { + return StringSplitEnumerator(Ptr, Length, separator, Int32.MaxValue, options); + } + + public StringSplitEnumerator Split(char8 separator, int count, StringSplitOptions options) + { + return StringSplitEnumerator(Ptr, Length, separator, count, options); + } + public StringSplitEnumerator Split(params char8[] separators) { return StringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None); } - public StringSplitEnumerator Split(char8[] separators, int count) - { - return StringSplitEnumerator(Ptr, Length, separators, count, StringSplitOptions.None); - } - - public StringSplitEnumerator Split(char8[] separators, int count, StringSplitOptions options) + public StringSplitEnumerator Split(char8[] separators, int count = Int32.MaxValue, StringSplitOptions options = .None) { return StringSplitEnumerator(Ptr, Length, separators, count, options); } diff --git a/BeefLibs/corlib/src/System/Windows.bf b/BeefLibs/corlib/src/System/Windows.bf index 603805a9..eedc8d9f 100644 --- a/BeefLibs/corlib/src/System/Windows.bf +++ b/BeefLibs/corlib/src/System/Windows.bf @@ -46,7 +46,7 @@ namespace System public struct VTable { - public function void(COM_IUnknown* self, ref Guid riid, out void* result) QueryInterface; + public function HResult(COM_IUnknown* self, ref Guid riid, void** result) QueryInterface; public function HResult(COM_IUnknown* self) AddRef; public function HResult(COM_IUnknown* self) Release; } @@ -188,6 +188,7 @@ namespace System public const int32 MB_YESNO = 4; public const int32 MB_ICONHAND = 0x10; + public const int32 MB_ICONQUESTION = 0x20; public const int32 IDOK = 1; public const int32 IDYES = 6; @@ -339,7 +340,7 @@ namespace System bool gotData = false; GetValue(name, scope [&] (regType, regData) => { - if (regType == Windows.REG_SZ) + if ((regType == Windows.REG_SZ) || (regType == Windows.REG_EXPAND_SZ)) { gotData = true; var span = Span((char16*)regData.Ptr, regData.Length / 2); @@ -419,11 +420,27 @@ namespace System Runtime.NotImplemented(); //return Variant.Create(1234); } + + public Result SetValue(StringView name, StringView strValue) + { + let result = Windows.RegSetValueExA(this, name.ToScopeCStr!(), 0, Windows.REG_SZ, strValue.ToScopeCStr!(), (uint32)strValue.Length + 1); + if (result != 0) + return .Err; + return .Ok; + } + + public Result SetValueExpand(StringView name, StringView strValue) + { + let result = Windows.RegSetValueExA(this, name.ToScopeCStr!(), 0, Windows.REG_EXPAND_SZ, strValue.ToScopeCStr!(), (uint32)strValue.Length + 1); + if (result != 0) + return .Err; + return .Ok; + } } public struct HWnd : int { - + public const HWnd Broadcast = (.)0xFFFF; } public struct HModule : int @@ -867,6 +884,7 @@ namespace System public const int32 WM_KEYDOWN = 0x0100; public const int32 WM_KEYUP = 0x0101; public const int32 WM_CHAR = 0x0102; + public const int32 WM_SETTINGCHANGE = 0x001A; public const int32 BFFM_INITIALIZED = 1; public const int32 BFFM_SELCHANGED = 2; @@ -932,6 +950,154 @@ namespace System public const int32 TIME_ZONE_ID_INVALID = -1; + public const int32 OBJECT_INHERIT_ACE = 1; + public const int32 CONTAINER_INHERIT_ACE = 2; + public const int32 NO_PROPAGATE_INHERIT_ACE = 4; + public const int32 INHERIT_ONLY_ACE = 8; + public const int32 INHERITED_ACE = 0x10; + public const int32 VALID_INHERIT_FLAGS = 0x1F; + + public const int32 SMTO_NORMAL = 0x0000; + public const int32 SMTO_BLOCK = 0x0001; + public const int32 SMTO_ABORTIFHUNG = 0x0002; + + enum SECURITY_INFORMATION : int32 + { + DACL_SECURITY_INFORMATION = 4 + } + + enum SE_OBJECT_TYPE : int32 + { + SE_UNKNOWN_OBJECT_TYPE, + SE_FILE_OBJECT, + SE_SERVICE, + SE_PRINTER, + SE_REGISTRY_KEY, + SE_LMSHARE, + SE_KERNEL_OBJECT, + SE_WINDOW_OBJECT, + SE_DS_OBJECT, + SE_DS_OBJECT_ALL, + SE_PROVIDER_DEFINED_OBJECT, + SE_WMIGUID_OBJECT, + SE_REGISTRY_WOW64_32KEY, + SE_REGISTRY_WOW64_64KEY + } + + public struct SID; + public struct SECURITY_DESCRIPTOR; + + [CRepr] + public struct ACL + { + uint8 AclRevision; + uint8 Sbz1; + uint16 AclSize; + uint16 AceCount; + uint16 Sbz2; + } + + public enum ACCESS_MODE : int32 + { + NOT_USED_ACCESS = 0, + GRANT_ACCESS, + SET_ACCESS, + DENY_ACCESS, + REVOKE_ACCESS, + SET_AUDIT_SUCCESS, + SET_AUDIT_FAILURE + } + + public enum MULTIPLE_TRUSTEE_OPERATION : int32 + { + NO_MULTIPLE_TRUSTEE, + TRUSTEE_IS_IMPERSONATE, + } + + public enum TRUSTEE_FORM : int32 + { + TRUSTEE_IS_SID, + TRUSTEE_IS_NAME, + TRUSTEE_BAD_FORM, + TRUSTEE_IS_OBJECTS_AND_SID, + TRUSTEE_IS_OBJECTS_AND_NAME + } + + public enum TRUSTEE_TYPE : int32 + { + TRUSTEE_IS_UNKNOWN, + TRUSTEE_IS_USER, + TRUSTEE_IS_GROUP, + TRUSTEE_IS_DOMAIN, + TRUSTEE_IS_ALIAS, + TRUSTEE_IS_WELL_KNOWN_GROUP, + TRUSTEE_IS_DELETED, + TRUSTEE_IS_INVALID, + TRUSTEE_IS_COMPUTER + } + + [CRepr] + public struct TRUSTEE_W + { + TRUSTEE_W* pMultipleTrustee; + MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation; + TRUSTEE_FORM TrusteeForm; + TRUSTEE_TYPE TrusteeType; + char16* ptstrName; + } + + [CRepr] + public struct EXPLICIT_ACCESS_W + { + uint32 grfAccessPermissions; + ACCESS_MODE grfAccessMode; + uint32 grfInheritance; + TRUSTEE_W Trustee; + } + + [Import("advapi32.lib"), CLink, StdCall] + public static extern uint32 GetNamedSecurityInfoW( + char16* pObjectName, + SE_OBJECT_TYPE ObjectType, + SECURITY_INFORMATION SecurityInfo, + SID** ppsidOwner, + SID** ppsidGroup, + ACL** ppDacl, + ACL** ppSacl, + SECURITY_DESCRIPTOR* *ppSecurityDescriptor + ); + + [Import("advapi32.lib"), CLink, StdCall] + public static extern void BuildExplicitAccessWithNameW( + EXPLICIT_ACCESS_W* pExplicitAccess, + char16* pTrusteeName, + uint32 AccessPermissions, + ACCESS_MODE AccessMode, + uint32 Inheritance + ); + + [Import("advapi32.lib"), CLink, StdCall] + public static extern uint32 SetEntriesInAclW( + uint32 cCountOfExplicitEntries, + EXPLICIT_ACCESS_W* pListOfExplicitEntries, + ACL* OldAcl, + ACL** NewAcl + ); + + [Import("advapi32.lib"), CLink, StdCall] + public static extern uint32 SetNamedSecurityInfoW( + char16* pObjectName, + SE_OBJECT_TYPE ObjectType, + SECURITY_INFORMATION SecurityInfo, + SID* psidOwner, + SID* psidGroup, + ACL* pDacl, + ACL* pSacl + ); + + [CLink, StdCall] + public static extern void LocalFree(void* ptr); + [CLink, StdCall] public static extern int32 GetTimeZoneInformation(out TimeZoneInformation dynamicTimeZoneInformation); @@ -953,6 +1119,9 @@ namespace System [Import("advapi32.lib"), CLink, StdCall] public static extern int32 RegGetValueA(HKey hkey, char8* lpSubKey, char8* lpValue, uint32 dwFlags, uint32* pdwType, void* pvData, uint32* pcbData); + [Import("advapi32.lib"), CLink, StdCall] + public static extern int32 RegSetValueExA(HKey hkey, char8* lpValue, uint32 reserved, uint32 dwType, void* pvData, uint32 cbData); + [Import("shell32.lib"), CLink, StdCall] public static extern int32 SHGetSpecialFolderLocation(HWnd hwnd, int32 csidl, ref int ppidl); @@ -1124,7 +1293,7 @@ namespace System public static extern int32 MessageBoxA(HWnd hWnd, char8* text, char8* caption, int32 type); [CLink, StdCall] - public static extern int32 MessageBoxW(HWnd hWnd, char16* text, char8* caption, int32 type); + public static extern int32 MessageBoxW(HWnd hWnd, char16* text, char16* caption, int32 type); [CLink, StdCall] public static extern int32 SetErrorMode(int32 errorMode); @@ -1182,7 +1351,10 @@ namespace System public static extern IntBool PostMessageW(HWnd hWnd, int32 msg, int wParam, int lParam); [Import("user32.lib"), CLink, StdCall] - public static extern IntBool SendMessageW(HWnd hWnd, int32 msg, int wParam, int lParam); + public static extern int32 SendMessageW(HWnd hWnd, int32 msg, int wParam, int lParam); + + [Import("user32.lib"), CLink, StdCall] + public static extern int32 SendMessageTimeoutW(HWnd hWnd, int32 msg, int wParam, int lParam, int32 flags, int32 timeout, int32* result); [Import("user32.lib "), CLink, StdCall] public static extern HWnd SetFocus(HWnd hWnd); diff --git a/BeefySysLib/platform/PlatformInterface.h b/BeefySysLib/platform/PlatformInterface.h index 4c577088..d77a3112 100644 --- a/BeefySysLib/platform/PlatformInterface.h +++ b/BeefySysLib/platform/PlatformInterface.h @@ -286,6 +286,8 @@ enum BfpSysDirectoryKind BfpSysDirectoryKind_AppData_Local, BfpSysDirectoryKind_AppData_LocalLow, BfpSysDirectoryKind_AppData_Roaming, + BfpSysDirectoryKind_Programs, + BfpSysDirectoryKind_Programs_Common }; struct BfpFindFileData; diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp index 8e67987c..d76cc8fd 100644 --- a/BeefySysLib/platform/win/Platform.cpp +++ b/BeefySysLib/platform/win/Platform.cpp @@ -2563,6 +2563,12 @@ BFP_EXPORT void BFP_CALLTYPE BfpDirectory_GetSysDirectory(BfpSysDirectoryKind sy case BfpSysDirectoryKind_AppData_Roaming: _GetKnownFolder(FOLDERID_RoamingAppData); return; + case BfpSysDirectoryKind_Programs: + _GetKnownFolder(FOLDERID_Programs); + return; + case BfpSysDirectoryKind_Programs_Common: + _GetKnownFolder(FOLDERID_CommonPrograms); + return; } TryStringOut(path, outPath, inOutPathLen, (BfpResult*)outResult); diff --git a/IDE/dist/BeefConfig.toml b/IDE/dist/BeefConfig.toml index b9e9315d..3c0cdd01 100644 --- a/IDE/dist/BeefConfig.toml +++ b/IDE/dist/BeefConfig.toml @@ -12,4 +12,8 @@ Location = { Path = "../../BeefLibs/Beefy2D" } [Registry.SDL2] Version = "1.0.0" -Location = { Path = "../../BeefLibs/SDL2" } \ No newline at end of file +Location = { Path = "../../BeefLibs/SDL2" } + +[Registry.MiniZ] +Version = "1.0.0" +Location = { Path = "../../BeefLibs/MiniZ" } \ No newline at end of file diff --git a/IDE/src/ui/AutoComplete.bf b/IDE/src/ui/AutoComplete.bf index 4397b23a..637da70a 100644 --- a/IDE/src/ui/AutoComplete.bf +++ b/IDE/src/ui/AutoComplete.bf @@ -1919,7 +1919,6 @@ namespace IDE.ui infoSections[i].ToString(str); mInvokeSrcPositions.Add(int32.Parse(str)); } - Debug.WriteLine("Invoke size: {}", mInvokeSrcPositions.Count); } case "invokeLeftParen": {