Пример #1
0
        public bool Parse(XElement top, out VkCommandInfo info)
        {
            var protoElem = top.Element("proto");

            if (protoElem != null)
            {
                var result = new VkCommandInfo();
                result.Name          = protoElem.Element("name").Value;
                result.CppReturnType = protoElem.Element("type").Value;
                result.CsReturnType  = mInspector.GetTypeCsName(result.CppReturnType, "type");

                ParseNativeInterface(top, result);

                ParseMethodSignature(top, result);

                ParseFunctionCalls(top, result);

                info = result;
                return(true);
            }
            else
            {
                info = null;
                return(false);
            }
        }
Пример #2
0
        //static void WriteVkInterface(StreamWriter interfaceFile, VkCommandInfo command)
        //{


        //	interfaceFile.WriteLine(tabbedField + "public class {0} : {1}", command.Name, command.InterfaceName);
        //	interfaceFile.WriteLine(tabbedField + "{");
        //	foreach (var method in command.Methods)
        //	{
        //		var methodTabs = tabbedField + "\t";
        //		interfaceFile.WriteLine(methodTabs + method.GetImplementation());
        //		interfaceFile.WriteLine(methodTabs + "{");
        //		interfaceFile.WriteLine(methodTabs + "}");
        //	}
        //	interfaceFile.WriteLine(tabbedField + "}");
        //	interfaceFile.WriteLine("}");
        //}

        static void VkMethod(StreamWriter methodFile, VkCommandInfo command)
        {
            methodFile.WriteLine(command.MethodSignature.GetImplementation());
            methodFile.WriteLine("{");
            foreach (var line in command.Lines)
            {
                methodFile.WriteLine(line.GetImplementation());
            }
            methodFile.WriteLine("}");
        }
Пример #3
0
        void ParseMethodSignature(XElement top, VkCommandInfo result)
        {
            var signature = new VkMethodSignature();

            signature.Name       = (result.Name.StartsWith("vk", StringComparison.InvariantCulture)) ? result.Name.Substring(2) : result.Name;
            signature.ReturnType = result.CsReturnType;

            var arguments = new Dictionary <string, VkFunctionArgument> ();

            foreach (var arg in result.NativeFunction.Arguments)
            {
                arguments.Add(arg.Name, arg);
            }

            // FILTER OUT VALUES FOR SIGNATURE
            foreach (var arg in result.NativeFunction.Arguments)
            {
                // object reference
                if (Handles.ContainsKey(arg.BaseCsType) && !arg.IsPointer)
                {
                    if (arg.Index == 0)
                    {
                        result.FirstInstance = arg;
                    }

                    arguments.Remove(arg.Name);
                }

                VkFunctionArgument localLength;
                if (arg.LengthVariable != null && arguments.TryGetValue(arg.LengthVariable, out localLength))
                {
                    result.LocalVariables.Add(localLength);
                    arguments.Remove(arg.LengthVariable);
                }
            }

            signature.Parameters = (from arg in arguments.Values
                                    orderby arg.Index ascending
                                    select new VkMethodParameter {
                Name = arg.Name, Source = arg
            }).ToList();

            foreach (var param in signature.Parameters)
            {
                param.CsType           = param.Source.BaseCsType;
                param.UseOut           = param.Source.UseOut;
                param.IsFixedArray     = param.Source.IsFixedArray;
                param.IsArrayParameter = !param.Source.IsConst && param.Source.LengthVariable != null;
                param.IsNullableType   = param.Source.IsPointer && param.Source.IsOptional;
                param.UseRef           = param.Source.UseOut && blittableTypes.Contains(param.CsType);
            }

            result.MethodSignature = signature;
        }
Пример #4
0
        public VkCommandInfo Parse(XElement top)
        {
            var result    = new VkCommandInfo();
            var protoElem = top.Element("proto");

            result.Name          = protoElem.Element("name").Value;
            result.CppReturnType = protoElem.Element("type").Value;
            result.CsReturnType  = GetTypeCsName(result.CppReturnType);

            ParseNativeInterface(top, result);

            ParseMethodSignature(top, result);

            ParseFunctionCalls(top, result);

            return(result);
        }
