move generics to a different directory, add task sending framework
[mTask.git] / miTask.icl
index d84121a..738f8c2 100644 (file)
@@ -8,6 +8,8 @@ import mTask
 
 from Text import class Text(startsWith,concat,split,join), instance Text String
 
+import qualified Data.Map as DM
+
 from Data.Func import $
 import Data.Tuple
 import Data.List
@@ -20,25 +22,44 @@ import iTasks._Framework.TaskServer
 import iTasks._Framework.IWorld
 import iTasks._Framework.Store
 
+
 import TTY
 
 derive class iTask Queue, TTYSettings, Parity, BaudRate, ByteSize
 derive class iTask MTaskMSGRecv, MTaskMSGSend, SerTCP, UserLED
 
-derive class iTask MTaskDevice
-
-:: SerTCP = Serial | TCP
 :: *Resource | TTYd !*TTY
+:: Channels :== ([MTaskMSGRecv], [MTaskMSGSend], Bool)
+
+:: SerTCP = SerialDevice | TCPDevice
 :: MTaskDevice = {
-               deviceConnected :: Maybe (Shared ([String], [String], Bool)),
+               deviceConnected :: Maybe String,
                deviceName :: String,
-               deviceSettings :: Either (String, Int) (String, TTYSettings)
+               deviceTasks :: [(String, Int)]
+       }
+:: MTaskShare = {
+               identifier :: Int,
+               realShare :: String
        }
 
 Start :: *World -> *World
 Start world = startEngine (mTaskManager
        >>* [OnAction (Action "Shutdown") (always $ shutDown)]) world
