Skip to content
This repository has been archived by the owner on Dec 5, 2019. It is now read-only.

Commit

Permalink
Renamed exportAccessor to exportAccessors, and removed the first stri…
Browse files Browse the repository at this point in the history
…ng argument (specifying the Objective-C function name), which can be inferred instead
  • Loading branch information
jspahrsummers committed Aug 6, 2012
1 parent 7ec2086 commit 880c1ea
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 23 deletions.
6 changes: 3 additions & 3 deletions Demos/PhotoUploader/PhotoUploader/User.hs
Expand Up @@ -50,6 +50,6 @@ decodeUser d = do

exportFunc "User_initWithData" [t| UnsafeId -> IO (MaybePtr User) |] 'decodeUser

exportAccessor "User_fullName" ''User 'fullName
exportAccessor "User_username" ''User 'username
exportAccessor "User_photoURL" ''User 'photoURL
exportAccessors ''User 'fullName
exportAccessors ''User 'username
exportAccessors ''User 'photoURL
56 changes: 36 additions & 20 deletions ObjectiveHaskell/Model.hs
Expand Up @@ -2,7 +2,7 @@

-- | Tools for building a model layer in Haskell that can interoperate with Objective-C
module ObjectiveHaskell.Model (
MaybePtr, exportAccessor
MaybePtr, exportAccessors
) where

import Control.Monad
Expand All @@ -12,32 +12,48 @@ import ObjectiveHaskell.MsgSend
import ObjectiveHaskell.ObjC
import ObjectiveHaskell.THUtils

-- | A pointer to a Maybe value that can be passed to and from Objective-C safely.
-- | A pointer to a 'Maybe' value that can be passed to and from Objective-C safely.
-- | This can be used to represent model data that may or may not exist.
type MaybePtr a = StablePtr (Maybe a)

-- | Defines a function, callable from Objective-C, which applies a Haskell function to a value within a 'MaybePtr',
-- | then converts the result into an Objective-C object.
-- | Defines two functions, callable from Objective-C, which get and set a field on a value within a 'MaybePtr'.
-- |
-- | If the 'MaybePtr' contains 'Nothing', the exported function will return @nil@.
exportAccessor
:: String -- ^ The name of the function to export to Objective-C.
-> Name -- ^ The name of the type of value stored in the 'MaybePtr'.
-> Name -- ^ The name of the Haskell accessor function to apply to the value, returning a Bridged value.
-> Q [Dec] -- ^ Top-level declarations to generate and export the accessor.

exportAccessor str valueTypeName accessorName = do
let accessor = varE accessorName
-- | For a type @Car@ and a field @model@, the following functions will be generated and exported to Objective-C:
-- |
-- | * A getter @Car_model()@ which accepts a 'MaybePtr' @Car@, reads the @model@ field and converts the result into an
-- | Objective-C object. If the 'MaybePtr' contains 'Nothing', @nil@ is returned.
-- | * A setter @Car_setModel()@ which accepts a 'MaybePtr' @Car@ and a new value for the @model@ field, and returns a
-- | new 'MaybePtr' @Car@, where the field in the @Car@ value has been set to the given value.
exportAccessors
:: Name -- ^ The name of the type of value stored in the 'MaybePtr'.
-> Name -- ^ The name of the record field to access or set in the value, which should hold a 'Bridged' value.
-> Q [Dec] -- ^ Top-level declarations to generate and export the accessors.

exportAccessors typeName field = do
let getter = (nameBase typeName) ++ "_" ++ (nameBase field)
t = conT typeName

-- TODO: export setter
exportGetter getter t field

exportGetter
:: String -- ^ The name of the function to export.
-> Q Type -- ^ The type of value stored in the 'MaybePtr'.
-> Name -- ^ The name of the record field to access.
-> Q [Dec]

exportGetter objcName t field = do
hsName <- newName $ "_hs_" ++ objcName
ft <- [t| MaybePtr $t -> IO UnsafeId |]

let getter = varE field
arg = mkName "ptr"
valCon = conT valueTypeName

name <- newName $ "_hs_" ++ str
ft <- [t| MaybePtr $valCon -> IO UnsafeId |]
decl = ForeignD $ ExportF CCall objcName hsName ft

let externDecl = ForeignD $ ExportF CCall str name ft
funcDef <- singleClauseFunc name [arg] [| do
def <- singleClauseFunc hsName [arg] [| do
ptr <- deRefStablePtr $(varE arg)
obj <- maybe nil (toObjC . $accessor) ptr
obj <- maybe nil (toObjC . $getter) ptr
autorelease obj |]

return [externDecl, funcDef]
return [decl, def]

0 comments on commit 880c1ea

Please sign in to comment.