Skip to content

Commit 5e45ce2

Browse files
committed
Generate toplevel module, too. Various cleanups.
1 parent db761dc commit 5e45ce2

File tree

1 file changed

+61
-29
lines changed

1 file changed

+61
-29
lines changed

RegistryProcessor/src/Main.hs

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,32 @@ main = do
2828
let extModules = extensionModules api registry
2929
CM.forM_ extModules printExtensionModule
3030
printReExports extModules
31-
CM.forM_ ["1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "2.0", "2.1"] $ \v ->
32-
printFeature api (read v) (ProfileName "version") registry
33-
CM.forM_ ["3.0", "3.1", "3.2", "3.3", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5"] $ \v ->
34-
CM.forM_ [ProfileName "core", ProfileName "compatibility"] $ \p ->
35-
printFeature api (read v) p registry
36-
37-
printFeature :: API -> Version -> ProfileName -> Registry -> IO ()
38-
printFeature api version profile registry = do
39-
let relName = capitalize (unProfileName profile) ++
40-
show (major version) ++ show (minor version)
41-
printExtension [relName] [] $ fixedReplay api version profile registry
31+
CM.forM_ openGLVersions $ \v ->
32+
CM.forM_ (supportedProfiles v) $ \p ->
33+
printFeature api v p registry
34+
printTopLevel extModules
35+
36+
openGLVersions :: [Version]
37+
openGLVersions = map read $ [
38+
"1.0", "1.1", "1.2", "1.3", "1.4", "1.5",
39+
"2.0", "2.1",
40+
"3.0", "3.1", "3.2", "3.3",
41+
"4.0", "4.1", "4.2", "4.3", "4.4", "4.5" ]
42+
43+
supportedProfiles :: Version -> [Maybe ProfileName]
44+
supportedProfiles v
45+
| major v < 3 = [ Nothing ]
46+
| otherwise = map (Just . ProfileName) [ "core", "compatibility" ]
47+
48+
printFeature :: API -> Version -> Maybe ProfileName -> Registry -> IO ()
49+
printFeature api version mbProfile registry = do
50+
printExtension [featureName version mbProfile] [] $
51+
fixedReplay api version mbProfile registry
52+
53+
featureName :: Version -> Maybe ProfileName -> String
54+
featureName version mbProfile =
55+
maybe "Version" (capitalize . unProfileName) mbProfile ++
56+
show (major version) ++ show (minor version)
4257

4358
printTokens :: API -> Registry -> IO ()
4459
printTokens api registry = do
@@ -164,12 +179,10 @@ mangleExtensionName extName = extName {
164179

165180
extensionModules :: API -> Registry -> [(ExtensionName, ExtensionName, ([TypeName], [Enum'], [Command]))]
166181
extensionModules api registry =
167-
[ (extName, mangledExtName, executeModifications api prof registry mods)
182+
[ (extName, mangledExtName, executeModifications api mbProfile registry mods)
168183
| (extName, mods) <- supportedExtensions api registry
169-
, let profDep = any isProfileDependent mods
170-
, prof <- map ProfileName $ [ "core" ] ++ if profDep then [ "compatibility" ] else []
171-
, let mbProfileName = if profDep then Just prof else Nothing
172-
, let mangledExtName = mangleExtensionName (extendWithProfile extName mbProfileName)
184+
, mbProfile <- supportedProfiles $ (if any isProfileDependent mods then last else head) openGLVersions
185+
, let mangledExtName = mangleExtensionName (extendWithProfile extName mbProfile)
173186
]
174187
where isProfileDependent :: Modification -> Bool
175188
isProfileDependent = DM.isJust . modificationProfile
@@ -275,6 +288,25 @@ printExtension moduleNameSuffix comment (ts, es, cs) =
275288
CM.unless (null cs) $
276289
SI.hPutStrLn h $ "import " ++ moduleNameFor ["Functions"]
277290

291+
printTopLevel :: [(ExtensionName, ExtensionName, ([TypeName], [Enum'], [Command]))] -> IO ()
292+
printTopLevel extModules = do
293+
let mangledCategories = sortUnique [ extensionNameCategory mangledExtName
294+
| (_, mangledExtName, _) <- extModules ]
295+
lastComp = featureName (last openGLVersions) (Just (ProfileName "compatibility"))
296+
moduleNames = [ moduleNameFor [c] | c <- [ lastComp, "GetProcAddress" ] ++ mangledCategories ]
297+
comment = [ "A convenience module, combining the latest OpenGL compatibility profile plus"
298+
, "all extensions." ]
299+
startModule [] Nothing comment $ \moduleName h -> do
300+
SI.hPutStrLn h $ "module "++ moduleName ++ " ("
301+
SI.hPutStrLn h $ separate (\m -> "module " ++ m) moduleNames
302+
SI.hPutStrLn h ") where"
303+
SI.hPutStrLn h ""
304+
CM.forM_ moduleNames $ \moduleName ->
305+
SI.hPutStrLn h $ "import " ++ moduleName
306+
307+
sortUnique :: Ord a => [a] -> [a]
308+
sortUnique = S.toList . S.fromList
309+
278310
startModule :: [String] -> Maybe String -> [String] -> (String -> SI.Handle -> IO ()) -> IO ()
279311
startModule moduleNameSuffix mbPragma comments action = do
280312
let path = modulePathFor moduleNameSuffix
@@ -315,12 +347,12 @@ printModuleHeader h mbPragma moduleName comments = do
315347
-- Annoyingly enough, the OpenGL registry doesn't contain any enums for
316348
-- OpenGL 1.0, so let's just use the OpenGL 1.1 ones. Furthermore, features
317349
-- don't explicitly list the types referenced by commands, so we add them.
318-
fixedReplay :: API -> Version -> ProfileName -> Registry -> ([TypeName], [Enum'], [Command])
319-
fixedReplay api version profile registry
350+
fixedReplay :: API -> Version -> Maybe ProfileName -> Registry -> ([TypeName], [Enum'], [Command])
351+
fixedReplay api version mbProfile registry
320352
| api == API "gl" && version == read "1.0" = (ts', es11, cs)
321353
| otherwise = (ts', es, cs)
322-
where (ts, es, cs) = replay api version profile registry
323-
(_, es11, _) = replay api (read "1.1") profile registry
354+
where (ts, es, cs) = replay api version mbProfile registry
355+
(_, es11, _) = replay api (read "1.1") mbProfile registry
324356
ts' = S.toList . addFuncsAndMakes . S.unions $ S.fromList ts : map referencedTypes cs
325357

326358
-- For debug callbacks, we want to export the Haskell types and their creators, too.
@@ -338,31 +370,31 @@ addFuncsAndMakes =
338370

339371
-- Here is the heart of the feature construction logic: Chronologically replay
340372
-- the whole version history for the given API/version/profile triple.
341-
replay :: API -> Version -> ProfileName -> Registry -> ([TypeName], [Enum'], [Command])
342-
replay api version profile registry =
343-
executeModifications api profile registry modifications
373+
replay :: API -> Version -> Maybe ProfileName -> Registry -> ([TypeName], [Enum'], [Command])
374+
replay api version mbProfile registry =
375+
executeModifications api mbProfile registry modifications
344376
where modifications = history >>= flip lookup' (features registry)
345377
history = L.sort [ key
346378
| key@(a,v) <- M.keys (features registry)
347379
, a == api
348380
, v <= version ]
349381

350-
executeModifications :: API -> ProfileName -> Registry -> [Modification] -> ([TypeName], [Enum'], [Command])
351-
executeModifications api profile registry modifications = (ts, es, cs)
382+
executeModifications :: API -> Maybe ProfileName -> Registry -> [Modification] -> ([TypeName], [Enum'], [Command])
383+
executeModifications api mbProfile registry modifications = (ts, es, cs)
352384
where ts = [ n | TypeElement n <- lst ]
353385
es = [ e | EnumElement n <- lst
354386
, e <- lookup' n (enums registry)
355387
, api `matches` enumAPI e ]
356388
cs = [ lookup' n (commands registry) | CommandElement n <- lst ]
357-
lst = S.toList $ interfaceElementsFor profile modifications
389+
lst = S.toList $ interfaceElementsFor mbProfile modifications
358390

359-
interfaceElementsFor :: ProfileName -> [Modification] -> S.Set InterfaceElement
360-
interfaceElementsFor profile modifications =
391+
interfaceElementsFor :: Maybe ProfileName -> [Modification] -> S.Set InterfaceElement
392+
interfaceElementsFor mbProfile modifications =
361393
foldl (flip ($)) S.empty modificationsFor
362394
where modificationsFor =
363395
[ op (modificationKind m) ie
364396
| m <- modifications
365-
, profile `matches` modificationProfile m
397+
, maybe True (`matches` modificationProfile m) mbProfile
366398
, ie <- modificationInterfaceElements m ]
367399
op Require = S.insert
368400
op Remove = S.delete

0 commit comments

Comments
 (0)