Exemple #1
0
        void Structs()
        {
            foreach (var c in def.structs)
            {
                var name = Cleanup.ConvertType(c.Name);

                if (!Cleanup.ShouldCreate(name))
                {
                    continue;
                }

                if (name.Contains("::"))
                {
                    continue;
                }

                var partial = "";
                if (c.Methods != null)
                {
                    partial = " partial";
                }

                //
                // Main struct
                //
                WriteLine($"[StructLayout( LayoutKind.Sequential, Pack = Platform.{(c.IsPack4OnWindows?"StructPackSize": "StructPlatformPackSize")} )]");
                StartBlock($"{Cleanup.Expose( name )}{partial} struct {name}");
                {
                    //
                    // The fields
                    //
                    StructFields(c.Fields);
                    WriteLine();

                    if (c.Enums != null)
                    {
                        foreach (var e in c.Enums)
                        {
                            WriteEnum(e, e.Name);
                        }
                    }
                }
                EndBlock();
                WriteLine();
            }
        }
        void Structs()
        {
            var callbackList = new List <SteamApiDefinition.StructDef>();

            foreach (var c in def.structs)
            {
                var name = Cleanup.ConvertType(c.Name);

                if (SkipStructs.Contains(c.Name))
                {
                    continue;
                }

                if (!Cleanup.ShouldCreate(name))
                {
                    continue;
                }

                if (name.Contains("::"))
                {
                    continue;
                }

                int defaultPack = c.IsPack4OnWindows ? 4 : 8;

                var isCallback = !string.IsNullOrEmpty(c.CallbackId);

                //
                // Main struct
                //
                WriteLine("[StructLayout( LayoutKind.Sequential, Pack = 4 )]");
                StartBlock($"{Cleanup.Expose( name )} struct {name}");
                {
                    //
                    // The fields
                    //
                    StructFields(c.Fields);
                    WriteLine();

                    if (isCallback)
                    {
                        WriteLine("#region SteamCallback");
                        {
                            if (defaultPack == 4)
                            {
                                WriteLine($"internal static readonly int StructSize = System.Runtime.InteropServices.Marshal.SizeOf( typeof({name}) );");
                                WriteLine($"internal static {name} Fill( IntPtr p ) => (({name})({name}) Marshal.PtrToStructure( p, typeof({name}) ) );");
                            }
                            else
                            {
                                WriteLine($"internal static readonly int StructSize = System.Runtime.InteropServices.Marshal.SizeOf( Config.PackSmall ? typeof({name}) : typeof(Pack8) );");
                                WriteLine($"internal static {name} Fill( IntPtr p ) => Config.PackSmall ? (({name})({name}) Marshal.PtrToStructure( p, typeof({name}) )) : (({name})(Pack8) Marshal.PtrToStructure( p, typeof(Pack8) ));");
                            }
                            WriteLine();
                            WriteLine($"static Action<{name}> actionClient;");
                            WriteLine($"[MonoPInvokeCallback] static void OnClient( IntPtr thisptr, IntPtr pvParam ) => actionClient?.Invoke( Fill( pvParam ) );");

                            WriteLine($"static Action<{name}> actionServer;");
                            WriteLine($"[MonoPInvokeCallback] static void OnServer( IntPtr thisptr, IntPtr pvParam ) => actionServer?.Invoke( Fill( pvParam ) );");

                            StartBlock($"public static void Install( Action<{name}> action, bool server = false )");
                            {
                                StartBlock("if ( server )");
                                {
                                    WriteLine($"Event.Register( OnServer, StructSize, {c.CallbackId}, true );");
                                    WriteLine($"actionServer = action;");
                                }
                                Else();
                                {
                                    WriteLine($"Event.Register( OnClient, StructSize, {c.CallbackId}, false );");
                                    WriteLine($"actionClient = action;");
                                }
                                EndBlock();
                            }
                            EndBlock();

                            StartBlock($"public static async Task<{name}?> GetResultAsync( SteamAPICall_t handle )");
                            {
                                WriteLine($"bool failed = false;");
                                WriteLine();
                                StartBlock($"while ( !SteamUtils.IsCallComplete( handle, out failed ) )");
                                {
                                    WriteLine($"await Task.Delay( 1 );");
                                }
                                EndBlock();

                                WriteLine($"if ( failed ) return null;");
                                WriteLine($"");
                                WriteLine($"var ptr = Marshal.AllocHGlobal( StructSize );");
                                WriteLine($"");
                                WriteLine($"try");
                                WriteLine($"{{");
                                WriteLine($"	if ( !SteamUtils.Internal.GetAPICallResult( handle, ptr, StructSize, {c.CallbackId}, ref failed ) || failed )");
                                WriteLine($"		return null;");
                                WriteLine($"");
                                WriteLine($"	return Fill( ptr );");
                                WriteLine($"}}");
                                WriteLine($"finally");
                                WriteLine($"{{");
                                WriteLine($"	Marshal.FreeHGlobal( ptr );");
                                WriteLine($"}}");
                            }
                            EndBlock();
                        }
                        WriteLine("#endregion");
                    }
                    else
                    {
                        WriteLine("#region Marshalling");
                        {
                            if (defaultPack == 4)
                            {
                                //WriteLine( $"internal static int GetStructSize() => System.Runtime.InteropServices.Marshal.SizeOf( typeof({name}) );" );
                                WriteLine($"internal static {name} Fill( IntPtr p ) => (({name})({name}) Marshal.PtrToStructure( p, typeof({name}) ) );");
                            }
                            else
                            {
                                //WriteLine( $"internal static int GetStructSize() => System.Runtime.InteropServices.Marshal.SizeOf( Config.PackSmall ? typeof({name}) : typeof(Pack8) );" );
                                WriteLine($"internal static {name} Fill( IntPtr p ) => Config.PackSmall ? (({name})({name}) Marshal.PtrToStructure( p, typeof({name}) )) : (({name})(Pack8) Marshal.PtrToStructure( p, typeof(Pack8) ));");
                            }
                        }
                        WriteLine("#endregion");
                    }

                    if (defaultPack != 4)
                    {
                        WriteLine("#region Packed Versions");
                        {
                            //
                            // Windows Packed version
                            //
                            WriteLine();
                            WriteLine($"[StructLayout( LayoutKind.Sequential, Pack = {defaultPack} )]");
                            StartBlock($"public struct Pack8");
                            {
                                StructFields(c.Fields);

                                //
                                // Implicit convert from PackSmall to regular
                                //
                                WriteLine();
                                Write($"public static implicit operator {name} ( {name}.Pack8 d ) => ");
                                {
                                    Write($"new {name}{{ ");
                                    {
                                        foreach (var f in c.Fields)
                                        {
                                            Write($"{CleanMemberName( f.Name )} = d.{CleanMemberName( f.Name )},");
                                        }
                                    }
                                    WriteLine(" };");
                                }

                                Write($"public static implicit operator {name}.Pack8 ( {name} d ) => ");
                                {
                                    Write($"new {name}.Pack8{{ ");
                                    {
                                        foreach (var f in c.Fields)
                                        {
                                            Write($"{CleanMemberName( f.Name )} = d.{CleanMemberName( f.Name )},");
                                        }
                                    }
                                    WriteLine(" };");
                                }
                            }
                            EndBlock();
                        }
                        WriteLine("#endregion");
                    }

                    if (!string.IsNullOrEmpty(c.CallbackId))
                    {
                        callbackList.Add(c);
                    }
                }
                EndBlock();
                WriteLine();
            }
        }
