Skip to content
This repository has been archived by the owner on Aug 23, 2018. It is now read-only.

Commit

Permalink
basic expando interactivity
Browse files Browse the repository at this point in the history
- factor log data structure out into its own module
- some wonky event routing and too many mailboxes;
  need to compress to one foldp eventually
  • Loading branch information
vilterp committed Jan 4, 2016
1 parent d941e96 commit e96c46d
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 64 deletions.
114 changes: 90 additions & 24 deletions src/debugger/Debugger/Active.elm
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import Effects exposing (..)

import Debugger.RuntimeApi as API
import Debugger.Model as DM
import Utils.Helpers exposing (last, unsafe)
import Debugger.Model.Log as Log
import Utils.Helpers exposing (last, unsafe, unsafeResult)
import Utils.JsArray as JsArray
import Explorer.Value.FromJs as FromJs exposing (ElmValue)
import Explorer.Value.Expando as Expando exposing (Expando)
Expand Down Expand Up @@ -40,7 +41,7 @@ initModel window_ signalValues session =
, exprLogs = Dict.empty
, nodeLogs =
signalValues
|> List.map (\(tag, val) -> (tag, [logEntry 0 val]))
|> List.map (\(tag, val) -> (tag, Log.fromList [makeLogEntry 0 val]))
|> Dict.fromList
, subscribedNodes = Set.empty
, salientNodes = session |> API.getSgShape |> DM.getSalientNodes
Expand All @@ -66,6 +67,7 @@ type Message
= Command Command
| Notification Notification
| Response Response
| UiMessage ValueExplorerAction
| NoOp


Expand Down Expand Up @@ -106,7 +108,7 @@ type Response


type alias ExpandoValueLog =
List (DM.FrameIndex, (ElmValue, Expando))
Log.Log DM.FrameIndex (ElmValue, Expando)


toExpandoLogElement : DM.JsElmValue -> (ElmValue, Expando)
Expand All @@ -120,7 +122,7 @@ toExpandoLogElement value =

toExpandoLog : DM.ValueLog -> ExpandoValueLog
toExpandoLog log =
List.map (\(idx, value) -> (idx, toExpandoLogElement value)) log
Log.map (\(idx, value) -> (idx, toExpandoLogElement value)) log


update : Message -> Model -> (Model, Effects Message)
Expand Down Expand Up @@ -253,10 +255,10 @@ update msg state =
nodeLogs
|> List.filter (\(nodeId, log) ->
nodeId == (API.getSgShape newSession).mainId)
|> List.head
|> last
|> unsafe "no log for main"
|> snd
|> last
|> Log.last
|> unsafe "no values in main log"
|> snd
in
Expand Down Expand Up @@ -338,14 +340,14 @@ update msg state =
(API.getSgShape state.session).mainId

newExprLogs =
updateLogs
appendToLogs
currentFrameIndex
state.exprLogs
newFrameNot.flaggedExprValues
(always True)

newNodeLogs =
updateLogs
appendToLogs
currentFrameIndex
state.nodeLogs
newFrameNot.subscribedNodeValues
Expand Down Expand Up @@ -423,8 +425,63 @@ update msg state =
, none
)

UiMessage mainPanelMessage ->
case mainPanelMessage of
VEAction veAction ->
case veAction of
Expando.NodeMessage nodeId action ->
( { state | nodeLogs =
updateLog
nodeId
(curFrameIdx state)
action
state.nodeLogs
|> unsafeResult
}
, none
)

Expando.ExprMessage tag action ->
( { state | exprLogs =
updateLog
tag
(curFrameIdx state)
action
state.exprLogs
|> unsafeResult
}
, none
)

VENoOp ->
(state, none)

NoOp ->
( state, none )
(state, none)


updateLog
: comparable
-> DM.FrameIndex
-> Expando.Action
-> Dict comparable ExpandoValueLog
-> Result String (Dict comparable ExpandoValueLog)
updateLog key idx action logs =
case Dict.get key logs of
Just log ->
let
updateEntry (_, (value, expando)) =
(value, Expando.update action expando)
in
case Log.update idx updateEntry log of
Just updatedLog ->
Ok <| Dict.insert key updatedLog logs

Nothing ->
Err "no log entry found at given index"

Nothing ->
Err "no such log"


-- should this be in RuntimeApi?
Expand Down Expand Up @@ -464,6 +521,11 @@ type CommandResponseMessage
| NoOpResponse


type ValueExplorerAction
= VEAction Expando.MainPanelMessage
| VENoOp


commandResponseMailbox : () -> Signal.Mailbox CommandResponseMessage
commandResponseMailbox _ =
crMailbox
Expand All @@ -473,6 +535,15 @@ crMailbox =
Signal.mailbox NoOpResponse


valueExplorerActionMailbox : () -> Signal.Mailbox ValueExplorerAction
valueExplorerActionMailbox _ =
veaMailbox


veaMailbox =
Signal.mailbox VENoOp


getMainVal : DM.DebugSession -> DM.ValueSet -> DM.JsElmValue
getMainVal session values =
let
Expand All @@ -499,13 +570,13 @@ getLatestMainVal session logs =
|> List.head
|> unsafe "no log with main id"
|> snd
|> last
|> Log.last
|> unsafe "empty log"
|> snd


logEntry : DM.FrameIndex -> DM.JsElmValue -> (DM.FrameIndex, (FromJs.ElmValue, Expando))
logEntry frameIdx value =
makeLogEntry : DM.FrameIndex -> DM.JsElmValue -> (DM.FrameIndex, (FromJs.ElmValue, Expando))
makeLogEntry frameIdx value =
let
reifiedElmValue =
FromJs.toElmValue value
Expand All @@ -517,25 +588,25 @@ appendToLog : DM.FrameIndex -> DM.JsElmValue -> Maybe ExpandoValueLog -> Maybe E
appendToLog currentFrameIndex value maybeLog =
let
entry =
logEntry currentFrameIndex value
makeLogEntry currentFrameIndex value

