luka-2012.8.29: src/Language/ObjectiveC/Luka/Extra.hs
module Language.ObjectiveC.Luka.Extra where
import Prelude ()
import Air.Env
import Air.Extra
import Control.Monad ((>=>))
import Language.ObjectiveC.Luka.API
import Language.ObjectiveC.Luka.Prelude
import Language.ObjectiveC.Luka.RunTime
import Foreign.C.Types
import Foreign hiding (void)
import Foreign.LibFFI
import Control.Concurrent.STM.TChan
import Control.Concurrent.STM (atomically)
import Control.Concurrent (forkOS)
import Data.IORef
g_dispatch_main_pool :: TChan (IO ())
g_dispatch_main_pool = purify - newTChanIO
g_dispatch_main_method :: IORef (Maybe String)
g_dispatch_main_method = purify - newIORef Nothing
g_dispatch_main_method_name :: String
g_dispatch_main_method_name = "g_dispatch_main_mailbox"
g_dispatch_main_method_type_encoding :: String
g_dispatch_main_method_type_encoding = "v" + g_dispatch_main_method_name.length.show
type Self = ID
type DispatchMain = Self -> IO ()
foreign import ccall "wrapper" mk_DispatchMain :: DispatchMain -> IO (FunPtr DispatchMain)
m_DispatchMain :: Self -> IO ()
m_DispatchMain self = do
-- puts "m_DispatchMain"
pool_empty <- atomically - isEmptyTChan g_dispatch_main_pool
if pool_empty
then
return ()
else do
io <- atomically - readTChan g_dispatch_main_pool
io
m_DispatchMain self
ns_application_delegate :: IO ID
ns_application_delegate = class_named "NSApplication" >>= msg "sharedApplication" [] >>= msg "delegate" []
-- Must be hooked into NSApplicationDelegate, e.g. [NSApplication sharedApplication].delegate
init_dispatch_main :: IO ()
init_dispatch_main = do
dispatch_main_method <- readIORef g_dispatch_main_method
case dispatch_main_method of
Nothing -> do
application_delegate_class <- ns_application_delegate >>= msg "class" []
-- ns_puts "delegate class is: %@" [argPtr application_delegate_class]
sel <- sel_named g_dispatch_main_method_name
method_implementation <- mk_DispatchMain m_DispatchMain
-- puts - "Inserting method: " + g_dispatch_main_method_name + " with encoding: " + g_dispatch_main_method_type_encoding + " into NSApp.delegate"
class_addMethod application_delegate_class sel method_implementation g_dispatch_main_method_type_encoding
writeIORef g_dispatch_main_method - Just g_dispatch_main_method_name
end
Just _ -> do
puts "g_dispatch_main_method has already been set"
dispatch_main_after :: Double -> IO () -> IO ()
dispatch_main_after after_time io = do
fork_with_pool - do
sleep after_time
-- self.dispatch_main "presentQuestion"
dispatch_main io
fork_with_pool :: IO () -> IO ()
fork_with_pool io = void - forkOS - with_pool io
dispatch_main :: IO () -> IO ()
dispatch_main io = do
dispatch_main_method_name <- readIORef g_dispatch_main_method
case dispatch_main_method_name of
Nothing -> do
puts "ERROR: g_dispatch_main_method not initialized, call init_dispatch_main before using dispatch_main"
return ()
Just method_name -> do
atomically - writeTChan g_dispatch_main_pool io
sel_method_name <- sel_named method_name
ns_application_delegate >>= msg_void "performSelectorOnMainThread:withObject:waitUntilDone:" [argPtr sel_method_name, argPtr nil, argNO]