Exemple #3
0
        void StructFunctions()
        {
            foreach (var c in def.structs.Union(def.callback_structs.Select(x => x as SteamApiDefinition.StructDef)).OrderBy(x => x.Name))
            {
                var name = Cleanup.ConvertType(c.Name);

                if (name.Contains("::"))
                {
                    continue;
                }

                if (c.Methods == null || c.Methods.Length == 0)
                {
                    continue;
                }

                //
                // Main struct
                //
                StartBlock($"{Cleanup.Expose( name )} partial struct {name}");
                {
                    foreach (var func in c.Methods)
                    {
                        if (func.Name.Contains("operator"))
                        {
                            func.Name = func.FlatName.Substring(func.FlatName.LastIndexOf('_') + 1);
                        }

                        var returnType = BaseType.Parse(func.ReturnType, null, func.CallResult);
                        returnType.Func = func.Name;

                        var args = func.Params.Select(x =>
                        {
                            var bt  = BaseType.Parse(x.ParamType, x.ParamName);
                            bt.Func = func.Name;
                            return(bt);
                        }).ToArray();

                        for (int i = 0; i < args.Length; i++)
                        {
                            if (args[i] is FetchStringType)
                            {
                                if (args[i + 1] is IntType || args[i + 1] is UIntType || args[i + 1] is UIntPtrType)
                                {
                                    if (string.IsNullOrEmpty(args[i + 1].Ref))
                                    {
                                        args[i + 1] = new LiteralType(args[i + 1], "(1024 * 32)");
                                    }
                                }
                                else
                                {
                                    throw new System.Exception($"String Builder Next Type Is {args[i + 1].GetType()}");
                                }
                            }
                        }

                        var delegateargstr = string.Join(", ", args.Select(x => x.AsNativeArgument()));

                        if (!string.IsNullOrEmpty(func.Desc))
                        {
                            WriteLine("/// <summary>");
                            WriteLine($"/// {func.Desc}");
                            WriteLine("/// </summary>");
                        }

                        if (returnType.ReturnAttribute != null)
                        {
                            WriteLine(returnType.ReturnAttribute);
                        }

                        var _unsafe  = "";
                        var firstArg = $"ref {name} self";

                        //
                        // If this is NetMsg then the ORIGINAL pointer address is important
                        // because we need to pass in the original pointer - not just the data
                        //
                        if (name == "NetMsg")
                        {
                            firstArg = $"{name}* self";
                            _unsafe  = " unsafe";
                        }

                        WriteLine($"[DllImport( Platform.LibraryName, EntryPoint = \"{func.FlatName}\", CallingConvention = Platform.CC)]");
                        WriteLine($"internal static{_unsafe} extern {returnType.TypeNameFrom} Internal{func.Name}( {firstArg}, {delegateargstr} );".Replace($"( {firstArg},  )", $"( {firstArg} )"));
                        WriteLine();
                    }
                }
                EndBlock();
                WriteLine();
            }
        }
        private void WriteEnum(SteamApiDefinition.EnumDef o, string name, string t = "int")
        {
            StartBlock($"{Cleanup.Expose( name )} enum {name} : {t}");
            {
                //
                // If all the enum values start with the same
                // string, remove it. This converts
                // "k_EUserHasLicenseResultHasLicense" to "HasLicense" etc
                //
                int iFinished = int.MaxValue;
                for (int i = 0; i < 4096; i++)
                {
                    var c = o.Values.First().Name[i];
                    foreach (var entry in o.Values)
                    {
                        if (entry.Name[i] != c)
                        {
                            iFinished = i;
                            break;
                        }
                    }

                    if (iFinished != int.MaxValue)
                    {
                        break;
                    }
                }

                foreach (var entry in o.Values)
                {
                    var ename = entry.Name;

                    if (ename.Contains("Force32Bit"))
                    {
                        continue;
                    }

                    if (iFinished != int.MaxValue)
                    {
                        ename = ename.Substring(iFinished);
                    }

                    //
                    // Names aren't allowed to start with a number
                    // So just stick the enum name on the front
                    //
                    if (char.IsNumber(ename[0]))
                    {
                        var p = name;

                        if (p == "HTTPStatusCode")
                        {
                            p = "Code";
                        }
                        if (p == "SteamIPType")
                        {
                            p = "Type";
                        }

                        ename = p + ename;
                    }

                    WriteLine($"{ename.Trim( ' ', '_' )} = {entry.Value},");
                }
            }
            EndBlock();
            WriteLine();
        }
        private void Enums()
        {
            foreach (var o in def.enums)
            {
                WriteLine($"//");
                WriteLine($"// {o.Name}");
                WriteLine($"//");
                var name = o.Name;

                // We're not interested in namespacing
                if (name.Contains("::"))
                {
                    name = o.Name.Substring(o.Name.LastIndexOf(":") + 1);
                }

                // Skip the E
                if (name[0] == 'E')
                {
                    name = name.Substring(1);
                }

                name = Cleanup.ConvertType(name);

                if (!Cleanup.ShouldCreate(name))
                {
                    continue;
                }

                StartBlock($"{Cleanup.Expose( name )} enum {name} : int");
                {
                    //
                    // If all the enum values start with the same
                    // string, remove it. This converts
                    // "k_EUserHasLicenseResultHasLicense" to "HasLicense" etc
                    //
                    int iFinished = int.MaxValue;
                    for (int i = 0; i < 4096; i++)
                    {
                        var c = o.Values.First().Name[i];
                        foreach (var entry in o.Values)
                        {
                            if (entry.Name[i] != c)
                            {
                                iFinished = i;
                                break;
                            }
                        }

                        if (iFinished != int.MaxValue)
                        {
                            break;
                        }
                    }

                    foreach (var entry in o.Values)
                    {
                        var ename = entry.Name;

                        if (iFinished != int.MaxValue)
                        {
                            ename = ename.Substring(iFinished);
                        }

                        //
                        // Names aren't allowed to start with a number
                        // So just stick the enum name on the front
                        //
                        if (char.IsNumber(ename[0]))
                        {
                            ename = name + ename;
                        }

                        WriteLine($"{ename} = {entry.Value},");
                    }
                }
                EndBlock();
                WriteLine();
            }
        }
        void Callbacks()
        {
            var callbackList = new List <SteamApiDefinition.StructDef>();

            foreach (var c in def.callback_structs)
            {
                var name = Cleanup.ConvertType(c.Name);

                if (!Cleanup.ShouldCreate(name))
                {
                    continue;
                }

                if (name.Contains("::"))
                {
                    continue;
                }

                var partial = "";
                if (c.Methods != null)
                {
                    partial = " partial";
                }

                int defaultPack = c.IsPack4OnWindows ? 4 : 8;

                var isCallback = true;
                var iface      = "";
                if (isCallback)
                {
                    iface = " : ICallbackData";
                }

                //
                // Main struct
                //
                WriteLine($"[StructLayout( LayoutKind.Sequential, Pack = Platform.{(c.IsPack4OnWindows?"StructPackSize": "StructPlatformPackSize")} )]");
                StartBlock($"{Cleanup.Expose( name )}{partial} struct {name}{iface}");
                {
                    //
                    // The fields
                    //
                    StructFields(c.Fields);
                    WriteLine();

                    if (isCallback)
                    {
                        WriteLine("#region SteamCallback");
                        {
                            WriteLine($"public static int _datasize = System.Runtime.InteropServices.Marshal.SizeOf( typeof({name}) );");
                            WriteLine($"public int DataSize => _datasize;");
                            WriteLine($"public CallbackType CallbackType => CallbackType.{name.Replace( "_t", "" )};");
                        }
                        WriteLine("#endregion");
                    }

                    if (c.Enums != null)
                    {
                        foreach (var e in c.Enums)
                        {
                            WriteEnum(e, e.Name);
                        }
                    }

                    // if (  c.CallbackId ) )
                    {
                        callbackList.Add(c);
                    }
                }
                EndBlock();
                WriteLine();
            }
        }
        private void Types()
        {
            foreach (var o in def.typedefs.Where(x => !x.Name.Contains("::")))
            {
                if (!Cleanup.ShouldCreate(o.Name))
                {
                    continue;
                }

                var typeName = Cleanup.ConvertType(o.Name);

                if (!Cleanup.ShouldCreate(typeName))
                {
                    continue;
                }

                if (SkipTypes.Contains(o.Name))
                {
                    continue;
                }

                if (SkipTypesStartingWith.Any(x => o.Name.StartsWith(x)))
                {
                    continue;
                }

                StartBlock($"{Cleanup.Expose( typeName )} struct {typeName} : IEquatable<{typeName}>, IComparable<{typeName}>");
                {
                    WriteLine($"// Name: {o.Name}, Type: {o.Type}");

                    if (o.Type == "char [1024]")
                    {
                        WriteLine($"public fixed char[1024] Value;");
                    }
                    else
                    {
                        WriteLine($"public {ToManagedType( o.Type )} Value;");
                    }
                    WriteLine();
                    WriteLine($"public static implicit operator {typeName}( {ToManagedType( o.Type )} value ) => new {typeName}(){{ Value = value }};");
                    WriteLine($"public static implicit operator {ToManagedType( o.Type )}( {typeName} value ) => value.Value;");
                    WriteLine($"public override string ToString() => Value.ToString();");
                    WriteLine($"public override int GetHashCode() => Value.GetHashCode();");
                    WriteLine($"public override bool Equals( object p ) => this.Equals( ({typeName}) p );");
                    WriteLine($"public bool Equals( {typeName} p ) => p.Value == Value;");
                    WriteLine($"public static bool operator ==( {typeName} a, {typeName} b ) => a.Equals( b );");
                    WriteLine($"public static bool operator !=( {typeName} a, {typeName} b ) => !a.Equals( b );");

                    if (ToManagedType(o.Type) == "IntPtr")
                    {
                        WriteLine($"public int CompareTo( {typeName} other ) => Value.ToInt64().CompareTo( other.Value.ToInt64() );");
                    }
                    else
                    {
                        WriteLine($"public int CompareTo( {typeName} other ) => Value.CompareTo( other.Value );");
                    }
                }
                EndBlock();
                WriteLine();
            }
        }