using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Generator { public partial class CodeWriter { public void GenerateGlobalFunctions( string startingWith, string filename ) { var functions = def.methods.Where( x => x.Name.StartsWith( startingWith ) ); sb = new StringBuilder(); WriteLine( $"using System;" ); WriteLine( $"using System.Runtime.InteropServices;" ); WriteLine( $"using System.Text;" ); WriteLine( $"using System.Threading.Tasks;" ); WriteLine( $"using Steamworks.Data;" ); WriteLine(); WriteLine(); StartBlock( $"namespace Steamworks" ); { StartBlock( $"internal static class {startingWith}" ); { StartBlock( $"internal static class Win64" ); { foreach ( var func in functions ) { WriteMarshalledFunction( func, "steam_api64" ); } } EndBlock(); StartBlock( $"internal static class Posix" ); { foreach ( var func in functions ) { WriteMarshalledFunction( func, "libsteam_api" ); } } EndBlock(); foreach ( var func in functions ) { WriteGlobalFunction( startingWith, func ); WriteLine(); } } EndBlock(); } EndBlock(); System.IO.File.WriteAllText( $"{filename}", sb.ToString().Replace( "( )", "()" ) ); } private void WriteGlobalFunction( string cname, SteamApiDefinition.MethodDef func ) { var cleanName = func.Name.Substring( cname.Length ).Trim( '_' ); var returnType = BaseType.Parse( func.ReturnType ); returnType.Func = func.Name; if ( func.Params == null ) func.Params = new SteamApiDefinition.MethodDef.ParamType[0]; var args = func.Params.Select( x => { var bt = BaseType.Parse( x.Type, x.Name ); bt.Func = func.Name; return bt; } ).ToArray(); var argstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); var delegateargstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); if ( returnType.IsReturnedWeird ) { throw new System.Exception( "TODO" ); } StartBlock( $"static internal {returnType.ReturnType} {cleanName}( {argstr} )" ); { var callargs = string.Join( ", ", args.Select( x => x.AsCallArgument() ) ); StartBlock( "if ( Config.Os == OsType.Windows )" ); { if ( returnType.IsReturnedWeird ) { WriteLine( $"var retVal = default( {returnType.TypeName} );" ); WriteLine( $"Win64.{func.Name}( ref retVal, {callargs} );" ); WriteLine( $"{returnType.Return( "retVal" )}" ); } else if ( returnType.IsVoid ) { WriteLine( $"Win64.{func.Name}( {callargs} );" ); } else { var v = $"Win64.{func.Name}( {callargs} )"; WriteLine( returnType.Return( v ) ); } } Else( " if ( Config.Os == OsType.Posix )" ); { if ( returnType.IsReturnedWeird ) { WriteLine( $"var retVal = default( {returnType.TypeName} );" ); WriteLine( $"Posix.{func.Name}( ref retVal, {callargs} );" ); WriteLine( $"{returnType.Return( "retVal" )}" ); } else if ( returnType.IsVoid ) { WriteLine( $"Posix.{func.Name}( {callargs} );" ); } else { var v = $"Posix.{func.Name}( {callargs} )"; WriteLine( returnType.Return( v ) ); } } Else(); { WriteLine( "throw new System.Exception( \"this platform isn't supported\" );" ); } EndBlock(); } EndBlock(); } private void WriteMarshalledFunction( SteamApiDefinition.MethodDef func, string dllName ) { var returnType = BaseType.Parse( func.ReturnType ); returnType.Func = func.Name; if ( func.Params == null ) func.Params = new SteamApiDefinition.MethodDef.ParamType[0]; var args = func.Params.Select( x => { var bt = BaseType.Parse( x.Type, x.Name ); bt.Func = func.Name; return bt; } ).ToArray(); var argstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); var delegateargstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); WriteLine( $"[DllImport( \"{dllName}\", EntryPoint = \"{func.Name}\", CallingConvention = CallingConvention.Cdecl )]" ); if ( returnType.ReturnAttribute != null ) WriteLine( returnType.ReturnAttribute ); WriteLine( $"public static extern {(returnType.IsReturnedWeird ? "void" : returnType.TypeNameFrom)} {func.Name}( {delegateargstr} );" ); WriteLine(); } /* */ /* var returnType = BaseType.Parse( func.ReturnType ); returnType.Func = func.Name; var args = func.Arguments.Select( x => { var bt = BaseType.Parse( x.Value, x.Key ); bt.Func = func.Name; return bt; } ).ToArray(); var argstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); var delegateargstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); if ( returnType.IsReturnedWeird ) { delegateargstr = $"ref {returnType.TypeName} retVal, {delegateargstr}"; delegateargstr = delegateargstr.Trim( ',', ' ' ); } if ( returnType is SteamApiCallType sap ) { sap.CallResult = func.CallResult; } WriteLine( $"#region FunctionMeta" ); WriteLine( $"[UnmanagedFunctionPointer( CallingConvention.ThisCall )]" ); if ( returnType.ReturnAttribute != null) WriteLine( returnType.ReturnAttribute ); WriteLine( $"private delegate {(returnType.IsReturnedWeird?"void":returnType.TypeNameFrom)} F{func.Name}( IntPtr self, {delegateargstr} );".Replace( "( IntPtr self, )", "( IntPtr self )" ) ); WriteLine( $"private F{func.Name} _{func.Name};" ); WriteLine(); WriteLine( $"#endregion" ); StartBlock( $"internal {returnType.ReturnType} {func.Name}( {argstr} )".Replace( "( )", "()" ) ); { var callargs = string.Join( ", ", args.Select( x => x.AsCallArgument() ) ); if ( returnType.IsReturnedWeird ) { WriteLine( $"var retVal = default( {returnType.TypeName} );" ); WriteLine( $"_{func.Name}( Self, ref retVal, {callargs} );".Replace( ", );", " );" ) ); WriteLine( $"{returnType.Return( "retVal" )}" ); } else if ( returnType.IsVoid ) { WriteLine( $"_{func.Name}( Self, {callargs} );".Replace( "( Self, )", "( Self )" ) ); } else { var v = $"_{func.Name}( Self, {callargs} )".Replace( "( Self, )", "( Self )" ); WriteLine( returnType.Return( v ) ); } } EndBlock(); */ } }