Example #1
0
        /// <summary>
        /// Generate the command delegate source code.
        /// </summary>
        /// <param name="sw">
        /// The <see cref="SourceStreamWriter"/> used to write the source code.
        /// </param>
        /// <param name="ctx">
        /// The <see cref="RegistryContext"/> defining the OpenGL registry information.
        /// </param>
        internal void GenerateDelegate(SourceStreamWriter sw, RegistryContext ctx)
        {
            // No sure if it is really necessary
            sw.WriteLine("[SuppressUnmanagedCodeSecurity()]");

            // Delegate type definition
            sw.WriteIdentation(); sw.Write("internal ");
            if (IsSafeImplementation == false)
            {
                sw.Write("unsafe ");
            }
            sw.Write("delegate ");

            sw.Write("{0} {1}(", DelegateReturnType, ImportName);

            int paramCount = Parameters.Count;

            foreach (CommandParameter param in Parameters)
            {
                string paramAttributes = param.GetDelegateTypeAttributes(ctx, this);
                string paramModifier   = param.GetDelegateTypeModifier(ctx, this);

                if (paramAttributes != null)
                {
                    sw.Write("{0} ", paramAttributes);
                }
                if (paramModifier != null)
                {
                    sw.Write("{0} ", paramModifier);
                }


                sw.Write("{0} {1}", param.GetDelegateType(ctx, this), param.ImportName);
                paramCount--;
                if (paramCount > 0)
                {
                    sw.Write(", ");
                }
            }
            sw.Write(");");
            sw.WriteLine();

            sw.WriteLine();
            if (Aliases.Count > 0)
            {
                sw.WriteLine("[AliasOf(\"{0}\")]", ImportName);
                foreach (Command aliasOf in Aliases)
                {
                    sw.WriteLine("[AliasOf(\"{0}\")]", aliasOf.ImportName);
                }
            }

            // Required on Windows platform: different threads can bind different OpenGL context, which can have different
            // entry points
            sw.WriteLine("[ThreadStatic]");

            // Delegate field
            sw.WriteLine("internal static {0} {1};", ImportName, DelegateName);
        }
Example #2
0
        /// <summary>
        /// Generate the command import source code.
        /// </summary>
        /// <param name="sw">
        /// The <see cref="SourceStreamWriter"/> used to write the source code.
        /// </param>
        /// <param name="ctx">
        /// The <see cref="RegistryContext"/> defining the OpenGL registry information.
        /// </param>
        internal void GenerateImport(SourceStreamWriter sw, RegistryContext ctx)
        {
            // The SuppressUnmanagedCodeSecurity attribute is used to increase P/Invoke performance
            sw.WriteLine("[SuppressUnmanagedCodeSecurity()]");
            // Import definition
            CommandFlags commandFlags = CommandFlagsDatabase.GetCommandFlags(this);

            if ((commandFlags & CommandFlags.SetLastError) != 0)
            {
                sw.WriteLine("[DllImport(Library, EntryPoint = \"{0}\", ExactSpelling = true, SetLastError = true)]", ImportName);
            }
            else
            {
                sw.WriteLine("[DllImport(Library, EntryPoint = \"{0}\", ExactSpelling = true)]", ImportName);
            }

            // GLboolean is mapped to 'unsigned char': instruct to marshal return value as 1 byte boolean
            if (Prototype.Type == "GLboolean")
            {
                sw.WriteLine("[return: MarshalAs(UnmanagedType.I1)]");
            }
            // BOOL is mapped to 'unsigned int': instruct to marshal return value as 4 byte boolean
            if (Prototype.Type == "BOOL")
            {
                sw.WriteLine("[return: MarshalAs(UnmanagedType.Bool)]");
            }

            // Import declaration
            sw.WriteIdentation(); sw.Write("internal extern static ");
            if (IsSafeImplementation == false)
            {
                sw.Write("unsafe ");
            }

            sw.Write("{0} {1}(", DelegateReturnType, ImportName);

            int paramCount = Parameters.Count;

            foreach (CommandParameter param in Parameters)
            {
                sw.Write("{0} {1}", param.ImportType, param.ImportName);
                paramCount--;
                if (paramCount > 0)
                {
                    sw.Write(", ");
                }
            }
            sw.Write(");");
            sw.WriteLine();
        }
