summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assignment-13/uFPL.icl2
-rw-r--r--assignment-13/uFPL/Sim.icl81
2 files changed, 53 insertions, 30 deletions
diff --git a/assignment-13/uFPL.icl b/assignment-13/uFPL.icl
index b87538e..129df92 100644
--- a/assignment-13/uFPL.icl
+++ b/assignment-13/uFPL.icl
@@ -241,7 +241,7 @@ evalTrigger (Change (EShared s)) st = case get s.sname st.vars of
Just shr -> Just (False, st)
_ -> Nothing
evalTrigger (EShared s ?= e) st = case get s.sname st.vars of
- Just shr=:{dirty=n} | n > 0 -> eval e st >>= \e -> flip tuple st <$> equals shr.val e
+ Just shr=:{dirty=n} | n > 0 -> eval e st >>= \e -> flip tuple {st & vars=put s.sname {shr & dirty=n-1} st.vars} <$> equals shr.val e
Just shr -> Just (False, st)
_ -> Nothing
where
diff --git a/assignment-13/uFPL/Sim.icl b/assignment-13/uFPL/Sim.icl
index 3d38b67..0f232fc 100644
--- a/assignment-13/uFPL/Sim.icl
+++ b/assignment-13/uFPL/Sim.icl
@@ -4,6 +4,7 @@ from StdFunc import flip, seq
from Data.Func import $
import Data.Functor
+from Data.List import concatMap
import qualified Data.Map as M
import Data.Maybe
import Data.Tuple
@@ -11,6 +12,7 @@ from Text import <+
import Text.HTML
import iTasks
+import iTasks.Extensions.DateTime
import iTasks.UI.Editor.Common
import uFPL
@@ -40,6 +42,9 @@ irules = sharedStore "irules" []
ishares :: Shared IShares
ishares = sharedStore "ishares" gDefault{|*|}
+simulatorRunning :: Shared Bool
+simulatorRunning = sharedStore "simulatorRunning" False
+
getShared :: ISharedRef -> Task Dynamic
getShared n = get ishares >>= \shrs -> case filter ((==) n o isharedName) shrs of
[] -> throw (NoShareException n)
@@ -272,11 +277,15 @@ where
}
simulate :: [NamedRule] -> *World -> *World
-simulate rs = startEngine (setupShares >>| sim)
+simulate rs = startEngine $
+ (setupShares >>| sim)
+ -&&- ((
+ whileUnchanged (irules >*< ishares) (uncurry newShares)
+ ) <<@ NoUserInterface)
where
setupShares =
- set (unlift (allShares rs)) ishares >>|
- set (unlift rs) irules
+ set (unlift rs) irules >>|
+ set (unlift (allShares rs)) ishares
sim =
(updateSharedInformation (Title "Rules") [] irules
@@ -285,17 +294,28 @@ where
(show -&&- check)
<<@ ArrangeHorizontal
- show :: Task IState
- show = whileUnchanged (irules >*< ishares) (\(_,shrs) ->
- newShares shrs >>|
- viewSharedInformation (Title "State") [viewAsLists] istate)
+ newShares :: [INamedRule] IShares -> Task IState
+ newShares rs shrs = get istate >>= lift >>= \ist -> case ist of
+ (st :: State) -> set (unlift
+ { st & vars = 'M'.mapWithKey (\k v -> {v & subscriptions=subscriptions k rs}) $ foldr (uncurry 'M'.put) st.vars
+ [(isharedName shr, {val=isharedInit shr, dirty=0, subscriptions=0}) \\ shr <- shrs]}) istate
where
- newShares :: IShares -> Task IState
- newShares shrs = get istate >>= lift >>= \ist -> case ist of
- (st :: State) -> set (unlift
- { st & vars = foldr (uncurry 'M'.put) st.vars
- [(isharedName shr, {val=isharedInit shr, dirty=0, subscriptions=0}) \\ shr <- shrs]}) istate
+ subscriptions :: String [INamedRule] -> Int
+ subscriptions s rs = length $ filter ((==) s) $ concatMap allSharedSubscriptions $ flatten [allTriggers rs` \\ Rule _ rs` <- rs]
+
+ allTriggers :: [IRule] -> [ITrigger]
+ allTriggers rs = [t \\ ITrigger t _ <- rs]
+ allSharedSubscriptions :: ITrigger -> [ISharedRef]
+ allSharedSubscriptions t = case t of
+ IChange s -> [s]
+ IBecomes s _ -> [s]
+ ITAnd a b -> allSharedSubscriptions a ++ allSharedSubscriptions b
+ ITOr a b -> allSharedSubscriptions a ++ allSharedSubscriptions b
+
+ show :: Task IState
+ show = viewSharedInformation (Title "State") [viewAsLists] istate
+ where
viewAsLists = ViewUsing tolists $ container3 listView listView listView
with
listView :: Editor [(String,IShareState a)] | iTask, == a
@@ -329,21 +349,12 @@ where
[action "Step" $ step])
where
action :: String (Task a) -> TaskCont String (Task String) | iTask a
- action s t = OnAction (Action s) $ ifOk $ t >>| check
+ action s t = OnAction (Action s) $ ifOk $ t >>- \_ -> check
ifOk :: a (TaskValue String) -> Maybe a
ifOk t (Value "OK" _) = Just t
ifOk _ _ = Nothing
- step :: Task IState
- step = get istate >>= lift >>= \st -> case st of
- (st :: State) -> get irules >>= lift >>= \rs -> case rs of
- (rs :: [NamedRule]) -> case run rs st of
- Just st -> set (unlift st) istate
- Nothing -> throw RunException
- _ -> throw (LiftException "step rules")
- _ -> throw (LiftException "step state")
-
buttonActions :: IShares -> [TaskCont String (Task String)]
buttonActions shrs =
[action ("Toggle B" <+ i) $ press i \\ i <- [0..5] | any ((==) ("b" <+ i) o isharedName) shrs]
@@ -356,15 +367,27 @@ where
millisActions :: IShares -> [TaskCont String (Task String)]
millisActions shrs
| any ((==) "millis" o isharedName) shrs =
- [ action "Millis +100" $ addMillis 100
- , action "Millis +1000" $ addMillis 1000
+ [ action "t +100ms" $ addMillis 100 $> ()
+ , action "t +1s" $ addMillis 1000 $> ()
+ , action "Toggle running / 1s" $
+ ((forever $ waitForTimer 0 >>| addMillis 1000 >>| step $> ()) <<@ NoUserInterface)
+ >>* [OnAction (Action "Stop") (always (return ()))]
]
| otherwise = []
- where
- addMillis :: Int -> Task IState
- addMillis n = get istate >>= lift >>= \st -> case st of
- (st :: State) -> set (unlift {st & vars='M'.alter upd "millis" st.vars}) istate
- with upd (Just s=:{val=v :: Int}) = Just {s & val=dynamic v+n, dirty=s.subscriptions}
+
+ step :: Task IState
+ step = get istate >>= lift >>= \st -> case st of
+ (st :: State) -> get irules >>= lift >>= \rs -> case rs of
+ (rs :: [NamedRule]) -> case run rs st of
+ Just st -> set (unlift st) istate
+ Nothing -> throw RunException
+ _ -> throw (LiftException "step rules")
+ _ -> throw (LiftException "step state")
+
+ addMillis :: Int -> Task IState
+ addMillis n = get istate >>= lift >>= \st -> case st of
+ (st :: State) -> set (unlift {st & vars='M'.alter upd "millis" st.vars}) istate
+ with upd (Just s=:{val=v :: Int}) = Just {s & val=dynamic v+n, dirty=s.subscriptions}
// From iTasks.UI.Editor.Controls
viewComponent toAttributes type = {Editor|genUI=genUI,onEdit=onEdit,onRefresh=onRefresh}