-//Start world = startEngine mTaskTask world
+
+memoryShare :: String a -> Shared a | iTask a
+memoryShare s d = sdsFocus s $ memoryStore "" $ Just d
+
+deviceStore :: Shared [MTaskDevice]
+deviceStore = memoryShare "mTaskDevices" []
+
+sdsStore :: Shared [MTaskShare]
+sdsStore = memoryShare "mTaskShares" []
+
+bcStateStore :: Shared BCState
+bcStateStore = memoryShare "mTaskBCState" zero
+
+mTaskTaskStore :: Shared [String]
+mTaskTaskStore = memoryShare "mTaskTasks" ["ledder", "ledon", "ledoff"]
 
 bc :: Main (ByteCode () Stmt)
 bc = sds \x=1 In sds \pinnetje=1 In {main =
@@ -64,38 +85,106 @@ bc2 d = {main = ledOn d}
 bc3 :: UserLED -> Main (ByteCode () Stmt)
 bc3 d = {main = ledOff d}
 
-:: MTaskDeviceStatus = {connected :: Bool, name :: String}
-derive class iTask MTaskDeviceStatus
+:: MTaskDeviceStatus = {connected :: Bool, name :: String, tasks :: [(String, Int)]}
+derive class iTask MTaskDeviceStatus, MTaskDevice, MTaskShare, BCState
 
 mTaskManager :: Task ()
-mTaskManager = forever (addDevice >>= \d->upd (\l->[d:l]) deviceStore)
-       ||- viewSharedInformation "Devices" [ViewAs deviceviewer] deviceStore
-       ||- whileUnchanged deviceStore (\m->if (isEmpty m)
-                       (viewInformation "No devices yet" [] "" @! ()) (connectDevice m)) @! ()
-//             )
+mTaskManager = anyTask 
+               [ viewmTasks @! ()
+               , viewShares
+               , whileUnchanged deviceStore viewDevices
+               ] <<@ ApplyLayout layout
        where
-               connectDevice :: [MTaskDevice] -> Task ()
-               connectDevice [] = treturn ()
-               connectDevice [d:ds] = (case d.deviceConnected of
-                       (Just sh) = viewSharedInformation "Buffers" [] sh @! ()
-                       Nothing = viewInformation ("Connect " +++ d.deviceName) [] "" >>* [
-                               OnAction (Action "connect") (const $ Just $ connect d)]
-                       ) -|| connectDevice ds
-
-               connect :: MTaskDevice -> Task ()
-               connect d=:{deviceSettings} = withShared ([], [], False) $ \ch->
-                       case deviceSettings of
-                               Left (host, port) = syncNetworkChannel host port ch
-                               Right (dev, sett) = syncSerialChannel dev sett ch
-                       ||- viewSharedInformation "Buffers" [] ch @! ()
+               isValue (Value _ _) = True
+               isValue _                       = False
+
+               viewmTasks = listmTasks
+                       >&^ \sh->whileUnchanged sh $ \mi->case mi of
+                               Nothing = viewInformation "No task selected" [] ()
+                               Just mTaskTask = get deviceStore
+                                       >>= \devices->case devices of
+                                               [] = viewInformation "No devices yet" [] ()
+                                               ds = sendmTask mTaskTask ds @! ()
+                       where
+                               listmTasks :: Task String
+                               listmTasks = enterChoiceWithShared "Available mTasks" [ChooseFromList id] mTaskTaskStore
+
+                               sendmTask mTaskId ds = enterChoice "Choose Device" [ChooseFromDropdown (\t->t.deviceName)] ds <<@ Title mTaskId
+                                       >>* [OnAction (Action "Send") (withValue $ sendToDevice mTaskId)]
+
+                               sendToDevice mTask device = Just $ viewInformation "" [] device
+                                       
+                                       
+
+               layout = sequenceLayouts
+                       [ arrangeWithSideBar 0 LeftSide 260 True
+                       , arrangeSplit Vertical True
+                       ]
+
+               viewShares :: Task ()
+               viewShares = forever $
+                               enterChoiceWithShared "Shares" [ChooseFromList sdsvw] sdsShare
+                       >>* [OnValue $ withValue $ Just o updateShare]
+                       >>* [OnAction (Action "Back") (const $ Just $ treturn ())]
+                       where
+                               sdsvw (k, v) = concat ["SDS ", toString k, ": ", toString v]
+                               updateShare (k, v) = (viewInformation "Key" [] k
+                                       ||- updateInformation "Value" [] v)
+                                       
+
+               viewDevices :: [MTaskDevice] -> Task ()
+               viewDevices ds = anyTask [
+                               addDevice deviceStore <<@ Title "Add new device" @! ():
+                                       [viewDevice d <<@ Title d.deviceName\\d<-ds]]
+                       <<@ ArrangeWithTabs @! ()
+               
+               viewDevice :: MTaskDevice -> Task ()
+               viewDevice d = (viewInformation "Device settings" [] d 
+                               ||- (case d.deviceConnected of
+                                       Just s = viewSharedInformation "Channels" [] (channels d.deviceName) @! ()
+                                       Nothing = viewInformation "No channels yet" [] "" @! ()
+                               )) <<@ ArrangeHorizontal
+
+               channels :: String -> Shared Channels
+               channels s = sdsFocus s $ memoryStore "" $ Just ([], [], False)
+
+               sdsShare :: Shared [(Int, Int)]
+               sdsShare = sdsFocus "mTaskSDSs" $ memoryStore "" $ Just [(1, 1)]
+
+               addDevice :: (Shared [MTaskDevice]) -> Task ()
+               addDevice devices = enterInformation "Device type and name" []
+                       >>= \(name, ty)->get randomInt @ ((+++) name o toString)
+                       >>= \realname->let ch = channels realname in case ty of
+                               TCPDevice = enterInformation "Hostname and port" []
+                                       >>= \(host, port)->cont realname name ||- syncNetworkChannel host port ch
+                               SerialDevice = accWorld getDevices
+                                       >>= \dl->(enterChoice "Device" [] dl -&&- updateInformation "Settings" [] zero)
+                                       >>= \(device, settings)->cont realname name ||- syncSerialChannel device settings ch
+                       where
+                               cont rn nm = (upd (\l->[dev rn nm:l]) devices >>| addDevice devices)
+                               dev rn nm = {deviceConnected=Just rn,deviceName=nm,deviceTasks=[]}
+
+                               getDevices :: !*World -> *(![String], !*World)
+                               getDevices w = case readDirectory "/dev" w of
+                                       (Error (errcode, errmsg), w) = abort errmsg
+                                       (Ok entries, w) = (map ((+++) "/dev/") (filter isTTY entries), w)
+
+                               isTTY s = not (isEmpty (filter (flip startsWith s) prefixes))
+                               prefixes = ["ttyS", "ttyACM", "ttyUSB", "tty.usbserial"]
+
+//             connectDevice :: [MTaskDevice] -> Task ()
+//             connectDevice [] = treturn ()
+//             connectDevice [d:ds] = (case d.deviceConnected of
+//                     (Just sh) = viewSharedInformation "Buffers" [] sh @! ()
+//                     Nothing = viewInformation ("Connect " +++ d.deviceName) [] "" >>* [
+//                             OnAction (Action "connect") (const $ Just $ connect d)]
+//                     ) -|| connectDevice ds
 
                deviceviewer :: [MTaskDevice] -> [MTaskDeviceStatus]
                deviceviewer ds = [{MTaskDeviceStatus | name = d.deviceName,
-                       connected = if (isNothing d.deviceConnected) False True}\\d<-ds]
+                       connected = if (isNothing d.deviceConnected) False True,
+                       tasks = d.deviceTasks}\\d<-ds]
        