Example #3
0
        /// <summary>
        /// Generate the command implementation (pinned variant).
        /// </summary>
        /// <param name="sw">
        /// The <see cref="SourceStreamWriter"/> used to write the source code.
        /// </param>
        /// <param name="ctx">
        /// The <see cref="RegistryContext"/> defining the OpenGL registry information.
        /// </param>
        /// <param name="commandParams">
        /// A <see cref="T:List{CommandParameter}"/> determining the method overload.
        /// </param>
        private void GenerateImplementation_Pinned(SourceStreamWriter sw, RegistryContext ctx, List <CommandParameter> commandParams)
        {
            // Signature
            GenerateImplementation_Signature(sw, ctx, commandParams);

            // Implementation block
            sw.WriteLine("{");
            sw.Indent();

            #region Pinned Object Block (Open)

            foreach (CommandParameter param in commandParams)
            {
                param.WritePinnedVariable(sw, ctx, this);
            }

            sw.WriteLine("try {");
            sw.Indent();

            #endregion

            #region Implementation Call

            sw.WriteIdentation();
            if (HasReturnValue)
            {
                sw.Write("return (");
            }

            sw.Write("{0}(", GetImplementationName(ctx));

            #region Parameters

            for (int i = 0; i < commandParams.Count; i++)
            {
                CommandParameter param = commandParams[i];

                param.WriteDelegateParam(sw, ctx, this);

                if (i != commandParams.Count - 1)
                {
                    sw.Write(", ");
                }
            }

            #endregion

            sw.Write(")");

            if (HasReturnValue)
            {
                sw.Write(")");
            }
            sw.Write(";");
            sw.WriteLine();

            #endregion

            #region Pinned Object Block (Close)

            sw.Unindent();
            sw.WriteLine("} finally {");
            sw.Indent();

            foreach (CommandParameter param in commandParams)
            {
                param.WriteUnpinCommand(sw, ctx, this);
            }

            sw.Unindent();
            sw.WriteLine("}");

            #endregion

            sw.Unindent();
            sw.WriteLine("}");
        }
Example #4
0
        /// <summary>
        /// Generate the command implementation (fixed variant).
        /// </summary>
        /// <param name="sw">
        /// The <see cref="SourceStreamWriter"/> used to write the source code.
        /// </param>
        /// <param name="ctx">
        /// The <see cref="RegistryContext"/> defining the OpenGL registry information.
        /// </param>
        /// <param name="commandParams">
        /// A <see cref="T:List{CommandParameter}"/> determining the method overload.
        /// </param>
        private void GenerateImplementation_Default(SourceStreamWriter sw, RegistryContext ctx, List <CommandParameter> commandParams)
        {
            List <Command> aliases      = new List <Command>();
            Command        aliasCommand = this;

            // The implementation returned type
            string returnType = aliasCommand.GetImplementationReturnType(ctx);
            // Is fixed implementation
            bool fixedImplementation = IsFixedImplementation(ctx, commandParams);

            aliases.Add(this);
            aliases.AddRange(Aliases);

            // Signature
            GenerateImplementation_Signature(sw, ctx, commandParams);

            // Implementation block
            sw.WriteLine("{");
            sw.Indent();

            #region Debug Assertions

            // Debug assertions
            foreach (CommandParameter param in commandParams)
            {
                param.WriteDebugAssertion(sw, ctx, this);
            }

            #endregion

            #region Local Variables

            // Local variable: returned value
            if (HasReturnValue)
            {
                sw.WriteLine("{0} {1};", DelegateReturnType, ReturnVariableName);
                sw.WriteLine();
            }

            #endregion

            #region Unsafe Block (Open)

            if (fixedImplementation)
            {
                sw.WriteLine("unsafe {");                                                                               // (1)
                sw.Indent();

                foreach (CommandParameter param in commandParams)
                {
                    param.WriteFixedStatement(sw, ctx, this);
                }

                sw.WriteLine("{");                                                                                              // (2)
                sw.Indent();
            }

            #endregion

            sw.WriteLine("Debug.Assert(Delegates.{0} != null, \"{0} not implemented\");", aliasCommand.DelegateName);

            #region Delegate Call

            sw.WriteIdentation();

            // Local return value
            if (HasReturnValue)
            {
                sw.Write("{0} = ", ReturnVariableName);
            }

            sw.Write("Delegates.{0}(", aliasCommand.DelegateName);

            #region Parameters

            for (int i = 0; i < commandParams.Count; i++)
            {
                CommandParameter param = commandParams[i];

                param.WriteDelegateParam(sw, ctx, this);

                if (i != Parameters.Count - 1)
                {
                    sw.Write(", ");
                }
            }

            #endregion

            sw.Write(")");

            sw.Write(";");
            sw.WriteLine();

            #endregion

            #region Call Log

            sw.WriteIdentation(); sw.Write("LogFunction(");

            #region Call Log - Format String

            sw.Write("\"{0}(", aliasCommand.ImportName);
            for (int i = 0; i < commandParams.Count; i++)
            {
                commandParams[i].WriteCallLogFormatParam(sw, ctx, this, i);
                if (i < commandParams.Count - 1)
                {
                    sw.Write(", ");
                }
            }
            sw.Write(")");

            if (HasReturnValue)
            {
                sw.Write(" = {{{0}}}", commandParams.Count);
            }

            sw.Write("\"");

            #endregion

            #region Call Log - Format Arguments

            if ((commandParams.Count > 0) || HasReturnValue)
            {
                sw.Write(", ");

                for (int i = 0; i < commandParams.Count; i++)
                {
                    commandParams[i].WriteCallLogArgParam(sw, ctx, this);
                    if (i < commandParams.Count - 1)
                    {
                        sw.Write(", ");
                    }
                }
            }

            // Return value
            if (HasReturnValue)
            {
                if (commandParams.Count > 0)
                {
                    sw.Write(", ");
                }
                CommandParameter.WriteCallLogArgParam(sw, GetReturnValueExpression(ctx), returnType);
            }

            #endregion

            sw.Write(");");
            sw.WriteLine();

            #endregion

            #region Unsafe Block (Close)

            if (fixedImplementation)
            {
                sw.Unindent();
                sw.WriteLine("}");                                                                                              // (2) CLOSED
                sw.Unindent();
                sw.WriteLine("}");                                                                                              // (1) CLOSED
            }

            #endregion

            // Check call errors
            if ((Flags & CommandFlags.NoGetError) == 0)
            {
                string returnValue = "null";

                // Optionally pass the returned value to error checking method
                if (HasReturnValue)
                {
                    returnValue = ReturnVariableName;
                }

                sw.WriteLine("DebugCheckErrors({0});", returnValue);
            }

            // Returns value
            if (HasReturnValue)
            {
                sw.WriteLine();
                sw.WriteLine("return ({0});", GetReturnValueExpression(ctx));
            }

            sw.Unindent();
            sw.WriteLine("}");
        }
