Skip to content

Commit

Permalink
Significant cleanups and bugfixes to the C++ wrappers. Improved typem…
Browse files Browse the repository at this point in the history
…ap to use correct OpenGL types.

git-svn-id: https://opentk.svn.sourceforge.net/svnroot/opentk/trunk@3109 ebc5dd9b-fb1d-0410-b6f8-d24c324e9604
  • Loading branch information
the_fiddler committed Dec 5, 2011
1 parent 1270770 commit ae1cdf6
Showing 1 changed file with 138 additions and 32 deletions.
170 changes: 138 additions & 32 deletions Source/Bind/CppSpecWriter.cs
Expand Up @@ -55,26 +55,26 @@ namespace Internals
#if defined(_WIN32) #if defined(_WIN32)
extern ""C"" extern ""C""
{ {
#define GLPP_APIENTRY __stdcall
typedef int (*PROC)(); typedef int (*PROC)();
extern void* __stdcall wglGetCurrentContext(); extern void* __stdcall wglGetCurrentContext();
extern PROC __stdcall wglGetProcAddress(const char *procname); extern PROC __stdcall wglGetProcAddress(const char *procname);
} }
#elif !defined(__APPLE__) #elif !defined(__APPLE__)
extern ""C"" extern ""C""
{ {
#define APIENTRY #define GLPP_APIENTRY
extern void* glXGetCurrentContext(); extern void* glXGetCurrentContext();
extern void (*glXGetProcAddress(const char *procname))(); extern void (*glXGetProcAddress(const char *procname))();
} }
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
#define APIENTRY #define GLPP_APIENTRY
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <AvailabilityMacros.h> #include <AvailabilityMacros.h>
#define APIENTRY
extern ""C"" void* CGLGetCurrentContext(); extern ""C"" void* CGLGetCurrentContext();
#ifdef MAC_OS_X_VERSION_10_3 #ifdef MAC_OS_X_VERSION_10_3
Expand Down Expand Up @@ -112,7 +112,7 @@ namespace Internals
#endif /* __APPLE__ */ #endif /* __APPLE__ */
#if defined(__sgi) || defined (__sun) #if defined(__sgi) || defined (__sun)
#define APIENTRY #define GLPP_APIENTRY
#include <dlfcn.h> #include <dlfcn.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
Expand Down Expand Up @@ -206,7 +206,10 @@ inline Enumeration(int value)
typedef double GLdouble; typedef double GLdouble;
typedef double GLclampd; typedef double GLclampd;
typedef void GLvoid; typedef void GLvoid;
typedef const char* GLstring; typedef GLint* GLintptr;
typedef GLsizei* GLsizeiptr;
typedef const char* GLstring;
#if defined(_MSC_VER) && _MSC_VER < 1400 #if defined(_MSC_VER) && _MSC_VER < 1400
typedef __int64 GLint64EXT; typedef __int64 GLint64EXT;
typedef unsigned __int64 GLuint64EXT; typedef unsigned __int64 GLuint64EXT;
Expand All @@ -217,6 +220,9 @@ inline Enumeration(int value)
typedef GLint64EXT GLint64; typedef GLint64EXT GLint64;
typedef GLuint64EXT GLuint64; typedef GLuint64EXT GLuint64;
typedef struct __GLsync { } *GLsync; typedef struct __GLsync { } *GLsync;
typedef struct __GLhandleARB { } *GLhandleARB;
typedef GLintptr GLintptrARB;
typedef GLsizeiptr GLsizeiptrARB;
typedef char GLchar; typedef char GLchar;
typedef void (*GLDEBUGPROCAMD)(GLuint id, typedef void (*GLDEBUGPROCAMD)(GLuint id,
Expand All @@ -231,8 +237,8 @@ inline Enumeration(int value)
/* For GL_ARB_cl_event */ /* For GL_ARB_cl_event */
typedef struct _cl_context *cl_context; typedef struct cl_context *_cl_context;
typedef struct _cl_event *cl_event; typedef struct cl_event *_cl_event;
//typedef GLsizei IntPtr; //typedef GLsizei IntPtr;
typedef void* IntPtr; typedef void* IntPtr;
Expand All @@ -250,14 +256,17 @@ inline Enumeration(int value)
typedef char* StringBuilder; typedef char* StringBuilder;
typedef GLDEBUGPROCAMD DebugProcAmd; typedef GLDEBUGPROCAMD DebugProcAmd;
typedef GLDEBUGPROCARB DebugProcArb; typedef GLDEBUGPROCARB DebugProcArb;
typedef struct _GLvdpauSurfaceNV *GLvdpauSurfaceNV;
struct Half struct Half
{ {
private: private:
UInt16 value; GLushort value;
public: public:
}; };
"; typedef Half GLhalf;
typedef GLhalf GLhalfNV;
";


#endregion #endregion


Expand Down Expand Up @@ -326,14 +335,17 @@ void Move(string file, string dest)


static Delegate WriteWrapper(Delegate last_delegate, Function f, BindStreamWriter sw) static Delegate WriteWrapper(Delegate last_delegate, Function f, BindStreamWriter sw)
{ {
if (last_delegate == f.WrappedDelegate) //if (last_delegate == f.WrappedDelegate)
return last_delegate; // Multiple wrappers for the same delegate are not necessary in C++ // return last_delegate; // Multiple wrappers for the same delegate are not necessary in C++

var valid = true;
var parameters = GenerateParameterString(f, true, out valid);
if (!valid)
return last_delegate;

last_delegate = f.WrappedDelegate; last_delegate = f.WrappedDelegate;


var parameters = f.WrappedDelegate.Parameters.ToString() sw.WriteLine("inline {0} {1}({2})", f.WrappedDelegate.ReturnType,
.Replace("String[]", "String*")
.Replace("[OutAttribute]", String.Empty);
sw.WriteLine("inline {0} {1}{2}", f.WrappedDelegate.ReturnType,
f.TrimmedName, parameters); f.TrimmedName, parameters);
sw.WriteLine("{"); sw.WriteLine("{");
sw.Indent(); sw.Indent();
Expand All @@ -343,6 +355,89 @@ static Delegate WriteWrapper(Delegate last_delegate, Function f, BindStreamWrite
return last_delegate; return last_delegate;
} }


static string GenerateParameterString(Delegate d, bool check_validity, out bool valid)
{
if (d == null)
throw new ArgumentNullException("d");

valid = true;
var sb = new StringBuilder();

if (d.Parameters.Count > 0)
{
foreach (var p in d.Parameters)
{
if (p.CurrentType.ToLower() == "string[]")
p.CurrentType = "char**";
if (p.CurrentType.ToLower() == "string")
p.CurrentType = "char*";

if (p.Reference)
{
if (/*check_validity &&*/ p.Generic)
{
// We don't need generic parameters in C++ and void& is illegal.
valid = false;
return String.Empty;
}

if (p.Flow != FlowDirection.Out)
sb.Append("const ");
sb.Append(p.QualifiedType);
sb.Append('*', p.Array);
sb.Append("&");
}
else if (p.Array > 0)
{
// Hack: generic parameters with array types are
// not real (i.e. they are created by the generator
// specifically for managed languages). We don't
// need them in C++.
// Todo: move C#/Java-specific code to their respective
// classes, instead of the main generator.
// Note: the 1-dimensional array is handled through the pointer case below.
// (C# differentiates between arrays and pointers, C++ doesn't).
if (check_validity && (p.Generic || p.Array == 1))
{
valid = false;
return String.Empty;
}

if (p.Flow != FlowDirection.Out)
sb.Append("const ");
sb.Append(p.Generic ? "void" : p.QualifiedType); // We don't need generic parameters in C++.
sb.Append('*', p.Array);
}
else if (p.Pointer > 0)
{
if (p.Flow != FlowDirection.Out)
sb.Append("const ");
sb.Append(p.Generic ? "void" : p.QualifiedType); // We don't need generic parameters in C++.
sb.Append('*', p.Pointer);
}
else if (p.CurrentType == "IntPtr")
{
if (p.Flow != FlowDirection.Out)
sb.Append("const ");
sb.Append("void*");
}
else
{
sb.Append(p.QualifiedType);
}

sb.Append(" ");
sb.Append(p.Name);
sb.Append(", ");
}

if (d.Parameters.Count > 0)
sb.Remove(sb.Length - 2, 2);
}

return sb.ToString();
}

static Delegate WriteInitDelegate(Delegate last_delegate, BindStreamWriter sw, Function f) static Delegate WriteInitDelegate(Delegate last_delegate, BindStreamWriter sw, Function f)
{ {
if (last_delegate != f.WrappedDelegate) if (last_delegate != f.WrappedDelegate)
Expand Down Expand Up @@ -437,9 +532,6 @@ static Delegate WriteInitDelegate(Delegate last_delegate, BindStreamWriter sw, F


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

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


#endregion #endregion
Expand Down Expand Up @@ -467,11 +559,10 @@ public void WriteEnums(BindStreamWriter sw, EnumCollection enums)
sw.Indent(); sw.Indent();
foreach (var c in @enum.ConstantCollection.Values) foreach (var c in @enum.ConstantCollection.Values)
{ {
// C++ doesn't have the concept of "unchecked", so remove this. sw.WriteLine(String.Format("{0} = {1}{2},",
if (!c.Unchecked) c.Name,
sw.WriteLine("{0},", c); !String.IsNullOrEmpty(c.Reference) ? (c.Reference + Settings.NamespaceSeparator) : "",
else !String.IsNullOrEmpty(c.Reference) ? c.Value : c.Value.ToLower()));
sw.WriteLine("{0},", c.ToString().Replace("unchecked", String.Empty));
} }
sw.Unindent(); sw.Unindent();
sw.WriteLine("};"); sw.WriteLine("};");
Expand Down Expand Up @@ -509,10 +600,9 @@ static void WriteDelegate(BindStreamWriter sw, Delegate d, ref Delegate last_del
if (d != last_delegate) if (d != last_delegate)
{ {
last_delegate = d; last_delegate = d;
var parameters = d.Parameters.ToString() bool valid = true;
.Replace("String[]", "String*") var parameters = GenerateParameterString(d, false, out valid);
.Replace("[OutAttribute]", String.Empty); sw.WriteLine("typedef {0} (GLPP_APIENTRY *p{1})({2});", d.ReturnType, d.Name, parameters);
sw.WriteLine("typedef {0} (APIENTRY *p{1}){2};", d.ReturnType, d.Name, parameters);
sw.WriteLine("inline p{0}& {0}()", d.Name); sw.WriteLine("inline p{0}& {0}()", d.Name);
sw.WriteLine("{"); sw.WriteLine("{");
sw.Indent(); sw.Indent();
Expand All @@ -529,13 +619,29 @@ static void WriteDelegate(BindStreamWriter sw, Delegate d, ref Delegate last_del


static void WriteMethodBody(BindStreamWriter sw, Function f) static void WriteMethodBody(BindStreamWriter sw, Function f)
{ {
//var callstring = f.Parameters.CallString()
// .Replace("String[]", "String*");

var callstring = GenerateCallString(f);


var callstring = f.Parameters.CallString()
.Replace("String[]", "String*");
if (f.ReturnType != null && !f.ReturnType.ToString().ToLower().Contains("void")) if (f.ReturnType != null && !f.ReturnType.ToString().ToLower().Contains("void"))
sw.WriteLine("return Delegates::{0}(){1};", f.WrappedDelegate.Name, callstring); sw.Write("return ");
else sw.WriteLine("Delegates::{0}()({1});", f.WrappedDelegate.Name, callstring);
sw.WriteLine("Delegates::{0}(){1};", f.WrappedDelegate.Name, callstring); }

static object GenerateCallString(Function f)
{
var sb = new StringBuilder();
foreach (var p in f.Parameters)
{
if (p.Reference)
sb.Append("&"); // Convert to pointer
sb.Append(p.Name);
sb.Append(", ");
}
if (f.Parameters.Count > 0)
sb.Remove(sb.Length - 2, 2);
return sb.ToString();
} }


static DocProcessor processor = new DocProcessor(Path.Combine(Settings.DocPath, Settings.DocFile)); static DocProcessor processor = new DocProcessor(Path.Combine(Settings.DocPath, Settings.DocFile));
Expand Down

0 comments on commit ae1cdf6

Please sign in to comment.