newLog =
case maybeLog of
Just log ->
log ++ [entry]
Log.append entry log

Nothing ->
[entry]
Log.fromList [entry]
in
Just newLog


updateLogs : DM.FrameIndex
appendToLogs : DM.FrameIndex
-> Dict comparable ExpandoValueLog
-> List (comparable, DM.JsElmValue)
-> (comparable -> Bool)
-> Dict comparable ExpandoValueLog
updateLogs currentFrameIndex logs updates idPred =
appendToLogs currentFrameIndex logs updates idPred =
List.foldl
(\(tag, value) logs ->
Dict.update tag (appendToLog currentFrameIndex value) logs)
Expand All @@ -546,13 +617,8 @@ updateLogs currentFrameIndex logs updates idPred =
truncateLogs : DM.FrameIndex -> Dict comparable ExpandoValueLog -> Dict comparable ExpandoValueLog
truncateLogs frameIdx logs =
logs
|> Dict.map (\_ log -> truncateLog frameIdx log)
|> Dict.filter (\_ log -> not (List.isEmpty log))


truncateLog : DM.FrameIndex -> ExpandoValueLog -> ExpandoValueLog
truncateLog frameIdx log =
List.filter (\(idx, val) -> idx <= frameIdx) log
|> Dict.map (\_ log -> Log.truncate frameIdx log)
|> Dict.filter (\_ log -> not (Log.isEmpty log))


isPlaying : Model -> Bool
Expand Down
11 changes: 2 additions & 9 deletions src/debugger/Debugger/Model.elm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Time exposing (Time)
import Utils.Helpers exposing (unsafe)

import Utils.JsArray as JsArray
import Debugger.Model.Log exposing (Log)


type alias FrameIndex =
Expand Down Expand Up @@ -81,7 +82,7 @@ type alias FrameInterval =


type alias ValueLog =
List (FrameIndex, JsElmValue)
Log FrameIndex JsElmValue


type alias ValueSet =
Expand Down Expand Up @@ -244,11 +245,3 @@ encodeEvent event =
, ("nodeId", JsEnc.int event.nodeId)
, ("time", JsEnc.float event.time)
]


logItemForFrameIdx : FrameIndex -> List (FrameIndex, a) -> Maybe a
logItemForFrameIdx idx log =
log
|> List.filter (\(itemIdx, val) -> itemIdx <= idx)
|> Utils.Helpers.last
|> Maybe.map snd
84 changes: 84 additions & 0 deletions src/debugger/Debugger/Model/Log.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
module Debugger.Model.Log
( Log, empty, fromList, toList, append, last
, mostRecentBeforeIndex, truncate, map, filter, isEmpty, update
) where


import Utils.Helpers


type Log timestamp item =
Log (List (timestamp, item))


empty : Log timestamp item
empty =
Log []


fromList : List (timestamp, item) -> Log timestamp item
fromList log =
Log log


toList : Log timestamp item -> List (timestamp, item)
toList (Log log) =
log


isEmpty : Log timestamp item -> Bool
isEmpty (Log log) =
List.isEmpty log


append : (timestamp, item) -> Log timestamp item -> Log timestamp item
append pair (Log log) =
log ++ [pair] |> Log


last : Log timestamp item -> Maybe (timestamp, item)
last (Log log) =
log |> Utils.Helpers.last


mostRecentBeforeIndex : comparable -> Log comparable item -> Maybe item
mostRecentBeforeIndex timestamp (Log log) =
log
|> List.filter (\(itemIdx, val) -> itemIdx <= timestamp)
|> Utils.Helpers.last
|> Maybe.map snd


truncate : comparable -> Log comparable item -> Log comparable item
truncate timestamp (Log log) =
List.filter (\(idx, val) -> idx <= timestamp) log |> Log


map : ((timestamp, item) -> (timestamp, b)) -> Log timestamp item -> Log timestamp b
map func (Log log) =
List.map func log |> Log


filter : ((timestamp, item) -> Bool) -> Log timestamp item -> Log timestamp item
filter predicate (Log log) =
List.filter predicate log |> Log


update
: comparable
-> ((comparable, item) -> item)
-> Log comparable item
-> Maybe (Log comparable item)
update timestamp updater (Log log) =
let
(before, after) =
List.partition (\(ts, _) -> ts < timestamp) log
in
case after of
[] ->
Nothing

((ts, x)::xs) ->
before ++ ((ts, updater (ts, x)) :: xs)
|> Log
|> Just
3 changes: 2 additions & 1 deletion src/debugger/Debugger/RuntimeApi.elm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Set
import Task exposing (Task)

import Debugger.Model exposing (..)
import Debugger.Model.Log as Log
import Native.Debugger.RuntimeApi
import Utils.Helpers exposing (unsafe)
import Utils.JsArray as JsArray
Expand Down Expand Up @@ -124,7 +125,7 @@ getNodeStateSingle session frameIdx nodes =
let
extract (id, log) =
( id
, snd (unsafe "corrupted node state" (List.head log))
, snd (unsafe "corrupted node state" (Log.last log))
)
in
getNodeState session { start = frameIdx, end = frameIdx } nodes
Expand Down
3 changes: 3 additions & 0 deletions src/debugger/Debugger/Service.elm
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ app moduleName =
, Signal.map
(ActiveMessage << Active.Command)
(commandsMailbox ()).signal
, Signal.map
(ActiveMessage << Active.UiMessage)
(Active.valueExplorerActionMailbox ()).signal
]
}

Expand Down
Loading

0 comments on commit e96c46d

Please sign in to comment.