Opentk/Source/Bind/ES/ESGenerator.cs
the_fiddler 137818d10c Moved enum, constant, delegate and function transformations to EnumProcessor and FuncProcessor respectively.
Removed global enum, delegate and function collections.
Simplified loading process and removed global Initialize() methods.
Read "count" attributes for function parameters in overrides.xml.
Disabled wgl/glx/glu generators.
Removed large amounts of stale code.
2010-10-13 21:41:06 +00:00

197 lines
8.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.XPath;
using Bind.GL2;
using Bind.Structures;
using Delegate=Bind.Structures.Delegate;
using Enum=Bind.Structures.Enum;
namespace Bind.ES
{
class ESGenerator : Generator
{
public ESGenerator(string nsName, string dirName)
{
if (String.IsNullOrEmpty(nsName))
throw new ArgumentNullException("nsName");
if (dirName == null)
dirName = nsName;
glTypemap = "GL2/gl.tm";
csTypemap = "csharp.tm";
enumSpec = dirName + "/signatures.xml";
enumSpecExt = String.Empty;
glSpec = dirName + "/signatures.xml";
glSpecExt = String.Empty;
functionOverridesFile = dirName + "/overrides.xml";
importsFile = "Core.cs";
delegatesFile = "Delegates.cs";
enumsFile = "Enums.cs";
wrappersFile = "ES.cs";
Settings.ImportsClass = "Core";
Settings.DelegatesClass = "Delegates";
Settings.OutputClass = "GL";
Settings.OutputNamespace = "OpenTK.Graphics." + nsName;
Settings.OutputPath = Path.Combine(Settings.OutputPath, dirName);
}
public override DelegateCollection ReadDelegates(StreamReader specFile)
{
DelegateCollection delegates = new DelegateCollection();
XPathDocument specs = new XPathDocument(specFile);
XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile)));
foreach (XPathNavigator nav in new XPathNavigator[] {
specs.CreateNavigator().SelectSingleNode("/signatures"),
overrides.CreateNavigator().SelectSingleNode("/overrides/add") })
{
if (nav != null)
{
foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty))
{
var name = node.GetAttribute("name", String.Empty);
// Check whether we are adding to an existing delegate or creating a new one.
Delegate d = null;
if (delegates.ContainsKey(name))
{
d = delegates[name];
}
else
{
d = new Delegate();
d.Name = name;
d.Version = node.GetAttribute("version", String.Empty);
d.Category = node.GetAttribute("category", String.Empty);
}
foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element))
{
switch (param.Name)
{
case "returns":
d.ReturnType.CurrentType = param.GetAttribute("type", String.Empty);
break;
case "param":
Parameter p = new Parameter();
p.CurrentType = param.GetAttribute("type", String.Empty);
p.Name = param.GetAttribute("name", String.Empty);
string element_count = param.GetAttribute("elementcount", String.Empty);
if (String.IsNullOrEmpty(element_count))
element_count = param.GetAttribute("count", String.Empty);
if (!String.IsNullOrEmpty(element_count))
p.ElementCount = Int32.Parse(element_count);
p.Flow = Parameter.GetFlowDirection(param.GetAttribute("flow", String.Empty));
d.Parameters.Add(p);
break;
}
}
//d.Translate(overrides);
delegates.Add(d);
}
}
}
return delegates;
}
public override Dictionary<string, string> ReadTypeMap(StreamReader specFile)
{
return base.ReadTypeMap(specFile);
}
public override Dictionary<string, string> ReadCSTypeMap(StreamReader specFile)
{
return base.ReadCSTypeMap(specFile);
}
public override EnumCollection ReadEnums(StreamReader specFile)
{
// First, read all enum definitions from spec and override file.
// Afterwards, read all token/enum overrides from overrides file.
// Every single enum is merged into
EnumCollection enums = new EnumCollection();
Enum all = new Enum() { Name = Settings.CompleteEnumName };
XPathDocument specs = new XPathDocument(specFile);
XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile)));
foreach (XPathNavigator nav in new XPathNavigator[] {
specs.CreateNavigator().SelectSingleNode("/signatures"),
overrides.CreateNavigator().SelectSingleNode("/overrides/add") })
{
if (nav != null)
{
foreach (XPathNavigator node in nav.SelectChildren("enum", String.Empty))
{
Enum e = new Enum()
{
Name = node.GetAttribute("name", String.Empty),
Type = node.GetAttribute("type", String.Empty)
};
if (String.IsNullOrEmpty(e.Name))
throw new InvalidOperationException(String.Format("Empty name for enum element {0}", node.ToString()));
foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element))
{
Constant c = null;
switch (param.Name)
{
case "token":
c = new Constant
{
Name = param.GetAttribute("name", String.Empty),
Value = param.GetAttribute("value", String.Empty)
};
break;
case "use":
c = new Constant
{
Name = param.GetAttribute("token", String.Empty),
Reference = param.GetAttribute("enum", String.Empty),
Value = param.GetAttribute("token", String.Empty),
};
break;
default:
throw new NotSupportedException();
}
Utilities.Merge(all, c);
try
{
if (!e.ConstantCollection.ContainsKey(c.Name))
{
e.ConstantCollection.Add(c.Name, c);
}
else if (e.ConstantCollection[c.Name].Value != c.Value)
{
Console.WriteLine("[Warning] Conflicting token {0}.{1} with value {2} != {3}",
e.Name, c.Name, e.ConstantCollection[c.Name].Value, c.Value);
}
}
catch (ArgumentException ex)
{
Console.WriteLine("[Warning] Failed to add constant {0} to enum {1}: {2}", c.Name, e.Name, ex.Message);
}
}
Utilities.Merge(enums, e);
}
}
}
Utilities.Merge(enums, all);
return enums;
}
}
}