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";