Example #5
0
        /// <summary>
        /// Generate the command implementation signature and the method documentation.
        /// </summary>
        /// <param name="sw">
        /// The <see cref="SourceStreamWriter"/> used to write the source code.
        /// </param>
        /// <param name="ctx">
        /// The <see cref="RegistryContext"/> defining the OpenGL registry information.
        /// </param>
        /// <param name="commandParams">
        /// A <see cref="T:List{CommandParameter}"/> determining the method overload.
        /// </param>
        private void GenerateImplementation_Signature(SourceStreamWriter sw, RegistryContext ctx, List <CommandParameter> commandParams, string implementationName, string returnType)
        {
#if !DEBUG
            // Documentation
            RegistryDocumentation.GenerateDocumentation(sw, ctx, this, commandParams);
#endif

            foreach (IFeature feature in RequiredBy)
            {
                sw.WriteLine("[RequiredByFeature(\"{0}\")]", feature.Name);
            }
            foreach (IFeature feature in RemovedBy)
            {
                sw.WriteLine("[RemovedByFeature(\"{0}\")]", feature.Name);
            }

            #region Signature

            sw.WriteIdentation();

            // Signature
            sw.Write("{0} static ", CommandFlagsDatabase.GetCommandVisibility(this));
            if (IsUnsafeImplementationSignature(ctx, commandParams))
            {
                sw.Write("unsafe ");
            }
            sw.Write("{0} {1}(", returnType, implementationName);
            // Signature - Parameters
            int paramCount = commandParams.FindAll(delegate(CommandParameter item) { return(!item.IsImplicit(ctx, this)); }).Count;

            foreach (CommandParameter param in commandParams)
            {
                // Skip in signature implicit parameters
                if (param.IsImplicit(ctx, this))
                {
                    continue;
                }

                string paramAttributes = param.GetImplementationTypeAttributes(ctx, this);
                string paramModifier   = param.GetImplementationTypeModifier(ctx, this);

                if (paramAttributes != null)
                {
                    sw.Write("{0} ", paramAttributes);
                }
                if (paramModifier != null)
                {
                    sw.Write("{0} ", paramModifier);
                }

                if ((paramCount == 1) && (param.IsManagedArray) && ((Flags & CommandFlags.VariadicParams) != 0))
                {
                    sw.Write("params ");
                }

                sw.Write("{0} {1}", param.GetImplementationType(ctx, this), param.ImplementationName);
                paramCount--;
                if (paramCount > 0)
                {
                    sw.Write(", ");
                }
            }
            sw.Write(")");
            sw.WriteLine();

            #endregion
        }
Example #6
0
		/// <summary>
		/// Generate the command implementation (generate one object variant).
		/// </summary>
		/// <param name="sw">
		/// The <see cref="SourceStreamWriter"/> used to write the source code.
		/// </param>
		/// <param name="ctx">
		/// The <see cref="RegistryContext"/> defining the OpenGL registry information.
		/// </param>
		/// <param name="commandParams">
		/// A <see cref="T:List{CommandParameter}"/> determining the method overload.
		/// </param>
		private void GenerateImplementation_GenOneObject(SourceStreamWriter sw, RegistryContext ctx)
		{
			List<CommandParameter> commandParams = new List<CommandParameter>();
			string implementationName = GetImplementationName(ctx);

			if      (implementationName.EndsWith("ies"))
				implementationName = implementationName.Substring(0, implementationName.Length - 3) + "y";
			else if (implementationName.EndsWith("s"))
				implementationName = implementationName.Substring(0, implementationName.Length - 1);

			foreach (CommandParameter commandParameter in Parameters)
				commandParams.Add(new CommandParameterArray(commandParameter, ctx, this));

			List<CommandParameterArray> arrayParameters = new List<CommandParameterArray>();
			List<CommandParameter> signatureParams = commandParams.FindAll(delegate(CommandParameter item) {
				bool compatible = CommandParameterArray.IsCompatible(item, ctx, this);
				bool arrayLengthParam = CommandParameterArray.IsArrayLengthParameter(item, ctx, this);

				if (compatible)
					arrayParameters.Add((CommandParameterArray)item);

				return (!compatible && !arrayLengthParam);
			});

			Debug.Assert(arrayParameters.Count == 1);
			CommandParameterArray returnParameter = arrayParameters[0];
			string returnParameterType = returnParameter.GetImplementationType(ctx, this);

			// Remove []
			returnParameterType = returnParameterType.Substring(0, returnParameterType.Length - 2);

			// Signature
			GenerateImplementation_Signature(sw, ctx, signatureParams, implementationName, returnParameterType);

			// Implementation block
			sw.WriteLine("{");
			sw.Indent();

			#region Local Variables

			sw.WriteLine("{0}[] {1} = new {0}[1];", returnParameterType, ReturnVariableName);

			#endregion

			#region Implementation Call

			sw.WriteIdentation();
			sw.Write("{0}(", GetImplementationName(ctx));

			#region Parameters

			for (int i = 0; i < commandParams.Count; i++) {
				CommandParameter param = commandParams[i];

				if        (CommandParameterArray.IsArrayLengthParameter(param, ctx, this)) {
					continue;
				} else if (CommandParameterArray.IsCompatible(param, ctx, this))
					sw.Write(ReturnVariableName);
				else
					param.WriteDelegateParam(sw, ctx, this);

				if (i != commandParams.Count - 1)
					sw.Write(", ");
			}

			#endregion

			sw.Write(");");
			sw.WriteLine();

			sw.WriteLine("return ({0}[0]);", ReturnVariableName);

			#endregion

			sw.Unindent();
			sw.WriteLine("}");
		}
