private static IEnumerable <(string, IEnumerable <Interface>, IEnumerable <(FunctionSignature, StringBuilder)>)> GetWithoutEnums(IEnumerable <FunctionSignature> fns) { // extension or core, (interface name, functions) var projects = new Dictionary <string, Dictionary <string, List <FunctionSignature> > >(); foreach (var function in fns) { foreach (var category in function.Categories) { // check that the root project exists if (!projects.ContainsKey("Core")) { projects.Add ( "Core", new Dictionary <string, List <FunctionSignature> >() ); } // check that the extension project exists, if applicable if (function.Extension != "Core" && !projects.ContainsKey(category)) { projects.Add ( category, new Dictionary <string, List <FunctionSignature> >() ); } // check that the interface exists if (!projects[function.Extension == "Core" ? "Core" : category] .ContainsKey("I" + NativeIdentifierTranslator.TranslateIdentifierName(category))) { projects[function.Extension == "Core" ? "Core" : category] .Add ( "I" + NativeIdentifierTranslator.TranslateIdentifierName(category), new List <FunctionSignature>() ); } // add the function to the interface projects[function.Extension == "Core" ? "Core" : category][ "I" + NativeIdentifierTranslator.TranslateIdentifierName(category)] .Add(function); } } return(projects.Select ( x => ( x.Key, x.Value.Select(y => new Interface(y.Key, y.Value)), x.Value.SelectMany(y => OverloadBaker.GetOverloads(y.Value)) ) )); }
/// <summary> /// Asynchronously generates bindings for the API described by the given <see cref="IGeneratorSettings"/> /// object. /// /// Broadly, this takes the following steps: /// 1) Load the base API. /// 2) Bake overrides into the API /// 3) Bake Documentation into the API /// 4) Create mappings between OpenGL types and C# types /// 5) Apply the mappings to the API /// 6) Bake convenience overloads into the API (adding unsafe, etc) /// 7) Write the bindings to the files. /// /// </summary> /// <param name="generatorSettings">The settings describing the API.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> private static async Task GenerateBindingsAsync([NotNull] IGeneratorSettings generatorSettings) { var signaturePath = Path.Combine(Arguments.InputPath, generatorSettings.SpecificationFile); if (!_cachedProfiles.TryGetValue(signaturePath, out var profiles)) { profiles = SignatureReader.GetAvailableProfiles(signaturePath).ToList(); _cachedProfiles.TryAdd(signaturePath, profiles); } var profileOverrides = OverrideReader .GetProfileOverrides(generatorSettings.OverrideFiles.ToArray()) .ToList(); var baker = new ProfileBaker(profiles, profileOverrides); var bakedProfile = baker.BakeProfile ( generatorSettings.ProfileName, generatorSettings.Versions, generatorSettings.BaseProfileName ); var documentationPath = Path.Combine ( Arguments.DocumentationPath, generatorSettings.SpecificationDocumentationPath ); var docs = DocumentationReader.ReadProfileDocumentation(documentationPath); var bakedDocs = new DocumentationBaker(bakedProfile).BakeDocumentation(docs); var languageTypemapPath = Path.Combine(Arguments.InputPath, generatorSettings.LanguageTypemap); if (!_cachedTypemaps.TryGetValue(languageTypemapPath, out var languageTypemap)) { using (var fs = File.OpenRead(languageTypemapPath)) { languageTypemap = new TypemapReader().ReadTypemap(fs); _cachedTypemaps.TryAdd(languageTypemapPath, languageTypemap); } } var apiTypemapPath = Path.Combine(Arguments.InputPath, generatorSettings.APITypemap); if (!_cachedTypemaps.TryGetValue(apiTypemapPath, out var apiTypemap)) { using (var fs = File.OpenRead(apiTypemapPath)) { apiTypemap = new TypemapReader().ReadTypemap(fs); _cachedTypemaps.TryAdd(apiTypemapPath, apiTypemap); } } var bakedMap = TypemapBaker.BakeTypemaps(apiTypemap, languageTypemap); var mapper = new ProfileMapper(bakedMap); var mappedProfile = mapper.Map(bakedProfile); var overloadedProfile = OverloadBaker.BakeOverloads(mappedProfile); var bindingsWriter = new BindingWriter(generatorSettings, overloadedProfile, bakedDocs); await bindingsWriter.WriteBindingsAsync(); }