module Graphics.UI.Qtah.Generator.Types (
QtExport (..),
qtExport,
qtExportToExports,
makeQtEnum,
makeQtEnum',
makeQtEnumAndFlags,
makeQtEnumAndFlags',
makeQtEnumAndFlagsWithOverrides,
ListenerInfo (ListenerInfo),
Signal, SignalGen, makeSignal, makeSignal', makeSignalPrivate,
makeQtClassAndSignals,
signalCName, signalHaskellName, signalClass, signalListenerClass, signalCallback,
) where
import Data.Maybe (mapMaybe)
import qualified Data.Set as S
import Foreign.Hoppy.Generator.Spec (
Callback,
Class,
ClassEntity (CEMethod),
CppEnum,
Scoped (Unscoped),
Export (Export),
Exportable,
ForeignLanguage (Haskell),
Function,
Identifier,
Include,
addReqIncludes,
callbackParams,
callbackReturn,
classAddEntities,
enumAddEntryNameOverrides,
enumSetHasBitOperations,
enumSetUnknownValueEntry,
enumSetValuePrefix,
identifierParts,
idPartBase,
makeAutoEnum,
mkMethod'_,
onParameterType,
stripToGc,
toExtName,
toExport,
)
import Graphics.UI.Qtah.Generator.Common (upperFirst)
import Graphics.UI.Qtah.Generator.Flags (Flags, makeFlags)
data QtExport =
QtExport Export
| QtExportFnRenamed Function String
| QtExportClassAndSignals Class [Signal]
| QtExportEvent Class
| QtExportSceneEvent Class
| QtExportSpecials
qtExport :: Exportable a => a -> QtExport
qtExport :: forall a. Exportable a => a -> QtExport
qtExport = Export -> QtExport
QtExport (Export -> QtExport) -> (a -> Export) -> a -> QtExport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Export
forall a. Exportable a => a -> Export
toExport
qtExportToExports :: QtExport -> [Export]
qtExportToExports :: QtExport -> [Export]
qtExportToExports QtExport
qtExport = case QtExport
qtExport of
QtExport Export
export -> [Export
export]
QtExportFnRenamed Function
fn [Char]
_ -> [Function -> Export
forall a. Exportable a => a -> Export
Export Function
fn]
QtExportClassAndSignals Class
cls [Signal]
_ -> [Class -> Export
forall a. Exportable a => a -> Export
Export Class
cls]
QtExportEvent Class
cls -> [Class -> Export
forall a. Exportable a => a -> Export
Export Class
cls]
QtExportSceneEvent Class
cls -> [Class -> Export
forall a. Exportable a => a -> Export
Export Class
cls]
QtExport
QtExportSpecials -> []
makeQtEnum :: Identifier -> [Include] -> [String] -> CppEnum
makeQtEnum :: Identifier -> [Include] -> [[Char]] -> CppEnum
makeQtEnum Identifier
identifier [Include]
includes [[Char]]
names =
Identifier -> Scoped -> [Include] -> [[Char]] -> CppEnum
makeQtEnum' Identifier
identifier
Scoped
Unscoped
[Include]
includes
[[Char]]
names
makeQtEnum' :: Identifier -> Scoped -> [Include] -> [String] -> CppEnum
makeQtEnum' :: Identifier -> Scoped -> [Include] -> [[Char]] -> CppEnum
makeQtEnum' Identifier
identifier Scoped
scoped [Include]
includes [[Char]]
names =
[Include] -> CppEnum -> CppEnum
forall a. HasReqs a => [Include] -> a -> a
addReqIncludes [Include]
includes (CppEnum -> CppEnum) -> CppEnum -> CppEnum
forall a b. (a -> b) -> a -> b
$
[Char] -> CppEnum -> CppEnum
enumSetValuePrefix [Char]
"" (CppEnum -> CppEnum) -> CppEnum -> CppEnum
forall a b. (a -> b) -> a -> b
$
[Char] -> CppEnum -> CppEnum
forall a. IsEnumUnknownValueEntry a => a -> CppEnum -> CppEnum
enumSetUnknownValueEntry ([Char]
"Unknown" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
niceName) (CppEnum -> CppEnum) -> CppEnum -> CppEnum
forall a b. (a -> b) -> a -> b
$
Bool -> CppEnum -> CppEnum
enumSetHasBitOperations Bool
False (CppEnum -> CppEnum) -> CppEnum -> CppEnum
forall a b. (a -> b) -> a -> b
$
CppEnum -> CppEnum
addEntryOverrides (CppEnum -> CppEnum) -> CppEnum -> CppEnum
forall a b. (a -> b) -> a -> b
$
Identifier -> Maybe ExtName -> Scoped -> [[Char]] -> CppEnum
forall v.
IsAutoEnumValue v =>
Identifier -> Maybe ExtName -> Scoped -> [v] -> CppEnum
makeAutoEnum Identifier
identifier
(ExtName -> Maybe ExtName
forall a. a -> Maybe a
Just (ExtName -> Maybe ExtName) -> ExtName -> Maybe ExtName
forall a b. (a -> b) -> a -> b
$ HasCallStack => [Char] -> ExtName
[Char] -> ExtName
toExtName [Char]
niceName)
Scoped
scoped
[[Char]]
names
where niceName :: [Char]
niceName = (IdPart -> [Char]) -> [IdPart] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap IdPart -> [Char]
idPartBase ([IdPart] -> [Char]) -> [IdPart] -> [Char]
forall a b. (a -> b) -> a -> b
$ Identifier -> [IdPart]
identifierParts Identifier
identifier
addEntryOverrides :: CppEnum -> CppEnum
addEntryOverrides = ForeignLanguage -> [([Char], [Char])] -> CppEnum -> CppEnum
forall v.
IsAutoEnumValue v =>
ForeignLanguage -> [(v, v)] -> CppEnum -> CppEnum
enumAddEntryNameOverrides ForeignLanguage
Haskell [([Char], [Char])]
applicableOverrides
applicableOverrides :: [([Char], [Char])]
applicableOverrides = (([Char], [Char]) -> Bool)
-> [([Char], [Char])] -> [([Char], [Char])]
forall a. (a -> Bool) -> [a] -> [a]
filter (\([Char]
from, [Char]
_) -> [Char] -> Set [Char] -> Bool
forall a. Ord a => a -> Set a -> Bool
S.member [Char]
from Set [Char]
nameSet) [([Char], [Char])]
enumNameOverrides
nameSet :: Set [Char]
nameSet = [[Char]] -> Set [Char]
forall a. Ord a => [a] -> Set a
S.fromList [[Char]]
names
makeQtEnumAndFlags :: Identifier -> String -> [Include] -> [String] -> (CppEnum, Flags)
makeQtEnumAndFlags :: Identifier -> [Char] -> [Include] -> [[Char]] -> (CppEnum, Flags)
makeQtEnumAndFlags Identifier
enumIdentifier [Char]
flagsName [Include]
includes [[Char]]
names =
let enum :: CppEnum
enum = Identifier -> [Include] -> [[Char]] -> CppEnum
makeQtEnum Identifier
enumIdentifier [Include]
includes [[Char]]
names
flags :: Flags
flags = CppEnum -> [Char] -> Flags
makeFlags CppEnum
enum [Char]
flagsName
in (CppEnum
enum, Flags
flags)
makeQtEnumAndFlags' :: Identifier -> String -> Scoped -> [Include] -> [String] -> (CppEnum, Flags)
makeQtEnumAndFlags' :: Identifier
-> [Char] -> Scoped -> [Include] -> [[Char]] -> (CppEnum, Flags)
makeQtEnumAndFlags' Identifier
enumIdentifier [Char]
flagsName Scoped
scoped [Include]
includes [[Char]]
names =
let enum :: CppEnum
enum = Identifier -> Scoped -> [Include] -> [[Char]] -> CppEnum
makeQtEnum' Identifier
enumIdentifier Scoped
scoped [Include]
includes [[Char]]
names
flags :: Flags
flags = CppEnum -> [Char] -> Flags
makeFlags CppEnum
enum [Char]
flagsName
in (CppEnum
enum, Flags
flags)
makeQtEnumAndFlagsWithOverrides ::
Identifier -> String -> [Include] -> [String] -> [(String, String)] -> (CppEnum, Flags)
makeQtEnumAndFlagsWithOverrides :: Identifier
-> [Char]
-> [Include]
-> [[Char]]
-> [([Char], [Char])]
-> (CppEnum, Flags)
makeQtEnumAndFlagsWithOverrides Identifier
enumIdentifier [Char]
flagsName [Include]
includes [[Char]]
names [([Char], [Char])]
nameOverrides =
let enum :: CppEnum
enum = ForeignLanguage -> [([Char], [Char])] -> CppEnum -> CppEnum
forall v.
IsAutoEnumValue v =>
ForeignLanguage -> [(v, v)] -> CppEnum -> CppEnum
enumAddEntryNameOverrides ForeignLanguage
Haskell [([Char], [Char])]
nameOverrides (CppEnum -> CppEnum) -> CppEnum -> CppEnum
forall a b. (a -> b) -> a -> b
$
Identifier -> [Include] -> [[Char]] -> CppEnum
makeQtEnum Identifier
enumIdentifier [Include]
includes [[Char]]
names
flags :: Flags
flags = CppEnum -> [Char] -> Flags
makeFlags CppEnum
enum [Char]
flagsName
in (CppEnum
enum, Flags
flags)
enumNameOverrides :: [(String, String)]
enumNameOverrides :: [([Char], [Char])]
enumNameOverrides =
[ ([Char]
"Type", [Char]
"Typ")
]
data Signal = Signal
{ Signal -> Class
signalClass :: Class
, Signal -> [Char]
signalCName :: String
, Signal -> [Char]
signalHaskellName :: String
, Signal -> Class
signalListenerClass :: Class
, Signal -> Callback
signalCallback :: Callback
, Signal -> Bool
signalPrivate :: Bool
}
type SignalGen = Class -> Signal
data ListenerInfo = ListenerInfo Class Callback
makeSignal :: String
-> ListenerInfo
-> SignalGen
makeSignal :: [Char] -> ListenerInfo -> SignalGen
makeSignal [Char]
cName (ListenerInfo Class
listenerClass Callback
callback) Class
cls =
Class -> [Char] -> [Char] -> Class -> Callback -> Bool -> Signal
Signal Class
cls [Char]
cName [Char]
cName Class
listenerClass Callback
callback Bool
False
makeSignal' :: String
-> String
-> ListenerInfo
-> SignalGen
makeSignal' :: [Char] -> [Char] -> ListenerInfo -> SignalGen
makeSignal' [Char]
cName [Char]
hsName (ListenerInfo Class
listenerClass Callback
callback) Class
cls =
Class -> [Char] -> [Char] -> Class -> Callback -> Bool -> Signal
Signal Class
cls [Char]
cName [Char]
hsName Class
listenerClass Callback
callback Bool
False
makeSignalPrivate ::
String
-> ListenerInfo
-> SignalGen
makeSignalPrivate :: [Char] -> ListenerInfo -> SignalGen
makeSignalPrivate [Char]
cName (ListenerInfo Class
listenerClass Callback
callback) Class
cls =
Class -> [Char] -> [Char] -> Class -> Callback -> Bool -> Signal
Signal Class
cls [Char]
cName [Char]
cName Class
listenerClass Callback
callback Bool
True
makeQtClassAndSignals :: [SignalGen] -> Class -> (Class, [Signal])
makeQtClassAndSignals :: [SignalGen] -> Class -> (Class, [Signal])
makeQtClassAndSignals [SignalGen]
sigs Class
cls = (Class
cls', [Signal]
sigs')
where cls' :: Class
cls' = ([ClassEntity] -> Class -> Class)
-> Class -> [ClassEntity] -> Class
forall a b c. (a -> b -> c) -> b -> a -> c
flip [ClassEntity] -> Class -> Class
classAddEntities Class
cls ([ClassEntity] -> Class) -> [ClassEntity] -> Class
forall a b. (a -> b) -> a -> b
$ ((Signal -> Maybe ClassEntity) -> [Signal] -> [ClassEntity])
-> [Signal] -> (Signal -> Maybe ClassEntity) -> [ClassEntity]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Signal -> Maybe ClassEntity) -> [Signal] -> [ClassEntity]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe [Signal]
sigs' ((Signal -> Maybe ClassEntity) -> [ClassEntity])
-> (Signal -> Maybe ClassEntity) -> [ClassEntity]
forall a b. (a -> b) -> a -> b
$ \Signal
sig ->
if Signal -> Bool
signalPrivate Signal
sig
then Maybe ClassEntity
forall a. Maybe a
Nothing
else ClassEntity -> Maybe ClassEntity
forall a. a -> Maybe a
Just (ClassEntity -> Maybe ClassEntity)
-> ClassEntity -> Maybe ClassEntity
forall a b. (a -> b) -> a -> b
$
let cName :: [Char]
cName = Signal -> [Char]
signalCName Signal
sig
hsName :: [Char]
hsName = [Char]
"emit" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
upperFirst (Signal -> [Char]
signalHaskellName Signal
sig)
callback :: Callback
callback = Signal -> Callback
signalCallback Signal
sig
params :: [Parameter]
params = (Parameter -> Parameter) -> [Parameter] -> [Parameter]
forall a b. (a -> b) -> [a] -> [b]
map ((Type -> Type) -> Parameter -> Parameter
onParameterType Type -> Type
stripToGc) ([Parameter] -> [Parameter]) -> [Parameter] -> [Parameter]
forall a b. (a -> b) -> a -> b
$ Callback -> [Parameter]
callbackParams Callback
callback
retType :: Type
retType = Callback -> Type
callbackReturn Callback
callback
in Method -> ClassEntity
CEMethod (Method -> ClassEntity) -> Method -> ClassEntity
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Parameter] -> Type -> Method
forall name p.
(IsFnName [Char] name, IsParameter p) =>
name -> [Char] -> [p] -> Type -> Method
mkMethod'_ [Char]
cName [Char]
hsName [Parameter]
params Type
retType
sigs' :: [Signal]
sigs' = (SignalGen -> Signal) -> [SignalGen] -> [Signal]
forall a b. (a -> b) -> [a] -> [b]
map (SignalGen -> SignalGen
forall a b. (a -> b) -> a -> b
$ Class
cls') [SignalGen]
sigs