2007-08-01 23:14:39 +02:00
|
|
|
|
#region --- License ---
|
|
|
|
|
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
|
|
|
|
* See license.txt for license info
|
|
|
|
|
*/
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
using System;
|
2007-07-23 02:15:18 +02:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
2007-08-01 23:14:39 +02:00
|
|
|
|
using System.Text.RegularExpressions;
|
2007-08-02 00:28:54 +02:00
|
|
|
|
using System.Diagnostics;
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
namespace Bind.Structures
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
2007-08-01 11:27:57 +02:00
|
|
|
|
public class Function : Delegate
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
2007-08-01 23:14:39 +02:00
|
|
|
|
internal static FunctionCollection Wrappers;
|
|
|
|
|
|
|
|
|
|
private static bool loaded;
|
2007-08-10 22:16:05 +02:00
|
|
|
|
|
|
|
|
|
#region internal static void Initialize()
|
|
|
|
|
|
2007-08-01 23:14:39 +02:00
|
|
|
|
internal static void Initialize()
|
|
|
|
|
{
|
|
|
|
|
if (!loaded)
|
|
|
|
|
{
|
|
|
|
|
Wrappers = new FunctionCollection();
|
|
|
|
|
loaded = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-08-10 22:16:05 +02:00
|
|
|
|
|
|
|
|
|
#endregion
|
2007-08-01 23:14:39 +02:00
|
|
|
|
|
2007-08-10 22:16:05 +02:00
|
|
|
|
Regex functionsNotToTrim = new Regex(@"(Coord1|Attrib(I?)1(u?)|Stream1|Uniform2(u?))[dfis]v");
|
|
|
|
|
|
|
|
|
|
//Regex endings = new Regex(@"(.)+[df(u?[isb])]v?");
|
|
|
|
|
|
2007-08-01 23:14:39 +02:00
|
|
|
|
private static List<string> endings = new List<string>(
|
|
|
|
|
new string[]
|
|
|
|
|
{
|
2007-08-10 22:16:05 +02:00
|
|
|
|
"fv", "f",
|
|
|
|
|
"dv", "d",
|
|
|
|
|
"i", "iv",
|
|
|
|
|
"s", "sv",
|
|
|
|
|
"b", "bv",
|
|
|
|
|
"ui", "uiv",
|
|
|
|
|
"us", "usv",
|
|
|
|
|
"ub", "ubv"
|
2007-08-01 23:14:39 +02:00
|
|
|
|
});
|
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
#region --- Constructors ---
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
|
|
|
|
public Function()
|
2007-08-01 11:27:57 +02:00
|
|
|
|
: base()
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
|
|
|
|
Body = new FunctionBody();
|
|
|
|
|
}
|
2007-08-01 23:14:39 +02:00
|
|
|
|
/*
|
2007-07-23 02:15:18 +02:00
|
|
|
|
public Function(Function f)
|
2007-08-01 11:27:57 +02:00
|
|
|
|
: base(f)
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
|
|
|
|
this.Body = new FunctionBody(f.Body);
|
2007-08-01 23:14:39 +02:00
|
|
|
|
this.Name = f.Name;
|
2007-07-23 02:15:18 +02:00
|
|
|
|
}
|
2007-08-01 23:14:39 +02:00
|
|
|
|
*/
|
2007-08-01 11:27:57 +02:00
|
|
|
|
public Function(Delegate d)
|
|
|
|
|
: base(d)
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
2007-08-01 23:14:39 +02:00
|
|
|
|
if (d is Function)
|
|
|
|
|
this.Body = new FunctionBody((d as Function).Body);
|
|
|
|
|
else
|
|
|
|
|
this.Body = new FunctionBody();
|
|
|
|
|
this.Name = d.Name;
|
2007-07-23 02:15:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-01 23:14:39 +02:00
|
|
|
|
#region public override bool Unsafe
|
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
public override bool Unsafe
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
2007-08-01 11:27:57 +02:00
|
|
|
|
get
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
2007-08-01 11:27:57 +02:00
|
|
|
|
if (Settings.Compatibility == Settings.Legacy.Tao)
|
|
|
|
|
return false;
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
return base.Unsafe;
|
|
|
|
|
}
|
2007-07-23 02:15:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-01 23:14:39 +02:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region public FunctionBody Body
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
FunctionBody _body;
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
public FunctionBody Body
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
2007-08-01 11:27:57 +02:00
|
|
|
|
get { return _body; }
|
|
|
|
|
set { _body = value; }
|
2007-07-23 02:15:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-01 23:14:39 +02:00
|
|
|
|
#region public string TrimmedName
|
|
|
|
|
|
|
|
|
|
string trimmedName;
|
|
|
|
|
/// <summary>
|
2007-08-02 00:28:54 +02:00
|
|
|
|
/// Gets or sets the name of the opengl function, trimming the excess 234dfubsiv endings.
|
2007-08-01 23:14:39 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
public string TrimmedName
|
|
|
|
|
{
|
|
|
|
|
get { return trimmedName; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (!String.IsNullOrEmpty(value))
|
|
|
|
|
trimmedName = value.Trim();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region public override string Name
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the name of the opengl function.
|
|
|
|
|
/// If no Tao compatibility is set, set TrimmedName to Name, after removing
|
|
|
|
|
/// [u][bsifd][v].
|
|
|
|
|
/// </summary>
|
|
|
|
|
public override string Name
|
|
|
|
|
{
|
|
|
|
|
get { return base.Name; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
base.Name = value;
|
|
|
|
|
|
|
|
|
|
// If we don't need compatibility with Tao,
|
|
|
|
|
// remove the Extension and the overload information from the name
|
|
|
|
|
// (Extension == "ARB", "EXT", etc, overload == [u][bsidf][v])
|
|
|
|
|
// TODO: Use some regex's here, to reduce clutter.
|
|
|
|
|
if (Settings.Compatibility != Settings.Legacy.Tao)
|
|
|
|
|
{
|
2007-08-10 22:16:05 +02:00
|
|
|
|
TrimmedName = value;
|
|
|
|
|
TrimmedName = Utilities.StripGL2Extension(value);
|
|
|
|
|
|
|
|
|
|
//if (TrimmedName.Contains("Uniform2iv"))
|
2007-08-01 23:14:39 +02:00
|
|
|
|
{
|
2007-08-10 22:16:05 +02:00
|
|
|
|
//Console.Write("niar");
|
2007-08-01 23:14:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove overload
|
2007-08-10 22:16:05 +02:00
|
|
|
|
for (int i = 3; i >= 1; i--)
|
2007-08-01 23:14:39 +02:00
|
|
|
|
{
|
2007-08-10 22:16:05 +02:00
|
|
|
|
if (endings.Contains(TrimmedName.Substring(TrimmedName.Length - i)))
|
|
|
|
|
{
|
|
|
|
|
// If there is a digit before the ending (e.g. 3fv) then we will remove
|
|
|
|
|
// the ending (some functions are blacklisted for CLS-Compliance).
|
|
|
|
|
// Otherwise, if there is no digit, but it ends with a 'v', do not remove
|
|
|
|
|
// the 'v' (CLS-Compliance). If no digit and it ends with a (plural) 's',
|
|
|
|
|
// do not remove anything (e.g. glCallLists)
|
|
|
|
|
// TODO: Add better handling for CLS-Compliance on ref ('v') functions.
|
|
|
|
|
if (Char.IsDigit(TrimmedName[TrimmedName.Length - (i + 1)]))
|
|
|
|
|
{
|
|
|
|
|
if (!functionsNotToTrim.IsMatch(Name))
|
|
|
|
|
{
|
|
|
|
|
TrimmedName = TrimmedName.Substring(0, TrimmedName.Length - i);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Function {0} blacklisted from trimming (CLS-Compliance).", Name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (TrimmedName.EndsWith("v"))
|
|
|
|
|
{
|
|
|
|
|
TrimmedName = TrimmedName.Substring(0, TrimmedName.Length - i) + "v";
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2007-08-01 23:14:39 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
#region public override string ToString()
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
public override string ToString()
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
2007-08-01 11:27:57 +02:00
|
|
|
|
|
|
|
|
|
sb.Append(Unsafe ? "unsafe " : "");
|
|
|
|
|
sb.Append(ReturnType);
|
|
|
|
|
sb.Append(" ");
|
|
|
|
|
if (Settings.Compatibility == Settings.Legacy.Tao)
|
|
|
|
|
{
|
|
|
|
|
sb.Append("gl");
|
|
|
|
|
}
|
2007-08-01 23:14:39 +02:00
|
|
|
|
sb.Append(!String.IsNullOrEmpty(TrimmedName) ? TrimmedName : Name);
|
2007-08-01 11:27:57 +02:00
|
|
|
|
sb.Append(Parameters.ToString(true));
|
|
|
|
|
if (Body.Count > 0)
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
2007-08-01 11:27:57 +02:00
|
|
|
|
sb.AppendLine();
|
|
|
|
|
sb.Append(Body.ToString());
|
2007-07-23 02:15:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
#region public Function GetCLSCompliantFunction(Dictionary<string, string> CSTypes)
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
2007-08-02 00:28:54 +02:00
|
|
|
|
public Function GetCLSCompliantFunction()
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
2007-08-01 11:27:57 +02:00
|
|
|
|
Function f = new Function(this);
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
2007-08-02 00:28:54 +02:00
|
|
|
|
bool somethingChanged = false;
|
2007-08-01 11:27:57 +02:00
|
|
|
|
for (int i = 0; i < f.Parameters.Count; i++)
|
|
|
|
|
{
|
2007-08-01 23:14:39 +02:00
|
|
|
|
f.Parameters[i].CurrentType = f.Parameters[i].GetCLSCompliantType();
|
2007-08-02 00:28:54 +02:00
|
|
|
|
if (f.Parameters[i].CurrentType != this.Parameters[i].CurrentType)
|
|
|
|
|
somethingChanged = true;
|
2007-08-01 11:27:57 +02:00
|
|
|
|
}
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
2007-08-02 00:28:54 +02:00
|
|
|
|
if (!somethingChanged)
|
|
|
|
|
return null;
|
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
f.Body.Clear();
|
|
|
|
|
if (!f.NeedsWrapper)
|
2007-07-23 02:15:18 +02:00
|
|
|
|
{
|
2007-08-01 23:14:39 +02:00
|
|
|
|
f.Body.Add((f.ReturnType.CurrentType != "void" ? "return " + this.CallString() : this.CallString()) + ";");
|
2007-08-01 11:27:57 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2007-08-01 23:14:39 +02:00
|
|
|
|
f.Body.AddRange(this.GetBodyWithPins(true));
|
2007-07-23 02:15:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
// The type system cannot differentiate between functions with the same parameters
|
|
|
|
|
// but different return types. Tough, only CLS-Compliant function in that case.
|
|
|
|
|
//f.ReturnType.Type = f.ReturnType.GetCLSCompliantType(CSTypes);
|
|
|
|
|
|
|
|
|
|
return f;
|
2007-07-23 02:15:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region class FunctionBody : List<string>
|
|
|
|
|
|
|
|
|
|
public class FunctionBody : List<string>
|
|
|
|
|
{
|
|
|
|
|
public FunctionBody()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public FunctionBody(FunctionBody fb)
|
|
|
|
|
{
|
|
|
|
|
foreach (string s in fb)
|
|
|
|
|
{
|
|
|
|
|
this.Add(s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
|
|
|
|
if (this.Count == 0)
|
|
|
|
|
return String.Empty;
|
|
|
|
|
|
|
|
|
|
StringBuilder sb = new StringBuilder(this.Count);
|
2007-08-01 11:27:57 +02:00
|
|
|
|
|
|
|
|
|
sb.AppendLine("{");
|
2007-07-23 02:15:18 +02:00
|
|
|
|
foreach (string s in this)
|
|
|
|
|
{
|
2007-08-01 11:27:57 +02:00
|
|
|
|
sb.AppendLine(" " + s);
|
2007-07-23 02:15:18 +02:00
|
|
|
|
}
|
2007-08-01 11:27:57 +02:00
|
|
|
|
sb.AppendLine("}");
|
2007-07-23 02:15:18 +02:00
|
|
|
|
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
2007-08-01 11:27:57 +02:00
|
|
|
|
|
2007-08-01 23:14:39 +02:00
|
|
|
|
#region class FunctionCollection : Dictionary<string, List<Function>>
|
|
|
|
|
|
2007-08-01 11:27:57 +02:00
|
|
|
|
class FunctionCollection : Dictionary<string, List<Function>>
|
|
|
|
|
{
|
|
|
|
|
public void Add(Function f)
|
|
|
|
|
{
|
|
|
|
|
if (!this.ContainsKey(f.Extension))
|
|
|
|
|
{
|
|
|
|
|
this.Add(f.Extension, new List<Function>());
|
|
|
|
|
this[f.Extension].Add(f);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this[f.Extension].Add(f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddRange(IEnumerable<Function> functions)
|
|
|
|
|
{
|
|
|
|
|
foreach (Function f in functions)
|
|
|
|
|
{
|
|
|
|
|
this.Add(f);
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-08-02 00:28:54 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds the function to the collection, if a function with the same
|
|
|
|
|
/// name and parameters doesn't already exist.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="f">The Function to add.</param>
|
|
|
|
|
public void AddChecked(Function f)
|
|
|
|
|
{
|
|
|
|
|
bool exists = false;
|
|
|
|
|
if (Bind.Structures.Function.Wrappers.ContainsKey(f.Extension))
|
|
|
|
|
{
|
|
|
|
|
Function fun = Bind.Structures.Function.Wrappers[f.Extension]
|
|
|
|
|
.Find(delegate(Function target)
|
|
|
|
|
{
|
|
|
|
|
return
|
|
|
|
|
!String.IsNullOrEmpty(target.TrimmedName) &&
|
|
|
|
|
target.TrimmedName == f.TrimmedName &&
|
|
|
|
|
target.Parameters.ToString(true) == f.Parameters.ToString(true);
|
|
|
|
|
});
|
|
|
|
|
if (fun != null)
|
|
|
|
|
{
|
|
|
|
|
exists = true;
|
|
|
|
|
/*Debug.WriteLine("Function redefinition:");
|
|
|
|
|
Debug.WriteLine(fun.ToString());
|
|
|
|
|
Debug.WriteLine(f.ToString());*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!exists)
|
|
|
|
|
Bind.Structures.Function.Wrappers.Add(f);
|
|
|
|
|
}
|
2007-08-01 11:27:57 +02:00
|
|
|
|
}
|
2007-08-01 23:14:39 +02:00
|
|
|
|
|
|
|
|
|
#endregion
|
2007-07-23 02:15:18 +02:00
|
|
|
|
}
|