diff --git a/Facepunch.Steamworks/Facepunch.Steamworks.csproj b/Facepunch.Steamworks/Facepunch.Steamworks.csproj index 97bbc70..21d3f90 100644 --- a/Facepunch.Steamworks/Facepunch.Steamworks.csproj +++ b/Facepunch.Steamworks/Facepunch.Steamworks.csproj @@ -144,6 +144,7 @@ + diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.Helpers.cs b/Facepunch.Steamworks/SteamNative/SteamNative.Helpers.cs new file mode 100644 index 0000000..eea11aa --- /dev/null +++ b/Facepunch.Steamworks/SteamNative/SteamNative.Helpers.cs @@ -0,0 +1,37 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; +using System.Collections.Generic; + +namespace SteamNative +{ + internal static class Helpers + { + private static StringBuilder[] StringBuilderPool; + private static int StringBuilderPoolIndex; + + /// + /// Returns a StringBuilder. This will get returned and reused later on. + /// + public static StringBuilder TakeStringBuilder() + { + if ( StringBuilderPool == null ) + { + // + // The pool has 8 items. This should be safe because we shouldn't really + // ever be using more than 2 StringBuilders at the same time. + // + StringBuilderPool = new StringBuilder[8]; + + for ( int i = 0; i < StringBuilderPool.Length; i++ ) + StringBuilderPool[i] = new StringBuilder( 4096 ); + } + + StringBuilderPoolIndex++; + if ( StringBuilderPoolIndex >= StringBuilderPool.Length ) + StringBuilderPoolIndex = 0; + + return StringBuilderPool[StringBuilderPoolIndex]; + } + } +} diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.SteamAppList.cs b/Facepunch.Steamworks/SteamNative/SteamNative.SteamAppList.cs index 13796e9..d9986ab 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.SteamAppList.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.SteamAppList.cs @@ -53,7 +53,7 @@ public int GetAppBuildId( AppId_t nAppID /*AppId_t*/ ) public string GetAppInstallDir( AppId_t nAppID /*AppId_t*/ ) { int bSuccess = default( int ); - System.Text.StringBuilder pchDirectory_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchDirectory_sb = Helpers.TakeStringBuilder(); int cchNameMax = 4096; bSuccess = platform.ISteamAppList_GetAppInstallDir( nAppID.Value, pchDirectory_sb, cchNameMax ); if ( bSuccess <= 0 ) return null; @@ -65,7 +65,7 @@ public string GetAppInstallDir( AppId_t nAppID /*AppId_t*/ ) public string GetAppName( AppId_t nAppID /*AppId_t*/ ) { int bSuccess = default( int ); - System.Text.StringBuilder pchName_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder(); int cchNameMax = 4096; bSuccess = platform.ISteamAppList_GetAppName( nAppID.Value, pchName_sb, cchNameMax ); if ( bSuccess <= 0 ) return null; diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.SteamApps.cs b/Facepunch.Steamworks/SteamNative/SteamNative.SteamApps.cs index 434315d..f0288fd 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.SteamApps.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.SteamApps.cs @@ -48,7 +48,7 @@ public bool BGetDLCDataByIndex( int iDLC /*int*/, ref AppId_t pAppID /*AppId_t * { bool bSuccess = default( bool ); pchName = string.Empty; - System.Text.StringBuilder pchName_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder(); int cchNameBufferSize = 4096; bSuccess = platform.ISteamApps_BGetDLCDataByIndex( iDLC, ref pAppID.Value, ref pbAvailable, pchName_sb, cchNameBufferSize ); if ( !bSuccess ) return bSuccess; @@ -115,7 +115,7 @@ public int GetAppBuildId() public string GetAppInstallDir( AppId_t appID /*AppId_t*/ ) { uint bSuccess = default( uint ); - System.Text.StringBuilder pchFolder_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchFolder_sb = Helpers.TakeStringBuilder(); uint cchFolderBufferSize = 4096; bSuccess = platform.ISteamApps_GetAppInstallDir( appID.Value, pchFolder_sb, cchFolderBufferSize ); if ( bSuccess <= 0 ) return null; @@ -142,7 +142,7 @@ public string GetAvailableGameLanguages() public string GetCurrentBetaName() { bool bSuccess = default( bool ); - System.Text.StringBuilder pchName_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder(); int cchNameBufferSize = 4096; bSuccess = platform.ISteamApps_GetCurrentBetaName( pchName_sb, cchNameBufferSize ); if ( !bSuccess ) return null; diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.SteamInventory.cs b/Facepunch.Steamworks/SteamNative/SteamNative.SteamInventory.cs index 70689e4..e3d4c1e 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.SteamInventory.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.SteamInventory.cs @@ -121,7 +121,7 @@ public bool GetItemDefinitionProperty( SteamItemDef_t iDefinition /*SteamItemDef { bool bSuccess = default( bool ); pchValueBuffer = string.Empty; - System.Text.StringBuilder pchValueBuffer_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchValueBuffer_sb = Helpers.TakeStringBuilder(); uint punValueBufferSizeOut = 4096; bSuccess = platform.ISteamInventory_GetItemDefinitionProperty( iDefinition.Value, pchPropertyName, pchValueBuffer_sb, out punValueBufferSizeOut ); if ( !bSuccess ) return bSuccess; diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.SteamMatchmaking.cs b/Facepunch.Steamworks/SteamNative/SteamNative.SteamMatchmaking.cs index e5eed64..15c68eb 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.SteamMatchmaking.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.SteamMatchmaking.cs @@ -147,10 +147,10 @@ public bool GetLobbyDataByIndex( CSteamID steamIDLobby /*class CSteamID*/, int i { bool bSuccess = default( bool ); pchKey = string.Empty; - System.Text.StringBuilder pchKey_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchKey_sb = Helpers.TakeStringBuilder(); int cchKeyBufferSize = 4096; pchValue = string.Empty; - System.Text.StringBuilder pchValue_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchValue_sb = Helpers.TakeStringBuilder(); int cchValueBufferSize = 4096; bSuccess = platform.ISteamMatchmaking_GetLobbyDataByIndex( steamIDLobby.Value, iLobbyData, pchKey_sb, cchKeyBufferSize, pchValue_sb, cchValueBufferSize ); if ( !bSuccess ) return bSuccess; diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.SteamRemoteStorage.cs b/Facepunch.Steamworks/SteamNative/SteamNative.SteamRemoteStorage.cs index 31026b4..79b685e 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.SteamRemoteStorage.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.SteamRemoteStorage.cs @@ -355,7 +355,7 @@ public bool GetUGCDetails( UGCHandle_t hContent /*UGCHandle_t*/, ref AppId_t pnA { bool bSuccess = default( bool ); ppchName = string.Empty; - System.Text.StringBuilder ppchName_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder ppchName_sb = Helpers.TakeStringBuilder(); int pnFileSizeInBytes = 4096; bSuccess = platform.ISteamRemoteStorage_GetUGCDetails( hContent.Value, ref pnAppID.Value, ppchName_sb, (IntPtr) pnFileSizeInBytes, out pSteamIDOwner.Value ); if ( !bSuccess ) return bSuccess; diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.SteamUGC.cs b/Facepunch.Steamworks/SteamNative/SteamNative.SteamUGC.cs index 22b1f5d..3c5be07 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.SteamUGC.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.SteamUGC.cs @@ -147,7 +147,7 @@ public bool GetItemInstallInfo( PublishedFileId_t nPublishedFileID /*PublishedFi { bool bSuccess = default( bool ); pchFolder = string.Empty; - System.Text.StringBuilder pchFolder_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchFolder_sb = Helpers.TakeStringBuilder(); uint cchFolderSize = 4096; bSuccess = platform.ISteamUGC_GetItemInstallInfo( nPublishedFileID.Value, out punSizeOnDisk, pchFolder_sb, cchFolderSize, out punTimeStamp ); if ( !bSuccess ) return bSuccess; @@ -180,10 +180,10 @@ public bool GetQueryUGCAdditionalPreview( UGCQueryHandle_t handle /*UGCQueryHand { bool bSuccess = default( bool ); pchURLOrVideoID = string.Empty; - System.Text.StringBuilder pchURLOrVideoID_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchURLOrVideoID_sb = Helpers.TakeStringBuilder(); uint cchURLSize = 4096; pchOriginalFileName = string.Empty; - System.Text.StringBuilder pchOriginalFileName_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchOriginalFileName_sb = Helpers.TakeStringBuilder(); uint cchOriginalFileNameSize = 4096; bSuccess = platform.ISteamUGC_GetQueryUGCAdditionalPreview( handle.Value, index, previewIndex, pchURLOrVideoID_sb, cchURLSize, pchOriginalFileName_sb, cchOriginalFileNameSize, out pPreviewType ); if ( !bSuccess ) return bSuccess; @@ -206,10 +206,10 @@ public bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle /*UGCQueryHandle_t*/ { bool bSuccess = default( bool ); pchKey = string.Empty; - System.Text.StringBuilder pchKey_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchKey_sb = Helpers.TakeStringBuilder(); uint cchKeySize = 4096; pchValue = string.Empty; - System.Text.StringBuilder pchValue_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchValue_sb = Helpers.TakeStringBuilder(); uint cchValueSize = 4096; bSuccess = platform.ISteamUGC_GetQueryUGCKeyValueTag( handle.Value, index, keyValueTagIndex, pchKey_sb, cchKeySize, pchValue_sb, cchValueSize ); if ( !bSuccess ) return bSuccess; @@ -225,7 +225,7 @@ public bool GetQueryUGCMetadata( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, u { bool bSuccess = default( bool ); pchMetadata = string.Empty; - System.Text.StringBuilder pchMetadata_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchMetadata_sb = Helpers.TakeStringBuilder(); uint cchMetadatasize = 4096; bSuccess = platform.ISteamUGC_GetQueryUGCMetadata( handle.Value, index, pchMetadata_sb, cchMetadatasize ); if ( !bSuccess ) return bSuccess; @@ -251,7 +251,7 @@ public bool GetQueryUGCPreviewURL( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, { bool bSuccess = default( bool ); pchURL = string.Empty; - System.Text.StringBuilder pchURL_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchURL_sb = Helpers.TakeStringBuilder(); uint cchURLSize = 4096; bSuccess = platform.ISteamUGC_GetQueryUGCPreviewURL( handle.Value, index, pchURL_sb, cchURLSize ); if ( !bSuccess ) return bSuccess; diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.SteamUser.cs b/Facepunch.Steamworks/SteamNative/SteamNative.SteamUser.cs index f600288..fa8f5c2 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.SteamUser.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.SteamUser.cs @@ -155,7 +155,7 @@ public ulong GetSteamID() public string GetUserDataFolder() { bool bSuccess = default( bool ); - System.Text.StringBuilder pchBuffer_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchBuffer_sb = Helpers.TakeStringBuilder(); int cubBuffer = 4096; bSuccess = platform.ISteamUser_GetUserDataFolder( pchBuffer_sb, cubBuffer ); if ( !bSuccess ) return null; diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.SteamUserStats.cs b/Facepunch.Steamworks/SteamNative/SteamNative.SteamUserStats.cs index 01409b9..1f21c16 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.SteamUserStats.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.SteamUserStats.cs @@ -208,7 +208,7 @@ public int GetMostAchievedAchievementInfo( out string pchName /*char **/, out fl { int bSuccess = default( int ); pchName = string.Empty; - System.Text.StringBuilder pchName_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder(); uint unNameBufLen = 4096; bSuccess = platform.ISteamUserStats_GetMostAchievedAchievementInfo( pchName_sb, unNameBufLen, out pflPercent, ref pbAchieved ); if ( bSuccess <= 0 ) return bSuccess; @@ -222,7 +222,7 @@ public int GetNextMostAchievedAchievementInfo( int iIteratorPrevious /*int*/, ou { int bSuccess = default( int ); pchName = string.Empty; - System.Text.StringBuilder pchName_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder(); uint unNameBufLen = 4096; bSuccess = platform.ISteamUserStats_GetNextMostAchievedAchievementInfo( iIteratorPrevious, pchName_sb, unNameBufLen, out pflPercent, ref pbAchieved ); if ( bSuccess <= 0 ) return bSuccess; diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.SteamUtils.cs b/Facepunch.Steamworks/SteamNative/SteamNative.SteamUtils.cs index 851d000..c066150 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.SteamUtils.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.SteamUtils.cs @@ -100,7 +100,7 @@ public byte GetCurrentBatteryPower() public string GetEnteredGamepadTextInput() { bool bSuccess = default( bool ); - System.Text.StringBuilder pchText_sb = new System.Text.StringBuilder( 4096 ); + System.Text.StringBuilder pchText_sb = Helpers.TakeStringBuilder(); uint cchText = 4096; bSuccess = platform.ISteamUtils_GetEnteredGamepadTextInput( pchText_sb, cchText ); if ( !bSuccess ) return null; diff --git a/Generator/CodeWriter/Class.cs b/Generator/CodeWriter/Class.cs index 42abd81..84451a7 100644 --- a/Generator/CodeWriter/Class.cs +++ b/Generator/CodeWriter/Class.cs @@ -340,7 +340,7 @@ private void Detect_StringFetch( List argList, List callargs if ( !ReturnString ) BeforeLines.Add( $"{chr.Name} = string.Empty;" ); - BeforeLines.Add( $"System.Text.StringBuilder {chr.Name}_sb = new System.Text.StringBuilder( 4096 );" ); + BeforeLines.Add( $"System.Text.StringBuilder {chr.Name}_sb = Helpers.TakeStringBuilder();" ); if ( ReturnString ) ReturnType = "string"; ReturnVar = "bSuccess";