Пример #5
0
        void ParseNativeInterface(XElement top, VkCommandInfo result)
        {
            var function = new VkNativeInterface();

            function.Name       = result.Name;
            function.ReturnType = result.CsReturnType;

            int index = 0;

            foreach (var param in top.Elements("param"))
            {
                var arg = new VkFunctionArgument {
                    Index = index
                };
                var tokens = param.Value.Split(new[] {
                    ' ',
                    '[',
                    ']'
                }, StringSplitOptions.RemoveEmptyEntries);
                arg.IsFixedArray = false;
                if (tokens.Length == 2)
                {
                    // usually instance
                    arg.ArgumentCppType = tokens [0];
                    arg.IsConst         = false;
                    // or int
                }
                else if (tokens.Length == 3)
                {
                    // possible const pointer
                    arg.IsConst         = (tokens [0] == "const");
                    arg.ArgumentCppType = tokens [1];
                }
                else if (tokens.Length == 4)
                {
                    // const float array
                    arg.IsConst         = (tokens [0] == "const");
                    arg.ArgumentCppType = tokens [1];
                    arg.ArrayConstant   = tokens [3];
                    arg.IsFixedArray    = true;
                }
                arg.IsPointer = arg.ArgumentCppType.IndexOf('*') >= 0;

                arg.Name        = param.Element("name").Value;
                arg.BaseCppType = param.Element("type").Value;
                arg.BaseCsType  = GetTypeCsName(arg.BaseCppType);
                XAttribute optionalAttr = param.Attribute("optional");
                arg.IsOptional = optionalAttr != null && optionalAttr.Value == "true";
                XAttribute lengthAttr = param.Attribute("len");
                if (lengthAttr != null)
                {
                    var lengths = lengthAttr.Value.Split(',').Where(s => s != "null-terminated").ToArray();
                    if (lengths.Length != 1)
                    {
                        throw new NotImplementedException(string.Format("param.len != 1 ({0} found)", lengths.Length));
                    }
                    arg.LengthVariable = lengths [0];
                }
                function.Arguments.Add(arg);

                // DETERMINE CSHARP TYPE
                if (arg.ArgumentCppType == "char*")
                {
                    arg.ArgumentCsType = "string";
                }
                else if (arg.ArgumentCppType == "void*")
                {
                    arg.ArgumentCsType = "IntPtr";
                }
                else
                {
                    HandleInfo found;
                    if (Handles.TryGetValue(arg.BaseCsType, out found))
                    {
                        arg.ArgumentCsType = (found.type == "VK_DEFINE_HANDLE") ? "IntPtr" : "UInt64";
                    }
                    else
                    {
                        arg.ArgumentCsType = arg.BaseCsType;
                    }
                }

                arg.UseOut = !arg.IsConst && arg.IsPointer;

                ++index;
            }
            result.NativeFunction = function;
        }
Пример #6
0
        void ParseFunctionCalls(XElement top, VkCommandInfo result)
        {
            //throw new NotImplementedException ();

            int noOfOuts      = 0;
            int noOfArguments = result.NativeFunction.Arguments.Count;

            for (int i = 0; i < noOfArguments; ++i)
            {
                var arg = result.NativeFunction.Arguments [i];
                if (arg.UseOut)
                {
                    ++noOfOuts;
                }
            }

            if (result.LocalVariables.Count > 0)
            {
                foreach (var local in result.LocalVariables)
                {
                    var letVar = new VkVariableDeclaration {
                        Source = local
                    };
                    result.Lines.Add(letVar);
                }

                var fetch = new VkFunctionCall {
                    Call = result.NativeFunction
                };
                result.Calls.Add(fetch);
                // method call
                result.Lines.Add(fetch);

                if (result.NativeFunction.ReturnType != "void")
                {
                    var errorCheck = new VkConditionalCheck {
                        ReturnType = result.NativeFunction.ReturnType
                    };
                    result.Lines.Add(errorCheck);
                }

                foreach (var arg in result.NativeFunction.Arguments)
                {
                    var item = new VkCallArgument {
                        Source = arg
                    };
                    item.IsNull = (arg.UseOut && arg.LengthVariable != null);
                    fetch.Arguments.Add(item);
                }
            }

            foreach (var param in result.MethodSignature.Parameters)
            {
                if (param.UseOut)
                {
                    var letVar = new VkVariableDeclaration {
                        Source = param.Source
                    };
                    result.Lines.Add(letVar);
                }
            }

            var body = new VkFunctionCall {
                Call = result.NativeFunction
            };

            result.Calls.Add(body);
            foreach (var arg in result.NativeFunction.Arguments)
            {
                var item = new VkCallArgument {
                    Source = arg
                };
                item.IsNull = (arg.UseOut && arg.LengthVariable != null);
                body.Arguments.Add(item);
            }

            result.Lines.Add(body);
        }