Example #7
0
        /// <summary>
        /// Generate the command implementation (generate one object variant).
        /// </summary>
        /// <param name="sw">
        /// The <see cref="SourceStreamWriter"/> used to write the source code.
        /// </param>
        /// <param name="ctx">
        /// The <see cref="RegistryContext"/> defining the OpenGL registry information.
        /// </param>
        /// <param name="commandParams">
        /// A <see cref="T:List{CommandParameter}"/> determining the method overload.
        /// </param>
        private void GenerateImplementation_GenOneObject(SourceStreamWriter sw, RegistryContext ctx)
        {
            List <CommandParameter> commandParams = new List <CommandParameter>();
            string implementationName             = GetImplementationName(ctx);

            if (implementationName.EndsWith("ies"))
            {
                implementationName = implementationName.Substring(0, implementationName.Length - 3) + "y";
            }
            else if (implementationName.EndsWith("s"))
            {
                implementationName = implementationName.Substring(0, implementationName.Length - 1);
            }

            foreach (CommandParameter commandParameter in Parameters)
            {
                commandParams.Add(new CommandParameterArrayLength(commandParameter, ctx, this));
            }

            List <CommandParameterArrayLength> arrayParameters = new List <CommandParameterArrayLength>();
            List <CommandParameter>            signatureParams = commandParams.FindAll(delegate(CommandParameter item) {
                bool compatible       = CommandParameterArrayLength.IsCompatible(ctx, this, item);
                bool arrayLengthParam = CommandParameterArrayLength.IsArrayLengthParameter(item, ctx, this);

                if (compatible)
                {
                    arrayParameters.Add((CommandParameterArrayLength)item);
                }

                return(!compatible && !arrayLengthParam);
            });

            Debug.Assert(arrayParameters.Count == 1);
            CommandParameterArrayLength returnParameter = arrayParameters[0];
            string returnParameterType = returnParameter.GetImplementationType(ctx, this);

            // Remove []
            returnParameterType = returnParameterType.Substring(0, returnParameterType.Length - 2);

            // Signature
            GenerateImplementation_Signature(sw, ctx, signatureParams, implementationName, returnParameterType);

            // Implementation block
            sw.WriteLine("{");
            sw.Indent();

            #region Local Variables

            sw.WriteLine("{0}[] {1} = new {0}[1];", returnParameterType, ReturnVariableName);

            #endregion

            #region Implementation Call

            sw.WriteIdentation();
            sw.Write("{0}(", GetImplementationName(ctx));

            #region Parameters

            for (int i = 0; i < commandParams.Count; i++)
            {
                CommandParameter param = commandParams[i];

                if (CommandParameterArrayLength.IsArrayLengthParameter(param, ctx, this))
                {
                    continue;
                }
                else if (CommandParameterArrayLength.IsCompatible(ctx, this, param))
                {
                    sw.Write(ReturnVariableName);
                }
                else
                {
                    param.WriteDelegateParam(sw, ctx, this);
                }

                if (i != commandParams.Count - 1)
                {
                    sw.Write(", ");
                }
            }

            #endregion

            sw.Write(");");
            sw.WriteLine();

            sw.WriteLine("return ({0}[0]);", ReturnVariableName);

            #endregion

            sw.Unindent();
            sw.WriteLine("}");
        }
