implementation module StdTimer import StdBool, StdFunc, StdList, StdMisc, StdTuple import commondef, id, iostate, timeraccess, timerdefaccess, timerdevice, timertable import StdId, StdTimerAttribute, StdTimerElementClass from StdPSt import appPIO, accPIO stdTimerFatalError :: String String -> .x stdTimerFatalError function error = fatalError function "StdTimer" error // Open timer: class Timers tdef where openTimer :: .ls !.(tdef .ls (PSt .l)) !(PSt .l) -> (!ErrorReport,!PSt .l) getTimerType:: .(tdef .ls .pst) -> TimerType instance Timers (Timer t) | TimerElements t where openTimer ls (Timer period items atts) pState # pState = timerFunctions.dOpen pState # (maybe_okId,pState) = accPIO (validateTimerId maybeId) pState | isNothing maybe_okId = (ErrorIdsInUse,pState) # (ok,timers,ioState) = ioStGetTimerHandles pState.io | not ok // This condition should never hold: TimerDevice has just been 'installed' = stdTimerFatalError "openTimer (Timer)" "could not retrieve TimerSystemState from IOSt" # (pid,ioState) = ioStGetIOId ioState # pState = {pState & io=ioState} id = fromJust maybe_okId # (ts,pState) = timerElementToHandles items pState itemHs = map timerElementStateToTimerElementHandle ts # (it,ioState) = ioStGetIdTable pState.io # (rt,ioState) = ioStGetReceiverTable ioState (ok,itemHs,rt,it) = bindTimerElementIds pid id itemHs rt it | not ok # ioState = ioStSetDevice (TimerSystemState timers) ioState # ioState = ioStSetIdTable it ioState # ioState = ioStSetReceiverTable rt ioState = (ErrorIdsInUse,{pState & io=ioState}) | otherwise = (NoError,pState2) with tH = { tId = id , tSelect = ableTimer , tPeriod = max 0 period , tFun = f , tItems = itemHs } tsH = TimerLSHandle {tState=ls1,tHandle=tH} tLoc = { tlIOId = pid , tlDevice = TimerDevice , tlParentId = id , tlTimerId = id } it1 = snd (addIdToIdTable id {idpIOId=pid,idpDevice=TimerDevice,idpId=id} it) ioState1 = addAbleTimerToTimerTable ableTimer tLoc period ioState ioState2 = ioStSetReceiverTable rt ioState1 ioState3 = ioStSetIdTable it1 ioState2 ioState4 = ioStSetDevice (TimerSystemState {timers & tTimers=[tsH:timers.tTimers]}) ioState3 pState1 = {pState & io=ioState4} (ls1,pState2) = timerInit (ls,pState1) where (hasIdAtt,idAtt) = cselect isTimerId undef atts maybeId = if hasIdAtt (Just (getTimerIdAtt idAtt)) Nothing ableTimer = enabled (getTimerSelectStateAtt (snd (cselect isTimerSelectState (TimerSelectState Able) atts))) f = getTimerFun (snd (cselect isTimerFunction (TimerFunction (\_ st->st)) atts)) timerInit = getTimerInitFun (snd (cselect isTimerInit (TimerInit id) atts)) validateTimerId :: !(Maybe Id) !(IOSt .l) -> (!Maybe Id,!IOSt .l) validateTimerId Nothing ioState # (tId,ioState) = openId ioState = (Just tId,ioState) validateTimerId (Just id) ioState # (it,ioState) = ioStGetIdTable ioState # (member,it) = memberIdTable id it | member = (Nothing,ioStSetIdTable it ioState) | otherwise = (Just id,ioStSetIdTable it ioState) addAbleTimerToTimerTable :: !Bool !TimerLoc !TimerInterval !(IOSt .l) -> IOSt .l addAbleTimerToTimerTable True tLoc period ioState # (tt,ioState) = ioStGetTimerTable ioState # (_,tt) = addTimerToTimerTable tLoc period tt = ioStSetTimerTable tt ioState addAbleTimerToTimerTable _ _ _ ioState = ioState getTimerType _ = "Timer" eqTimerStateHandleId :: !Id !(TimerStateHandle .pst) -> (!Bool,!TimerStateHandle .pst) eqTimerStateHandleId id tsH=:(TimerLSHandle {tHandle={tId}}) = (id==tId,tsH) // Close timer: closeTimer :: !Id !(IOSt .l) -> IOSt .l closeTimer id ioState # (ok,tHs,ioState) = ioStGetTimerHandles ioState | not ok = ioState | otherwise # (pid,ioState) = ioStGetIOId ioState # (rt,ioState) = ioStGetReceiverTable ioState # (tt,ioState) = ioStGetTimerTable ioState # (it,ioState) = ioStGetIdTable ioState (rt,tt,it,tsHs) = closetimer id pid rt tt it tHs.tTimers # ioState = ioStSetIdTable it ioState # ioState = ioStSetReceiverTable rt ioState # ioState = ioStSetTimerTable tt ioState tHs = {tHs & tTimers=tsHs} # ioState = ioStSetDevice (TimerSystemState tHs) ioState = ioState where closetimer :: !Id !SystemId !*ReceiverTable !*TimerTable !*IdTable ![TimerStateHandle .pst] -> (!*ReceiverTable,!*TimerTable,!*IdTable,![TimerStateHandle .pst]) closetimer id pid rt tt it [tsH:tsHs] # (eqid,tsH) = eqTimerStateHandleId id tsH | eqid # (tt1,rt1,it1) = disposeElementIds pid tsH tt rt it = (rt1,tt1,it1,tsHs) | otherwise # (rt,tt,it,tsHs) = closetimer id pid rt tt it tsHs = (rt,tt,it,[tsH:tsHs]) where disposeElementIds :: !SystemId !(TimerStateHandle .pst) !*TimerTable !*ReceiverTable !*IdTable -> (!*TimerTable,!*ReceiverTable,!*IdTable) disposeElementIds pid (TimerLSHandle {tHandle={tId,tItems}}) tt rt it # (tt,rt,it) = unbindTimerElementIds pid tItems (tt,rt,it) = (snd (removeTimerFromTimerTable teLoc tt),rt,snd (removeIdFromIdTable tId it)) where teLoc = {tlIOId=pid,tlDevice=TimerDevice,tlParentId=tId,tlTimerId=tId} closetimer _ _ rt tt it _ = (rt,tt,it,[]) // Get the Ids and TimerTypes of all timers: getTimers :: !(IOSt .l) -> (![(Id,TimerType)],!IOSt .l) getTimers ioState # (ok,tHs,ioState) = ioStGetTimerHandles ioState | not ok = ([],ioState) | otherwise # (idtypes,timers) = getidtypes tHs.tTimers tHs = {tHs & tTimers=timers} # ioState = ioStSetDevice (TimerSystemState tHs) ioState = (idtypes,ioState) where getidtypes :: ![TimerStateHandle .pst] -> (![(Id,TimerType)],![TimerStateHandle .pst]) getidtypes [TimerLSHandle tlsH=:{tHandle=tH}:tsHs] # (idtype, tH) = getidtype tH (idtypes,tsHs) = getidtypes tsHs = ([idtype:idtypes],[TimerLSHandle {tlsH & tHandle=tH}:tsHs]) where getidtype :: !(TimerHandle .ls .pst) -> ((Id,TimerType),!TimerHandle .ls .pst) getidtype tH=:{tId} = ((tId,"Timer"),tH) getidtypes _ = ([],[]) // Enabling and Disabling of timers: enableTimer :: !Id !(IOSt .l) -> IOSt .l enableTimer id ioState = changeTimer id enabletimer ioState where enabletimer :: TimerLoc !*TimerTable !(TimerStateHandle .pst) -> (!*TimerTable, !TimerStateHandle .pst) enabletimer teLoc tt tlsH=:(TimerLSHandle tsH=:{tHandle=tH=:{tSelect,tPeriod}}) | tSelect = (tt,tlsH) | otherwise # (_,tt) = addTimerToTimerTable teLoc tPeriod tt = (tt,TimerLSHandle {tsH & tHandle={tH & tSelect=True}}) disableTimer :: !Id !(IOSt .l) -> IOSt .l disableTimer id ioState = changeTimer id disabletimer ioState where disabletimer :: TimerLoc !*TimerTable !(TimerStateHandle .pst) -> (!*TimerTable, !TimerStateHandle .pst) disabletimer teLoc tt tlsH=:(TimerLSHandle tsH=:{tHandle=tH=:{tSelect}}) | not tSelect = (tt,tlsH) | otherwise # (_,tt)= removeTimerFromTimerTable teLoc tt = (tt,TimerLSHandle {tsH & tHandle={tH & tSelect=False}}) // Get the SelectState of timers: getTimerSelectState :: !Id !(IOSt .l) -> (!Maybe SelectState,!IOSt .l) getTimerSelectState id ioState # (ok,tHs,ioState) = ioStGetTimerHandles ioState | not ok = (Nothing,ioState) | otherwise # (maybe_select,timers) = gettimerselect id tHs.tTimers tHs = {tHs & tTimers=timers} # ioState = ioStSetDevice (TimerSystemState tHs) ioState = (maybe_select,ioState) where gettimerselect :: !Id ![TimerStateHandle .pst] -> (!Maybe SelectState, ![TimerStateHandle .pst]) gettimerselect id [tsH=:(TimerLSHandle {tHandle={tId,tSelect}}):tsHs] | id==tId = (Just (if tSelect Able Unable),[tsH:tsHs]) | otherwise # (optselect,tsHs) = gettimerselect id tsHs = (optselect,[tsH:tsHs]) gettimerselect _ _ = (Nothing,[]) // Set the TimerInterval of timers: setTimerInterval :: !Id !TimerInterval !(IOSt .l) -> IOSt .l setTimerInterval id interval ioState = changeTimer id (settimerinterval interval) ioState where settimerinterval :: !TimerInterval !TimerLoc !*TimerTable !(TimerStateHandle .pst) -> (!*TimerTable, !TimerStateHandle .pst) settimerinterval period teLoc tt tlsH=:(TimerLSHandle tsH=:{tHandle=tH=:{tSelect,tPeriod}}) # period = max 0 period | period==tPeriod = (tt,tlsH) # tlsH = TimerLSHandle {tsH & tHandle={tH & tPeriod=period}} | not tSelect = (tt,tlsH) | otherwise # (_,tt) = setIntervalInTimerTable teLoc period tt = (tt,tlsH) // Get the TimerInterval of timers: getTimerInterval :: !Id !(IOSt .l) -> (!Maybe TimerInterval,!IOSt .l) getTimerInterval id ioState # (ok,tHs,ioState) = ioStGetTimerHandles ioState | not ok = (Nothing,ioState) # (optinterval,timers) = gettimerinterval id tHs.tTimers tHs = {tHs & tTimers=timers} # ioState = ioStSetDevice (TimerSystemState tHs) ioState = (optinterval,ioState) where gettimerinterval :: !Id ![TimerStateHandle .pst] -> (!Maybe TimerInterval, ![TimerStateHandle .pst]) gettimerinterval id [tsH=:(TimerLSHandle {tHandle={tId,tPeriod}}):tsHs] | id==tId = (Just tPeriod,[tsH:tsHs]) | otherwise # (optselect,tsHs) = gettimerinterval id tsHs = (optselect, [tsH:tsHs]) gettimerinterval _ _ = (Nothing,[]) ioStGetTimerHandles :: !(IOSt .l) -> (!Bool,TimerHandles (PSt .l), !IOSt .l) ioStGetTimerHandles ioState # (found,tDevice,ioState) = ioStGetDevice TimerDevice ioState | not found = (False,undef,ioState) | otherwise = (True,timerSystemStateGetTimerHandles tDevice,ioState) // General TimerHandle changing function: :: DeltaTimerStateHandle pst :== TimerLoc -> *TimerTable -> *((TimerStateHandle pst) -> *(*TimerTable,TimerStateHandle pst)) changeTimer :: !Id !(DeltaTimerStateHandle (PSt .l)) !(IOSt .l) -> IOSt .l changeTimer id f ioState # (ok,tHs,ioState) = ioStGetTimerHandles ioState | not ok = ioState | otherwise # (tt, ioState)= ioStGetTimerTable ioState # (ioid,ioState)= ioStGetIOId ioState (tt,tHs) = changetimerdevice ioid id f tt tHs # ioState = ioStSetDevice (TimerSystemState tHs) ioState # ioState = ioStSetTimerTable tt ioState = ioState where changetimerdevice :: SystemId !Id (DeltaTimerStateHandle .pst) !*TimerTable !(TimerHandles .pst) -> (!*TimerTable, !TimerHandles .pst) changetimerdevice ioid id f tt timers=:{tTimers=tsHs} # (tt,tsHs) = changetimerstatehandles ioid id f tt tsHs = (tt,{timers & tTimers=tsHs}) where changetimerstatehandles :: SystemId !Id (DeltaTimerStateHandle .pst) !*TimerTable ![TimerStateHandle .pst] -> (!*TimerTable,![TimerStateHandle .pst]) changetimerstatehandles ioid id f tt [tsH=:(TimerLSHandle {tHandle={tId}}):tsHs] | id==tId = (tt1,[tsH1:tsHs]) with teLoc = {tlIOId=ioid,tlDevice=TimerDevice,tlParentId=id,tlTimerId=id} (tt1,tsH1) = f teLoc tt tsH | otherwise = (tt1,[tsH:tsHs1]) with (tt1,tsHs1) = changetimerstatehandles ioid id f tt tsHs changetimerstatehandles _ _ _ tt [] = (tt,[])