Пример #7
0
        void ParseNativeInterface(XElement top, VkCommandInfo result)
        {
            var function = new VkNativeInterface();

            function.Name       = result.Name;
            function.ReturnType = result.CsReturnType;

            int index = 0;

            foreach (var param in top.Elements("param"))
            {
                var arg = new VkFunctionArgument {
                    Index = index
                };
                var tokens = param.Value.Split(new[] {
                    ' ',
                    '[',
                    ']'
                }, StringSplitOptions.RemoveEmptyEntries);
                arg.IsFixedArray = false;
                if (tokens.Length == 2)
                {
                    // usually instance
                    arg.ArgumentCppType = tokens [0];
                    arg.IsConst         = false;
                    // or int
                }
                else if (tokens.Length == 3)
                {
                    // possible const pointer
                    arg.IsConst         = (tokens [0] == "const");
                    arg.ArgumentCppType = tokens [1];
                }
                else if (tokens.Length == 4)
                {
                    // const float array
                    arg.IsConst         = (tokens [0] == "const");
                    arg.ArgumentCppType = tokens [1];
                    arg.ArrayConstant   = tokens [3];
                    arg.IsFixedArray    = true;
                }
                arg.IsPointer = arg.ArgumentCppType.IndexOf('*') >= 0;

                arg.Name = param.Element("name").Value;

                arg.BaseCppType = param.Element("type").Value;
                arg.BaseCsType  = mInspector.GetTypeCsName(arg.BaseCppType, "type");

                XAttribute optionalAttr = param.Attribute("optional");
                arg.IsOptional  = optionalAttr != null && optionalAttr.Value == "true";
                arg.ByReference = optionalAttr != null && optionalAttr.Value == "false,true";

                VkStructInfo structFound;
                arg.IsStruct = mInspector.Structs.TryGetValue(arg.BaseCsType, out structFound);

                XAttribute lengthAttr = param.Attribute("len");
                if (lengthAttr != null)
                {
                    var lengths = lengthAttr.Value.Split(',').Where(s => s != "null-terminated").ToArray();
                    if (lengths.Length != 1)
                    {
                        //throw new NotImplementedException(string.Format("param.len != 1 ({0} found)", lengths.Length));
                        arg.LengthVariable = null;
                    }
                    else
                    {
                        arg.LengthVariable = lengths[0];
                    }
                }
                function.Arguments.Add(arg);

                arg.IsNullableIntPtr = arg.IsOptional && arg.IsPointer && !arg.IsFixedArray && arg.LengthVariable == null;

                // DETERMINE CSHARP TYPE
                if (arg.ArgumentCppType == "char*")
                {
                    arg.ArgumentCsType = "string";
                }
                else if (arg.ArgumentCppType == "void*")
                {
                    arg.ArgumentCsType = "IntPtr";
                }
                else if (arg.ArgumentCppType == "void**")
                {
                    arg.ArgumentCsType = "IntPtr";
                }
                else
                {
                    VkHandleInfo found;
                    if (mInspector.Handles.TryGetValue(arg.BaseCsType, out found))
                    {
                        arg.ArgumentCsType = found.csType;
                    }
                    else if (arg.IsNullableIntPtr)
                    {
                        // REQUIRES MARSHALLING FOR NULLS IN ALLOCATOR
                        arg.ArgumentCsType = "IntPtr";
                    }
                    else
                    {
                        arg.ArgumentCsType = arg.BaseCsType;
                    }
                }

                if (structFound != null && structFound.returnedonly)
                {
                    arg.UseOut = false;
                }
                else
                {
                    arg.UseOut = !arg.IsConst && arg.IsPointer;
                }

                arg.IsBlittable = mInspector.BlittableTypes.Contains(arg.ArgumentCsType);

                ++index;
            }

            // USE POINTER / unsafe ONLY IF
            // ALL ARGUMENTS ARE BLITTABLE
            // && >= 1 ARGUMENTS
            // && >= 1 BLITTABLE STRUCT && NOT OPTIONAL POINTER

            bool useUnsafe            = function.Arguments.Count > 0;
            uint noOfBlittableStructs = 0;

            foreach (var arg in function.Arguments)
            {
                if (!arg.IsBlittable)
                {
                    useUnsafe = false;
                }

                if (arg.IsStruct && arg.IsBlittable && !arg.IsNullableIntPtr)
                {
                    noOfBlittableStructs++;
                }
            }
            function.UseUnsafe = useUnsafe && noOfBlittableStructs > 0;

            // Add [In, Out] attribute to struct array variables
            if (!function.UseUnsafe)
            {
                foreach (var arg in function.Arguments)
                {
                    if (arg.LengthVariable != null && arg.IsStruct && !arg.IsBlittable)
                    {
                        // SINGULAR MARSHALLED STRUCT ARRAY INSTANCES
                        arg.Attribute = "[In, Out]";
                    }
                    else if (arg.IsFixedArray && !arg.IsStruct && arg.IsBlittable)
                    {
                        // PRETTY MUCH FOR BLENDCONSTANTS
                        arg.Attribute = string.Format("[MarshalAs(UnmanagedType.LPArray, SizeConst = {0})]", arg.ArrayConstant);
                    }
                    else if (arg.IsStruct && !arg.IsBlittable && !arg.IsNullableIntPtr)
                    {
                        // SINGULAR MARSHALLED STRUCT INSTANCES
                        arg.Attribute = "[In, Out]";
                    }
                    //else
                    //{
                    //	// Add attribute
                    //	VkStructInfo readOnlyStruct;
                    //	if (!arg.IsOptional && mInspector.Structs.TryGetValue(arg.BaseCsType, out readOnlyStruct) && readOnlyStruct.returnedonly)
                    //		arg.Attribute = "[In, Out]";
                    //}
                }
            }

            result.NativeFunction = function;
        }