mirror of
https://gitlab.com/sheaf/metabrush.git
synced 2024-11-05 14:53:37 +00:00
fix time-travel issue in deletion code
This commit is contained in:
parent
dc11c1af15
commit
087c29aef3
|
@ -58,7 +58,7 @@ import Control.Lens
|
||||||
|
|
||||||
-- tardis
|
-- tardis
|
||||||
import Control.Monad.Trans.Tardis
|
import Control.Monad.Trans.Tardis
|
||||||
( Tardis, TardisT )
|
( Tardis )
|
||||||
import qualified Control.Monad.Trans.Tardis as Tardis
|
import qualified Control.Monad.Trans.Tardis as Tardis
|
||||||
( TardisT(..)
|
( TardisT(..)
|
||||||
, getPast, getFuture, sendPast, sendFuture
|
, getPast, getFuture, sendPast, sendFuture
|
||||||
|
@ -68,8 +68,8 @@ import qualified Control.Monad.Trans.Tardis as Tardis
|
||||||
import Control.Monad.Trans.Class
|
import Control.Monad.Trans.Class
|
||||||
( lift )
|
( lift )
|
||||||
import Control.Monad.Trans.State.Strict
|
import Control.Monad.Trans.State.Strict
|
||||||
( StateT(..)
|
( StateT(..), State, runState, evalState
|
||||||
, State, runState, evalState, get, put, modify'
|
, get, put, modify
|
||||||
)
|
)
|
||||||
|
|
||||||
-- MetaBrush
|
-- MetaBrush
|
||||||
|
@ -296,15 +296,24 @@ data UpdateInfo
|
||||||
deriving ( Semigroup, Monoid )
|
deriving ( Semigroup, Monoid )
|
||||||
via Generically UpdateInfo
|
via Generically UpdateInfo
|
||||||
|
|
||||||
recordPointUpdate :: Unique -> StrokePoint d -> State UpdateInfo ()
|
-- Update the info to record a modification.
|
||||||
recordPointUpdate uniq ( PathPoint {} ) = modify'
|
--
|
||||||
( over ( field' @"pathPointsAffected" ) (<>1)
|
-- Needs to be lazy in the given Boolean, to avoid time paradoxes.
|
||||||
. over ( field' @"strokesAffected" ) ( Set.insert uniq )
|
recordPointUpdate :: Monad m => Bool -> Unique -> StrokePoint d -> StateT UpdateInfo m ()
|
||||||
)
|
recordPointUpdate doUpdate uniq ( PathPoint {} ) = modify $
|
||||||
recordPointUpdate uniq ( ControlPoint {} ) = modify'
|
if doUpdate
|
||||||
|
then
|
||||||
|
( over ( field' @"pathPointsAffected" ) (<>1)
|
||||||
|
. over ( field' @"strokesAffected" ) ( Set.insert uniq )
|
||||||
|
)
|
||||||
|
else id
|
||||||
|
recordPointUpdate doUpdate uniq ( ControlPoint {} ) = modify $
|
||||||
|
if doUpdate
|
||||||
|
then
|
||||||
( over ( field' @"controlPointsAffected" ) (<>1)
|
( over ( field' @"controlPointsAffected" ) (<>1)
|
||||||
. over ( field' @"strokesAffected" ) ( Set.insert uniq )
|
. over ( field' @"strokesAffected" ) ( Set.insert uniq )
|
||||||
)
|
)
|
||||||
|
else id
|
||||||
|
|
||||||
-- | Translate all selected points by the given vector.
|
-- | Translate all selected points by the given vector.
|
||||||
--
|
--
|
||||||
|
@ -330,7 +339,7 @@ translateSelection mode t doc =
|
||||||
updateStrokePoint :: HasType FocusState pt => Unique -> StrokePoint pt -> State UpdateInfo ( StrokePoint pt )
|
updateStrokePoint :: HasType FocusState pt => Unique -> StrokePoint pt -> State UpdateInfo ( StrokePoint pt )
|
||||||
updateStrokePoint uniq pt
|
updateStrokePoint uniq pt
|
||||||
| Selected <- view _selection pt
|
| Selected <- view _selection pt
|
||||||
= recordPointUpdate uniq pt
|
= recordPointUpdate True uniq pt
|
||||||
$> pt { coords = t • coords pt }
|
$> pt { coords = t • coords pt }
|
||||||
| otherwise
|
| otherwise
|
||||||
= pure pt
|
= pure pt
|
||||||
|
@ -339,16 +348,15 @@ translateSelection mode t doc =
|
||||||
--
|
--
|
||||||
-- Returns the updated document, together with info about how many points were deleted.
|
-- Returns the updated document, together with info about how many points were deleted.
|
||||||
deleteSelected :: Mode -> Document -> ( Document, UpdateInfo )
|
deleteSelected :: Mode -> Document -> ( Document, UpdateInfo )
|
||||||
deleteSelected mode doc = ( newDoc, updateInfo )
|
deleteSelected mode doc = deletionResult
|
||||||
where
|
where
|
||||||
|
|
||||||
newDoc :: Document
|
deletionResult :: ( Document, UpdateInfo )
|
||||||
updateInfo :: UpdateInfo
|
deletionResult
|
||||||
( ( newDoc, _ ), updateInfo )
|
= fst . runIdentity . ( `Tardis.runTardisT` ( False, False ) ) . ( `runStateT` mempty )
|
||||||
= runIdentity . ( `runStateT` mempty ) . ( `Tardis.runTardisT` ( False, False ) )
|
|
||||||
$ ( field' @"documentContent" . field' @"strokes" . traverse ) updateStroke doc
|
$ ( field' @"documentContent" . field' @"strokes" . traverse ) updateStroke doc
|
||||||
|
|
||||||
updateStroke :: Stroke -> TardisT Bool Bool ( State UpdateInfo ) Stroke
|
updateStroke :: Stroke -> StateT UpdateInfo ( Tardis Bool Bool ) Stroke
|
||||||
updateStroke stroke@( Stroke { strokeVisible, strokeUnique } )
|
updateStroke stroke@( Stroke { strokeVisible, strokeUnique } )
|
||||||
| not strokeVisible
|
| not strokeVisible
|
||||||
= pure stroke
|
= pure stroke
|
||||||
|
@ -365,24 +373,24 @@ deleteSelected mode doc = ( newDoc, updateInfo )
|
||||||
:: forall pt
|
:: forall pt
|
||||||
. HasType FocusState pt
|
. HasType FocusState pt
|
||||||
=> Unique -> Seq ( StrokePoint pt )
|
=> Unique -> Seq ( StrokePoint pt )
|
||||||
-> TardisT Bool Bool ( State UpdateInfo ) ( Seq ( StrokePoint pt ) )
|
-> StateT UpdateInfo ( Tardis Bool Bool ) ( Seq ( StrokePoint pt ) )
|
||||||
updateStrokePoints _ Empty = pure Empty
|
updateStrokePoints _ Empty = pure Empty
|
||||||
updateStrokePoints uniq ( p :<| ps ) = case p of
|
updateStrokePoints uniq ( p :<| ps ) = case p of
|
||||||
PathPoint {}
|
PathPoint {}
|
||||||
| Selected <- selectionState
|
| Selected <- selectionState
|
||||||
-> do
|
-> do
|
||||||
Tardis.sendPast True
|
lift ( Tardis.sendPast True )
|
||||||
Tardis.sendFuture True
|
lift ( Tardis.sendFuture True )
|
||||||
lift ( recordPointUpdate uniq p )
|
recordPointUpdate True uniq p
|
||||||
updateStrokePoints uniq ps
|
updateStrokePoints uniq ps
|
||||||
| otherwise
|
| otherwise
|
||||||
-> do
|
-> do
|
||||||
Tardis.sendPast False
|
lift ( Tardis.sendPast False )
|
||||||
Tardis.sendFuture False
|
lift ( Tardis.sendFuture False )
|
||||||
( p :<| ) <$> updateStrokePoints uniq ps
|
( p :<| ) <$> updateStrokePoints uniq ps
|
||||||
_ -> do
|
_ -> do
|
||||||
prevPathPointDeleted <- Tardis.getPast
|
prevPathPointDeleted <- lift Tardis.getPast
|
||||||
nextPathPointDeleted <- Tardis.getFuture
|
nextPathPointDeleted <- lift Tardis.getFuture
|
||||||
rest <- updateStrokePoints uniq ps
|
rest <- updateStrokePoints uniq ps
|
||||||
let
|
let
|
||||||
-- Control point must be deleted:
|
-- Control point must be deleted:
|
||||||
|
@ -391,17 +399,13 @@ deleteSelected mode doc = ( newDoc, updateInfo )
|
||||||
-- - if the next path point is going to be deleted.
|
-- - if the next path point is going to be deleted.
|
||||||
--
|
--
|
||||||
-- Need to be lazy in "nextPathPointDeleted" to avoid looping.
|
-- Need to be lazy in "nextPathPointDeleted" to avoid looping.
|
||||||
res :: Seq ( StrokePoint pt )
|
needsDeletion :: Bool
|
||||||
stateAction :: State UpdateInfo ()
|
needsDeletion
|
||||||
( res, stateAction )
|
= selectionState == Selected
|
||||||
| selectionState == Selected
|
|
||||||
|| prevPathPointDeleted
|
|| prevPathPointDeleted
|
||||||
|| nextPathPointDeleted
|
|| nextPathPointDeleted
|
||||||
= ( rest, recordPointUpdate uniq p )
|
recordPointUpdate needsDeletion uniq p
|
||||||
| otherwise
|
pure $ if needsDeletion then rest else ( p :<| rest )
|
||||||
= ( p :<| rest, pure () )
|
|
||||||
lift stateAction
|
|
||||||
pure res
|
|
||||||
where
|
where
|
||||||
selectionState :: FocusState
|
selectionState :: FocusState
|
||||||
selectionState = view _selection p
|
selectionState = view _selection p
|
||||||
|
|
Loading…
Reference in a new issue