Make log error messages ephemeral (#1877)

Closes #1291.  The idea is that log entries produced by `log` or `say` will always be shown; but other log messages (error messages, status reports, etc.) are "ephemeral", meaning they will be shown as long as they are the most recent log entry, but will no longer be shown once a new log entry is added.  The motivation is that it is often unhelpful to see one's log full of error messages.

- All the log messages are still retained in the `RobotLog`; we just filter out some entries when displaying the log in the info panel.
- All unfiltered log entries are still shown in the Messages dialog.
- Also added a `run: OK.` log entry for successful execution of `run`, so that it in the common situation when you are trying repeatedly to `run` a file and then fixing type errors, you can immediately tell when you are successful since the error will disappear to be replaced by an `OK` message.

To test this, start a new game and try executing some commands that cause an error (e.g. `run` a non-existent file, or execute `move` with the base robot, etc.) as well as executing `log` or `say`.  Observe that `log` and `say` entries persist, whereas error messages are shown only until a new log entry is added.
This commit is contained in:
Brent Yorgey 2024-05-29 22:08:27 -05:00 committed by GitHub
parent 70956da041
commit 75eab16115
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 11 deletions

View File

@ -1234,6 +1234,8 @@ execConst runChildProg c vs s k = do
-- it's slightly technically incorrect, and (3) why it is still way
-- better than what we had before.
robotContext . defReqs <>= (pt ^. processedReqCtx)
void $ traceLog CmdStatus Info "run: OK."
return $ initMachine' pt empty s k
_ -> badConst
Not -> case vs of

View File

@ -44,6 +44,8 @@ data RobotLogSource
Logged
| -- | Produced as the result of an error.
RobotError
| -- | Produced as a status message from a command.
CmdStatus
deriving (Show, Eq, Ord, Generic, FromJSON, ToJSON)
-- | Source of a log entry.

View File

@ -934,6 +934,7 @@ colorLogs e = case e ^. leSource of
Said -> robotColor rid
Logged -> notifAttr
RobotError -> colorSeverity (e ^. leSeverity)
CmdStatus -> notifAttr
where
-- color each robot message with different color of the world
robotColor = indexWrapNonEmpty messageAttributeNames
@ -1439,27 +1440,42 @@ drawReqs = vBox . map (hCenter . drawReq)
indent2 :: WrapSettings
indent2 = defaultWrapSettings {fillStrategy = FillIndent 2}
-- | Only show the most recent entry, and any entries which were
-- produced by "say" or "log" commands. Other entries (i.e. errors
-- or command status reports) are thus ephemeral, i.e. they are only
-- shown when they are the most recent log entry, but hidden once
-- something else is logged.
getLogEntriesToShow :: AppState -> [LogEntry]
getLogEntriesToShow s = logEntries ^.. traversed . ifiltered shouldShow
where
logEntries = s ^. gameState . to focusedRobot . _Just . robotLog
n = Seq.length logEntries
shouldShow i le =
(i == n - 1) || case le ^. leSource of
RobotLog src _ _ -> src `elem` [Said, Logged]
SystemLog -> False
drawRobotLog :: AppState -> Widget Name
drawRobotLog s =
vBox
[ padBottom (Pad 1) (hBorderWithLabel (txt "Log"))
, vBox . F.toList . imap drawEntry $ logEntries
, vBox . F.toList . imap drawEntry $ logEntriesToShow
]
where
logEntries = s ^. gameState . to focusedRobot . _Just . robotLog
rid = s ^? gameState . to focusedRobot . _Just . robotID
n = Seq.length logEntries
allMe = all me logEntries
me le = case le ^. leSource of
RobotLog _ i _ -> Just i == rid
_ -> False
logEntriesToShow = getLogEntriesToShow s
n = length logEntriesToShow
drawEntry i e =
(if i == n - 1 && s ^. uiState . uiGameplay . uiScrollToEnd then visible else id) $
drawLogEntry (not allMe) e
rid = s ^? gameState . to focusedRobot . _Just . robotID
allMe = all me logEntriesToShow
me le = case le ^. leSource of
RobotLog _ i _ -> Just i == rid
_ -> False
-- | Show the 'CESK' machine of focused robot. Puts a separator above.
drawRobotMachine :: AppState -> Bool -> Widget Name
drawRobotMachine s showName = case s ^. gameState . to focusedRobot of