示例#1
0
        private DotNetFunctionData ChangeFunctionParamsToRefOrOut(DotNetFunctionData function, IEnumerable<string> @params)
        {
            var copy = function.Clone();
            copy.IsNative = false;

            //if (function.OriginalName == "glShaderBinary")
            //	Console.WriteLine("Stop");

            foreach (var param in copy.Params.Where(x => @params.Contains(x.OriginalName)))
            {
                param.DotNetType = param.DotNetType.Replace("[]", "");

                if (param.IsOutput)
                {
                    param.ShouldUseOut = true;
                }
                else
                {
                    param.ShouldUseRef = true;
                }

                param.ShouldUseAddressOfOperator = true;
            }

            return copy;
        }
示例#2
0
        private DotNetFunctionData ChangeFunctionParamsToEnums(DotNetFunctionData function, IEnumerable<XmlCommandParamData> @params)
        {
            var copy = function.Clone();
            copy.IsNative = false;

            foreach (var param in @params)
            {
                var dotNetParam = copy.Params.Single(x => x.OriginalName == param.Name);

                dotNetParam.DotNetType = param.TypeGroup;
                dotNetParam.IsEnum = true;
            }

            return copy;
        }
示例#3
0
        private DotNetFunctionData ChangeFunctionParamsToIntPtr(DotNetFunctionData function, IEnumerable<string> @params)
        {
            var copy = function.Clone();
            copy.IsNative = false;

            foreach (var param in copy.Params.Where(x => @params.Contains(x.OriginalName)))
            {
                param.DotNetType = "IntPtr";
                param.ShouldUseGenerics = false;
                param.ShouldUseFixed = false;
            }

            if (!copy.Params.Any(x => x.IsPointer))
                copy.IsUnsafe = false;

            if (!copy.Params.Any(x => x.ShouldUseGenerics))
                copy.ShouldUseGenerics = false;

            return copy;
        }
示例#4
0
        private void TranslateFunctions(XmlSpecData spec, DotNetApiData api, Options options)
        {
            foreach (var specCommand in spec.Commands.Where(x => options.CommandFilter(x)))
            {
                var specFeature = spec.Features.Where(x => x.Commands.Contains(specCommand.Name)).FirstOrDefault();

                var functionData = new DotNetFunctionData()
                {
                    IsNative = true,
                    OriginalName = specCommand.Name,
                    NativeName = this.InflectFunctionNativeName(specCommand.Name, options),
                    DotNetName = this.InflectFunctionDotNetName(specCommand.Name, options),
                    OriginalReturnType = specCommand.ReturnType,
                    NativeReturnType = this.InflectNativeReturnType(specCommand),
                    DotNetReturnType = this.InflectDotNetReturnType(specCommand)
                };

                if (specFeature != null)
                {
                    functionData.VersionMajor = specFeature.VersionMajor;
                    functionData.VersionMinor = specFeature.VersionMinor;
                    functionData.CanPInvoke = specFeature.VersionMajor == 1 && specFeature.VersionMinor <= 1;
                }

                if (functionData.NativeReturnType == "string")
                    functionData.IsUnsafe = true;

                foreach (var specCommandParam in specCommand.Params)
                {
                    var functionParamData = new DotNetFunctionParamData()
                    {
                        OriginalName = specCommandParam.Name,
                        Name = this.InflectFunctionParamName(specCommandParam.Name),
                        OriginalType = specCommandParam.Type,
                        NativeType = this.InflectFunctionParamNativeType(specCommandParam),
                        DotNetType = this.InflectFunctionParamDotNetType(specCommandParam),
                        IsPointer = this.IsTypePointer(specCommandParam.Type),
                        IsOutput = this.IsTypeOutput(specCommandParam.Type),
                        ShouldUseGenerics = this.ShouldUseGenericsForType(specCommandParam.Type),
                        ShouldUseFixed = this.ShouldUseFixedForParam(specCommandParam),
                        ShouldUseAddressOfOperator = this.ShouldUseAddressOfOperatorForParam(specCommandParam)
                    };

                    if (functionParamData.IsPointer)
                        functionData.IsUnsafe = true;

                    if (functionParamData.ShouldUseGenerics)
                        functionData.ShouldUseGenerics = true;

                    if (functionParamData.IsOutput && functionParamData.DotNetType == "IntPtr")
                    {
                        functionParamData.ShouldUseOut = true;
                    }

                    functionData.Params.Add(functionParamData);
                }

                api.Functions.Add(functionData);

                // Create overload which accepts the Enum variant.
                if (specCommand.Params.Any(x => this.IsTypeEnum(x, api)))
                {
                    api.Functions.Add(this.ChangeFunctionParamsToEnums(functionData, specCommand.Params.Where(x => this.IsTypeEnum(x, api))));
                }
            }

            foreach (var functionData in api.Functions.ToArray())
            {
                var specCommand = spec.Commands.Single(x => x.Name == functionData.OriginalName);

                // Commands which take a pointer and it could be a single element.
                if (specCommand.Params.Any(x => this.ShouldChangeFunctionParamToRefOrOut(x)))
                {
                    api.Functions.Add(this.ChangeFunctionParamsToRefOrOut(functionData, specCommand.Params.Where(x => this.ShouldChangeFunctionParamToRefOrOut(x)).Select(x => x.Name)));
                }

                // Commands which take a pointer and it could be a single element.
                if (specCommand.Params.Any(x => this.ShouldChangeFunctionParamToIntPtr(x)))
                {
                    api.Functions.Add(this.ChangeFunctionParamsToIntPtr(functionData, specCommand.Params.Where(x => this.ShouldChangeFunctionParamToIntPtr(x)).Select(x => x.Name)));
                }
            }

            api.Functions.Sort((x, y) => x.OriginalName != null && y.OriginalName != null ? x.OriginalName.CompareTo(y.OriginalName) : 0);
        }
