ghcjs / ghcjs-base

base library for GHCJS for JavaScript interaction and marshalling, used by higher level libraries like JSC
MIT License
45 stars 67 forks source link

Add multi argument callback helpers #76

Open hamishmack opened 7 years ago

hamishmack commented 7 years ago

We should add something like this to GHCJS.Foreign.Callback (based on function from jsaddle):

syncCallbackMulti :: OnBlocked -> (JSVal -> [JSVal] -> IO ())
                               -> IO (Callback (JSVal -> JSVal -> IO ()), Object)
syncCallbackMulti onBlocked f = do
    callback <- syncCallback2 onBlocked $ \this args -> do
        rargs <- Array.toListIO (coerce args)
        f this rargs
    (callback,) <$> makeMultiArgCallback callback

foreign import javascript unsafe "$r = function () { $1(this, arguments); }"
    makeMultiArgCallback :: Callback (JSVal -> JSVal -> IO ()) -> IO Object

Returns two values. The first is just for use with releaseCallback, the second is to pass on to JavaScript. We should change it to something more meaningful than Object.

hamishmack commented 7 years ago

Not sure if we need the this argument (I have never used it in the jsaddle version), so we could probably get by with:

type CallbackMulti = Callback ([JSVal] -> IO ())

syncCallbackMulti :: OnBlocked -> ([JSVal] -> IO ())
                               -> IO (Callback (JSVal -> IO ()), CallbackMulti)
syncCallbackMulti onBlocked f = do
    callback <- syncCallback1 onBlocked $ \args ->
        Array.toListIO (coerce args) >>= f
    (callback,) <$> makeMultiArgCallback callback

foreign import javascript unsafe "$r = function () { $1(arguments); }"
    makeMultiArgCallback :: Callback (JSVal -> IO ()) -> IO CallbackMulti
crocket commented 7 years ago

I suggest documenting syncCallbackMulti, asyncCallbackMulti, and syncCallbackMulti' on README.

crocket commented 7 years ago

Is a polyvariadic function going to help here? I don't know much about polyvariadic functions.

crocket commented 7 years ago

@luite This is useful because http://electron.atom.io/docs/api/app/#event-certificate-error requires a callback of 6 arguments. Currently, ghcjs-base cannot handle event-certificate-error.