Example #8
0
		/// <summary>
		/// Generate the command implementation (fixed variant).
		/// </summary>
		/// <param name="sw">
		/// The <see cref="SourceStreamWriter"/> used to write the source code.
		/// </param>
		/// <param name="ctx">
		/// The <see cref="RegistryContext"/> defining the OpenGL registry information.
		/// </param>
		/// <param name="commandParams">
		/// A <see cref="T:List{CommandParameter}"/> determining the method overload.
		/// </param>
		private void GenerateImplementation_Default(SourceStreamWriter sw, RegistryContext ctx, List<CommandParameter> commandParams)
		{
			List<Command> aliases = new List<Command>();
			Command aliasCommand = this;

			// The implementation returned type
			string returnType = aliasCommand.GetImplementationReturnType(ctx);
			// The delegate returned type
			string delegateReturnType = aliasCommand.DelegateReturnType;

			bool fixedImplementation = IsFixedImplementation(ctx, commandParams);
			// At least one parameter is an array with length correlated with another parameter
			bool isArrayImplementation = commandParams.FindIndex(delegate(CommandParameter item) { return (item is CommandParameterArray); }) >= 0;
			// Returned value must be marshalled as string
			bool marshalReturnedString = aliasCommand.HasReturnValue && (returnType.ToLower() == "string") && (delegateReturnType.ToLower() != "string");
			// Returned value must be marshalled as structure
			bool marshalReturnedStruct = aliasCommand.HasReturnValue && (DelegateReturnType == "IntPtr") && (GetImplementationReturnType(ctx) != "IntPtr");

			aliases.Add(this);
			aliases.AddRange(Aliases);

			// Signature
			GenerateImplementation_Signature(sw, ctx, commandParams);

			// Implementation block
			sw.WriteLine("{");
			sw.Indent();

			#region Debug Assertions

			// Debug assertions
			foreach (CommandParameter param in commandParams)
				param.WriteDebugAssertion(sw, ctx, this);

			#endregion

			#region Local Variables

			// Local variable: returned value
			if (HasReturnValue) {
				sw.WriteLine("{0} {1};", DelegateReturnType, ReturnVariableName);
				sw.WriteLine();
			}

			#endregion

			#region Unsafe Block (Open)

			if (fixedImplementation) {
				sw.WriteLine("unsafe {");								// (1)
				sw.Indent();

				foreach (CommandParameter param in commandParams)
					param.WriteFixedStatement(sw, ctx, this);

				sw.WriteLine("{");										// (2)
				sw.Indent();
			}

			#endregion

			sw.WriteLine("Debug.Assert(Delegates.{0} != null, \"{0} not implemented\");", aliasCommand.DelegateName);

			#region Delegate Call

			sw.WriteIdentation();

			// Local return value
			if (HasReturnValue) 
				sw.Write("{0} = ", ReturnVariableName);

			sw.Write("Delegates.{0}(", aliasCommand.DelegateName);

			#region Parameters

			for (int i = 0; i < commandParams.Count; i++) {
				CommandParameter param = commandParams[i];

				param.WriteDelegateParam(sw, ctx, this);

				if (i != Parameters.Count - 1)
					sw.Write(", ");
			}

			#endregion

			sw.Write(")");

			sw.Write(";");
			sw.WriteLine();

			#endregion

			#region Call Log

			sw.WriteIdentation(); sw.Write("CallLog(");

			#region Call Log - Format String

			sw.Write("\"{0}(", aliasCommand.ImportName);
			for (int i = 0; i < commandParams.Count; i++)
			{
				commandParams[i].WriteCallLogFormatParam(sw, ctx, this, i);
				if (i < commandParams.Count - 1)
					sw.Write(", ");
			}
			sw.Write(")");

			if (HasReturnValue)
				sw.Write(" = {{{0}}}", commandParams.Count);

			sw.Write("\"");

			#endregion

			#region Call Log - Format Arguments

			if ((commandParams.Count > 0) || HasReturnValue) {
				sw.Write(", ");

				for (int i = 0; i < commandParams.Count; i++) {
					commandParams[i].WriteCallLogArgParam(sw, ctx, this);
					if (i < commandParams.Count - 1)
						sw.Write(", ");
				}
			}

			// Return value
			if (HasReturnValue)
			{
				if (commandParams.Count > 0)
					sw.Write(", ");
				CommandParameter.WriteCallLogArgParam(sw, ReturnVariableName, returnType);
			}

			#endregion

			sw.Write(");");
			sw.WriteLine();

			#endregion

			#region Unsafe Block (Close)

			if (fixedImplementation)
			{
				sw.Unindent();
				sw.WriteLine("}");										// (2) CLOSED
				sw.Unindent();
				sw.WriteLine("}");										// (1) CLOSED
			}

			#endregion

			// Check call errors
			if ((Flags & CommandFlags.NoGetError) == 0)
				sw.WriteLine("DebugCheckErrors();");

			// Returns value
			if (HasReturnValue) {
				sw.WriteLine();

				if      (marshalReturnedString)
					sw.WriteLine("return (Marshal.PtrToStringAnsi({0}));", ReturnVariableName);
				else if (marshalReturnedStruct)
					sw.WriteLine("return (({1})Marshal.PtrToStructure({0}, typeof({1})));", ReturnVariableName, GetImplementationReturnType(ctx));
				else if (returnType != delegateReturnType)
					sw.WriteLine("return (({1}){0});", ReturnVariableName, GetImplementationReturnType(ctx));
				else
					sw.WriteLine("return ({0});", ReturnVariableName);
			}

			sw.Unindent();
			sw.WriteLine("}");
		}