示例#5
0
        private string GetSignature(string prefix, DotNetFunctionData function, bool useDotNetStyle)
        {
            string signature = prefix;

            string returnType = function.NativeReturnType;

            if (returnType == "GLenum" || returnType == "GLbitfield")
                returnType = "uint";

            string functionName = (useDotNetStyle ? function.DotNetName : function.NativeName);

            signature += returnType + " " + functionName;

            if (useDotNetStyle && function.ShouldUseGenerics)
                signature += "<T>";

            signature += "(";

            int i = 0;
            foreach (var param in function.Params)
            {
                if (!useDotNetStyle)
                {
                    if (param.IsOutput)
                        signature += "[Out] ";
                }
                else
                {
                    if (param.ShouldUseRef)
                    {
                        signature += "ref ";
                    }
                    else if (param.ShouldUseOut)
                    {
                        signature += "out ";
                    }
                }

                signature += (useDotNetStyle ? param.DotNetType : param.NativeType) + " " + param.Name;

                if (i < function.Params.Count - 1)
                    signature += ", ";

                i++;
            }

            signature += ")";

            if (useDotNetStyle && function.ShouldUseGenerics)
                signature += " where T : struct";

            return signature;
        }
示例#6
0
        private string GetNativeDeclaration(string padding, DotNetFunctionData function, bool asPublic)
        {
            string header = padding + "[System.Runtime.InteropServices.DllImport(Library, EntryPoint=\"" + function.OriginalName + "\", ExactSpelling=true)]" + Environment.NewLine;

            string prefix = string.Empty;

            if (asPublic)
                prefix = "public ";
            else
                prefix = "internal ";

            prefix += "static extern ";

            if (function.IsUnsafe)
                prefix += "unsafe ";

            string signature = this.GetSignature(padding + prefix, function, false) + ";";

            return header + signature;
        }
示例#7
0
        private string GetMethodCallParamsList(DotNetFunctionData function)
        {
            string output = string.Empty;

            if (function.Params.Count > 0)
            {
                for (int i = 0; i < function.Params.Count; i++)
                {
                    var param = function.Params[i];

                    if (param.ShouldUseGenerics)
                    {
                        output += "(IntPtr)";
                    }
                    else if (param.IsEnum)
                    {
                        output += "(uint)";
                    }

                    output += param.Name;

                    if (param.ShouldUseFixed || param.ShouldUseGenerics)
                    {
                        output += "Ptr";
                    }

                    if (param.ShouldUseGenerics)
                    {
                        output += ".AddrOfPinnedObject()";
                    }

                    if (i != function.Params.Count - 1)
                        output += ", ";
                }
            }

            return output;
        }