-               deviceStore :: Shared [MTaskDevice]
-               deviceStore = sdsFocus "mTaskDevices" $ memoryStore "" (Just [])
-
 //             showTabbed :: [MTaskDevice] -> Task ()
 //             showTabbed [] = viewInformation "" [] "No devices yet" @! ()
 //             showTabbed [l:ls] = foldr (\e es->manageDevice e ||- es) (manageDevice l) ls
@@ -114,27 +203,6 @@ mTaskManager = forever (addDevice >>= \d->upd (\l->[d:l]) deviceStore)
                allAtOnce t = foldr1 (||-) t @! ()
                //allAtOnce = (flip (@!) ()) o foldr1 (||-)
 
-addDevice :: Task MTaskDevice
-addDevice = enterInformation "Device name" []
-       -&&- enterInformation "Device type" []
-       >>= \(name, ty)->(case ty of
-               TCP = (enterInformation "Host" [] -&&- enterInformation "Port" [])
-                       >>= treturn o Left
-               Serial = accWorld getDevices
-                       >>= \dl->(enterChoice "Device" [] dl -&&- updateInformation "Settings" [] zero)
-                       >>= treturn o Right
-       ) >>= \set->treturn {MTaskDevice |
-               deviceConnected=Nothing,
-               deviceName=name,
-               deviceSettings=set}
-       where
-               getDevices :: !*World -> *(![String], !*World)
-               getDevices w = case readDirectory "/dev" w of
-                       (Error (errcode, errmsg), w) = abort errmsg
-                       (Ok entries, w) = (map ((+++) "/dev/") (filter isTTY entries), w)
-                       where
-                               isTTY s = not (isEmpty (filter (flip startsWith s) prefixes))
-                               prefixes = ["ttyS", "ttyACM", "ttyUSB", "tty.usbserial"]
 
 //mTaskTask :: Task ()
 //mTaskTask = let (msgs, sdsShares) = makeMsgs 1000 bc in
@@ -263,7 +331,6 @@ syncNetworkChannel server port channel
                whileConnected :: (Maybe String) String ([MTaskMSGRecv], [MTaskMSGSend],Bool) -> (MaybeErrorString String, Maybe ([MTaskMSGRecv],[MTaskMSGSend],Bool), [String], Bool)
                whileConnected Nothing acc (msgs,send,sendStopped)
                = (Ok acc, Nothing, [], False)
-//             = (Ok acc, Just (msgs,[],sendStopped), map encode send, False)
 
                whileConnected (Just newData) acc (msgs,send,sendStopped)
                | sendStopped = (Ok acc, Just (msgs ++ [decode newData],[],False), map encode send, False)