Example #9
0
		/// <summary>
		/// Generate the command implementation (pinned variant).
		/// </summary>
		/// <param name="sw">
		/// The <see cref="SourceStreamWriter"/> used to write the source code.
		/// </param>
		/// <param name="ctx">
		/// The <see cref="RegistryContext"/> defining the OpenGL registry information.
		/// </param>
		/// <param name="commandParams">
		/// A <see cref="T:List{CommandParameter}"/> determining the method overload.
		/// </param>
		private void GenerateImplementation_Pinned(SourceStreamWriter sw, RegistryContext ctx, List<CommandParameter> commandParams)
		{
			// Signature
			GenerateImplementation_Signature(sw, ctx, commandParams);

			// Implementation block
			sw.WriteLine("{");
			sw.Indent();

			#region Pinned Object Block (Open)

			foreach (CommandParameter param in commandParams)
				param.WritePinnedVariable(sw, ctx, this);

			sw.WriteLine("try {");
			sw.Indent();

			#endregion

			#region Implementation Call

			sw.WriteIdentation();
			if (HasReturnValue)
				sw.Write("return (");

			sw.Write("{0}(", GetImplementationName(ctx));

			#region Parameters

			for (int i = 0; i < commandParams.Count; i++) {
				CommandParameter param = commandParams[i];

				param.WriteDelegateParam(sw, ctx, this);

				if (i != commandParams.Count - 1)
					sw.Write(", ");
			}

			#endregion

			sw.Write(")");

			if (HasReturnValue)
				sw.Write(")");
			sw.Write(";");
			sw.WriteLine();

			#endregion

			#region Pinned Object Block (Close)

			sw.Unindent();
			sw.WriteLine("} finally {");
			sw.Indent();

			foreach (CommandParameter param in commandParams)
				param.WriteUnpinCommand(sw, ctx, this);

			sw.Unindent();
			sw.WriteLine("}");

			#endregion

			sw.Unindent();
			sw.WriteLine("}");
		}
Example #10
0
		/// <summary>
		/// Generate the command implementation signature and the method documentation.
		/// </summary>
		/// <param name="sw">
		/// The <see cref="SourceStreamWriter"/> used to write the source code.
		/// </param>
		/// <param name="ctx">
		/// The <see cref="RegistryContext"/> defining the OpenGL registry information.
		/// </param>
		/// <param name="commandParams">
		/// A <see cref="T:List{CommandParameter}"/> determining the method overload.
		/// </param>
		private void GenerateImplementation_Signature(SourceStreamWriter sw, RegistryContext ctx, List<CommandParameter> commandParams, string implementationName, string returnType)
		{
#if !DEBUG
			// Documentation
			RegistryDocumentation.GenerateDocumentation(sw, ctx, this, commandParams);
#endif

			foreach (IFeature feature in RequiredBy)
				sw.WriteLine("[RequiredByFeature(\"{0}\")]", feature.Name);
			foreach (IFeature feature in RemovedBy)
				sw.WriteLine("[RemovedByFeature(\"{0}\")]", feature.Name);

			#region Signature

			sw.WriteIdentation();

			// Signature
			sw.Write("{0} static ", CommandFlagsDatabase.GetCommandVisibility(this));
			if (IsUnsafeImplementationSignature(ctx, commandParams))
				sw.Write("unsafe ");
			sw.Write("{0} {1}(", returnType, implementationName);
			// Signature - Parameters
			int paramCount = commandParams.FindAll(delegate(CommandParameter item) { return (!item.IsImplicit(ctx, this)); }).Count;

			foreach (CommandParameter param in commandParams) {
				// Skip in signature implicit parameters
				if (param.IsImplicit(ctx, this))
					continue;

				string paramAttributes = param.GetImplementationTypeAttributes(ctx, this);
				string paramModifier = param.GetImplementationTypeModifier(ctx, this);

				if (paramAttributes != null)
					sw.Write("{0} ", paramAttributes);
				if (paramModifier != null)
					sw.Write("{0} ", paramModifier);

				if ((paramCount == 1) && (param.IsManagedArray) && ((Flags & CommandFlags.VariadicParams) != 0))
					sw.Write("params ");

				sw.Write("{0} {1}", param.GetImplementationType(ctx, this), param.ImplementationName);
				paramCount--;
				if (paramCount > 0)
					sw.Write(", ");
			}
			sw.Write(")");
			sw.WriteLine();

			#endregion
		}