示例#8
0
        private string GetDotNetDeclaration(string padding, DotNetFunctionData function, Options options)
        {
            string output = padding + "/// " + function.OriginalName + Environment.NewLine;
            output += padding + "/// Version: " + function.VersionMajor + "." + function.VersionMinor + Environment.NewLine;

            output += padding + GetSignature("public ", function, true);

            output += Environment.NewLine + padding + "{" + Environment.NewLine;

            string bodyPadding = padding + "\t";

            if (function.NativeReturnType != "void")
                output += bodyPadding + function.NativeReturnType + " result;" + Environment.NewLine + Environment.NewLine;

            if (function.Params.Any(x => x.ShouldUseOut && !x.ShouldUseFixed))
            {
                foreach (var param in function.Params.Where(x => x.ShouldUseOut && !x.ShouldUseFixed))
                {
                    output += bodyPadding + param.Name + " = default(" + param.DotNetType + ");" + Environment.NewLine;
                }

                output += Environment.NewLine;
            }

            bool wrapInTryFinally = function.ShouldUseGenerics;

            if (function.IsUnsafe)
            {
                output += bodyPadding + "unsafe" + Environment.NewLine;
                output += bodyPadding + "{" + Environment.NewLine;
                bodyPadding += "\t";

                if (function.IsAtLeastOneParamNonVoidPointer)
                {
                    foreach (var param in function.Params)
                    {
                        if (param.ShouldUseFixed)
                        {
                            output += bodyPadding + "fixed (" + param.NativeType + " " + param.Name + "Ptr = ";

                            if (param.ShouldUseAddressOfOperator)
                                output += "&";

                            output += param.Name + ")" + Environment.NewLine;
                        }
                    }

                    output += bodyPadding + "{" + Environment.NewLine;
                    bodyPadding += "\t";
                }
            }

            if (wrapInTryFinally)
            {
                foreach (var param in function.Params)
                {
                    if (param.ShouldUseGenerics)
                        output += bodyPadding + "GCHandle " + param.Name + "Ptr = GCHandle.Alloc(" + param.Name + ", GCHandleType.Pinned);" + Environment.NewLine;
                }

                output += bodyPadding + "try" + Environment.NewLine;
                output += bodyPadding + "{" + Environment.NewLine;
                bodyPadding += "\t";
            }

            output += bodyPadding;

            if (function.NativeReturnType != "void")
                output += "result = ";

            if (function.NativeReturnType == "string")
                output += "new string ((sbyte*)";

            if (function.CanPInvoke)
                output += options.FunctionsClassName + "." + function.NativeName + "(" + this.GetMethodCallParamsList(function);
            else
                output += "this._" + function.NativeName + "(" + this.GetMethodCallParamsList(function);

            if (function.NativeReturnType == "string")
                output += ")";

            output += ");" + Environment.NewLine;

            if (wrapInTryFinally)
            {
                bodyPadding = bodyPadding.Substring(0, bodyPadding.Length - 1);
                output += bodyPadding + "}" + Environment.NewLine;
                output += bodyPadding + "finally" + Environment.NewLine;
                output += bodyPadding + "{" + Environment.NewLine;

                if (function.ShouldUseGenerics)
                {
                    foreach (var param in function.Params)
                    {
                        if (param.ShouldUseGenerics)
                            output += bodyPadding + "\t" + param.Name + "Ptr.Free();" + Environment.NewLine;
                    }
                }

                output += bodyPadding + "}" + Environment.NewLine;
            }

            if (function.IsUnsafe)
            {
                if (function.IsAtLeastOneParamNonVoidPointer)
                {
                    bodyPadding = bodyPadding.Substring(0, bodyPadding.Length - 1);
                    output += bodyPadding + "}" + Environment.NewLine;
                }

                bodyPadding = bodyPadding.Substring(0, bodyPadding.Length - 1);
                output += bodyPadding + "}" + Environment.NewLine;
            }

            if (function.NativeReturnType != "void")
                output += Environment.NewLine + bodyPadding + "return result;" + Environment.NewLine;

            output += padding + "}";

            return output;
        }
示例#9
0
        private string GetDelegateDeclaration(string padding, DotNetFunctionData function)
        {
            string prefix = "internal delegate ";

            if (function.IsUnsafe)
                prefix = "internal unsafe delegate ";

            string signature = this.GetSignature(padding + prefix, function, false) + ";";

            return signature;
        }
示例#10
0
        public DotNetFunctionData Clone()
        {
            var copy = new DotNetFunctionData()
            {
                IsNative = this.IsNative,
                OriginalName = this.OriginalName,
                NativeName = this.NativeName,
                DotNetName = this.DotNetName,
                OriginalReturnType = this.OriginalReturnType,
                NativeReturnType = this.NativeReturnType,
                DotNetReturnType = this.DotNetReturnType,
                VersionMajor = this.VersionMajor,
                VersionMinor = this.VersionMinor,
                CanPInvoke = this.CanPInvoke,
                IsUnsafe = this.IsUnsafe,
                ShouldUseGenerics = this.ShouldUseGenerics
            };

            foreach (var param in this.Params)
                copy.Params.Add(param.Clone());

            return copy;
        }