Example #11
0
		/// <summary>
		/// Generate the command delegate source code.
		/// </summary>
		/// <param name="sw">
		/// The <see cref="SourceStreamWriter"/> used to write the source code.
		/// </param>
		/// <param name="ctx">
		/// The <see cref="RegistryContext"/> defining the OpenGL registry information.
		/// </param>
		internal void GenerateDelegate(SourceStreamWriter sw, RegistryContext ctx)
		{
			if (Aliases.Count > 0) {
				sw.WriteLine("[AliasOf(\"{0}\")]", ImportName);
				foreach (Command aliasOf in Aliases)
					sw.WriteLine("[AliasOf(\"{0}\")]", aliasOf.ImportName);
			}

			// No sure if it is really necessary
			sw.WriteLine("[SuppressUnmanagedCodeSecurity()]");

			// Delegate type definition
			sw.WriteIdentation(); sw.Write("internal ");
			if (IsSafeImplementation == false) sw.Write("unsafe ");
			sw.Write("delegate ");

			sw.Write("{0} {1}(", DelegateReturnType, ImportName);

			int paramCount = Parameters.Count;

			foreach (CommandParameter param in Parameters) {
				string paramAttributes = param.GetDelegateTypeAttributes(ctx, this);
				string paramModifier = param.GetDelegateTypeModifier(ctx, this);

				if (paramAttributes != null)
					sw.Write("{0} ", paramAttributes);
				if (paramModifier != null)
					sw.Write("{0} ", paramModifier);


				sw.Write("{0} {1}", param.GetDelegateType(ctx, this), param.ImportName);
				paramCount--;
				if (paramCount > 0)
					sw.Write(", ");
			}
			sw.Write(");");
			sw.WriteLine();

			// Required on Windows platform: different threads can bind different OpenGL context, which can have different
			// entry points
			sw.WriteLine("[ThreadStatic]");

			// Delegate field
			sw.WriteLine("internal static {0} {1};", ImportName, DelegateName);
		}
Example #12
0
		/// <summary>
		/// Generate the command import source code.
		/// </summary>
		/// <param name="sw">
		/// The <see cref="SourceStreamWriter"/> used to write the source code.
		/// </param>
		/// <param name="ctx">
		/// The <see cref="RegistryContext"/> defining the OpenGL registry information.
		/// </param>
		internal void GenerateImport(SourceStreamWriter sw, RegistryContext ctx)
		{
			// The SuppressUnmanagedCodeSecurity attribute is used to increase P/Invoke performance
			sw.WriteLine("[SuppressUnmanagedCodeSecurity()]");
			// Import definition
			sw.WriteLine("[DllImport(Library, EntryPoint = \"{0}\", ExactSpelling = true)]", ImportName);

			// GLboolean is mapped to 'unsigned char': instruct to marshal return value as 1 byte boolean
			if (Prototype.Type == "GLboolean")
				sw.WriteLine("[return: MarshalAs(UnmanagedType.I1)]");
			// BOOL is mapped to 'unsigned int': instruct to marshal return value as 4 byte boolean
			if (Prototype.Type == "BOOL")
				sw.WriteLine("[return: MarshalAs(UnmanagedType.Bool)]");

			// Import declaration
			sw.WriteIdentation(); sw.Write("internal extern static ");
			if (IsSafeImplementation == false) sw.Write("unsafe ");

			sw.Write("{0} {1}(", DelegateReturnType, ImportName);

			int paramCount = Parameters.Count;

			foreach (CommandParameter param in Parameters) {
				sw.Write("{0} {1}", param.ImportType, param.ImportName);
				paramCount--;
				if (paramCount > 0)
					sw.Write(", ");
			}
			sw.Write(");");
			sw.WriteLine();
		}
Example #13
0
		/// <summary>
		/// Generate the command implementation (fixed variant).
		/// </summary>
		/// <param name="sw">
		/// The <see cref="SourceStreamWriter"/> used to write the source code.
		/// </param>
		/// <param name="ctx">
		/// The <see cref="RegistryContext"/> defining the OpenGL registry information.
		/// </param>
		/// <param name="commandParams">
		/// A <see cref="T:List{CommandParameter}"/> determining the method overload.
		/// </param>
		private void GenerateImplementation_Default(SourceStreamWriter sw, RegistryContext ctx, List<CommandParameter> commandParams)
		{
			List<Command> aliases = new List<Command>();
			Command aliasCommand = this;

			// The implementation returned type
			string returnType = aliasCommand.GetImplementationReturnType(ctx);
			// Is fixed implementation
			bool fixedImplementation = IsFixedImplementation(ctx, commandParams);

			aliases.Add(this);
			aliases.AddRange(Aliases);

			// Signature
			GenerateImplementation_Signature(sw, ctx, commandParams);

			// Implementation block
			sw.WriteLine("{");
			sw.Indent();

			#region Debug Assertions

			// Debug assertions
			foreach (CommandParameter param in commandParams)
				param.WriteDebugAssertion(sw, ctx, this);

			#endregion

			#region Local Variables

			// Local variable: returned value
			if (HasReturnValue) {
				sw.WriteLine("{0} {1};", DelegateReturnType, ReturnVariableName);
				sw.WriteLine();
			}

			#endregion

			#region Unsafe Block (Open)

			if (fixedImplementation) {
				sw.WriteLine("unsafe {");								// (1)
				sw.Indent();

				foreach (CommandParameter param in commandParams)
					param.WriteFixedStatement(sw, ctx, this);

				sw.WriteLine("{");										// (2)
				sw.Indent();
			}

			#endregion

			sw.WriteLine("Debug.Assert(Delegates.{0} != null, \"{0} not implemented\");", aliasCommand.DelegateName);

			#region Delegate Call

			sw.WriteIdentation();

			// Local return value
			if (HasReturnValue) 
				sw.Write("{0} = ", ReturnVariableName);

			sw.Write("Delegates.{0}(", aliasCommand.DelegateName);

			#region Parameters

			for (int i = 0; i < commandParams.Count; i++) {
				CommandParameter param = commandParams[i];

				param.WriteDelegateParam(sw, ctx, this);

				if (i != Parameters.Count - 1)
					sw.Write(", ");
			}

			#endregion

			sw.Write(")");

			sw.Write(";");
			sw.WriteLine();

			#endregion

			#region Call Log

			sw.WriteIdentation(); sw.Write("LogFunction(");

			#region Call Log - Format String

			sw.Write("\"{0}(", aliasCommand.ImportName);
			for (int i = 0; i < commandParams.Count; i++)
			{
				commandParams[i].WriteCallLogFormatParam(sw, ctx, this, i);
				if (i < commandParams.Count - 1)
					sw.Write(", ");
			}
			sw.Write(")");

			if (HasReturnValue)
				sw.Write(" = {{{0}}}", commandParams.Count);

			sw.Write("\"");

			#endregion

			#region Call Log - Format Arguments

			if ((commandParams.Count > 0) || HasReturnValue) {
				sw.Write(", ");

				for (int i = 0; i < commandParams.Count; i++) {
					commandParams[i].WriteCallLogArgParam(sw, ctx, this);
					if (i < commandParams.Count - 1)
						sw.Write(", ");
				}
			}

			// Return value
			if (HasReturnValue)
			{
				if (commandParams.Count > 0)
					sw.Write(", ");
				CommandParameter.WriteCallLogArgParam(sw, GetReturnValueExpression(ctx), returnType);
			}

			#endregion

			sw.Write(");");
			sw.WriteLine();

			#endregion

			#region Unsafe Block (Close)

			if (fixedImplementation)
			{
				sw.Unindent();
				sw.WriteLine("}");										// (2) CLOSED
				sw.Unindent();
				sw.WriteLine("}");										// (1) CLOSED
			}

			#endregion

			// Check call errors
			if ((Flags & CommandFlags.NoGetError) == 0) {
				string returnValue = "null";

				// Optionally pass the returned value to error checking method
				if (HasReturnValue)
					returnValue = ReturnVariableName;

				sw.WriteLine("DebugCheckErrors({0});", returnValue);
			}

			// Returns value
			if (HasReturnValue) {
				sw.WriteLine();
				sw.WriteLine("return ({0});", GetReturnValueExpression(ctx));
			}

			sw.Unindent();
			sw.WriteLine("}");
		}
Example #14
0
        /// <summary>
        /// Generate the command delegate source code.
        /// </summary>
        /// <param name="sw">
        /// The <see cref="SourceStreamWriter"/> used to write the source code.
        /// </param>
        /// <param name="ctx">
        /// The <see cref="RegistryContext"/> defining the OpenGL registry information.
        /// </param>
        internal void GenerateDelegate(SourceStreamWriter sw, RegistryContext ctx)
        {
            // Attributes required for checking API commands support
            string classDefaultApi = ctx.Class.ToLower();

            foreach (IFeature feature in RequiredBy)
            {
                sw.WriteLine(feature.GenerateRequiredByAttribute(this, classDefaultApi));
            }

            foreach (IFeature feature in RemovedBy)
            {
                sw.WriteLine(feature.GenerateRemovedByAttribute(classDefaultApi));
            }

            // Not yet sure if it is really necessary
            sw.WriteLine("[SuppressUnmanagedCodeSecurity()]");

            // Delegate type definition
            sw.WriteIdentation(); sw.Write("internal ");
            if (IsSafeImplementation == false)
            {
                sw.Write("unsafe ");
            }
            sw.Write("delegate ");

            sw.Write("{0} {1}(", DelegateReturnType, ImportName);

            int paramCount = Parameters.Count;

            foreach (CommandParameter param in Parameters)
            {
                string paramAttributes = param.GetDelegateTypeAttributes(ctx, this);
                string paramModifier   = param.GetDelegateTypeModifier(ctx, this);

                if (paramAttributes != null)
                {
                    sw.Write("{0} ", paramAttributes);
                }
                if (paramModifier != null)
                {
                    sw.Write("{0} ", paramModifier);
                }


                sw.Write("{0} {1}", param.GetDelegateType(ctx, this), param.ImportName);
                paramCount--;
                if (paramCount > 0)
                {
                    sw.Write(", ");
                }
            }
            sw.Write(");");
            sw.WriteLine();

            sw.WriteLine();

            foreach (IFeature feature in RequiredBy)
            {
                sw.WriteLine(feature.GenerateRequiredByAttribute(this, classDefaultApi));
            }

            foreach (IFeature feature in RemovedBy)
            {
                sw.WriteLine(feature.GenerateRemovedByAttribute(classDefaultApi));
            }

            // Required on Windows platform: different threads can bind different OpenGL context, which can have different
            // entry points
            if (ctx.Class == "Gl")
            {
                sw.WriteLine("[ThreadStatic]");
            }

            // Delegate field
            sw.WriteLine("internal static {0} {1};", ImportName, DelegateName);
        }