{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Data.GI.Gtk.ModelView.ForestStore (
ForestStore(..),
forestStoreNew,
forestStoreNewDND,
forestStoreDefaultDragSourceIface,
forestStoreDefaultDragDestIface,
forestStoreGetValue,
forestStoreGetTree,
forestStoreGetForest,
forestStoreLookup,
forestStoreSetValue,
forestStoreInsert,
forestStoreInsertTree,
forestStoreInsertForest,
forestStoreRemove,
forestStoreClear,
forestStoreChange,
forestStoreChangeM,
) where
import Prelude ()
import Prelude.Compat
import Data.Bits
import Data.Word (Word32)
import Data.Int (Int32)
import Data.Maybe ( fromMaybe, isJust )
import Data.Tree
import Control.Monad ((>=>), when)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Exception (assert)
import Data.IORef
import Foreign.ForeignPtr (ForeignPtr)
import Data.GI.Base.BasicTypes
(TypedObject(..), ManagedPtr(..), GObject)
import Data.GI.Base.ManagedPtr (withManagedPtr)
import Data.GI.Base.Overloading (HasParentTypes, ParentTypes)
import Data.GI.Gtk.ModelView.Types
import Data.GI.Gtk.ModelView.CustomStore
(customStoreGetStamp, customStoreGetPrivate,
TreeModelIface(..), customStoreNew, DragDestIface(..),
DragSourceIface(..), CustomStore(..), customStoreInvalidateIters)
import GI.GObject.Objects.Object (Object(..))
import GI.Gtk.Interfaces.TreeModel
(treeModelRowDeleted, treeModelRowInserted,
treeModelRowChanged, toTreeModel, TreeModel(..), IsTreeModel(..),
treeModelRowHasChildToggled)
import GI.Gtk.Functions (treeSetRowDragData, treeGetRowDragData)
import GI.Gtk.Structs.TreePath
(TreePath)
import GI.Gtk.Structs.TreeIter
(getTreeIterUserData3, getTreeIterUserData2, getTreeIterUserData,
getTreeIterStamp, setTreeIterUserData3, setTreeIterUserData2,
setTreeIterUserData, setTreeIterStamp, TreeIter(..))
import Data.GI.Base (get, new)
import Unsafe.Coerce (unsafeCoerce)
data ForestStoreIter = ForestStoreIter Int32 Word32 Word32 Word32
fromForestStoreIter :: MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter :: forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter (ForestStoreIter Int32
s Word32
u1 Word32
u2 Word32
u3) = do
TreeIter
i <- (ManagedPtr TreeIter -> TreeIter)
-> [AttrOp TreeIter 'AttrSet] -> m TreeIter
forall a (tag :: AttrOpTag) (m :: * -> *).
(Constructible a tag, MonadIO m) =>
(ManagedPtr a -> a) -> [AttrOp a tag] -> m a
forall (m :: * -> *).
MonadIO m =>
(ManagedPtr TreeIter -> TreeIter)
-> [AttrOp TreeIter 'AttrSet] -> m TreeIter
new ManagedPtr TreeIter -> TreeIter
TreeIter []
TreeIter -> Int32 -> m ()
forall (m :: * -> *). MonadIO m => TreeIter -> Int32 -> m ()
setTreeIterStamp TreeIter
i Int32
s
TreeIter -> Ptr () -> m ()
forall (m :: * -> *). MonadIO m => TreeIter -> Ptr () -> m ()
setTreeIterUserData TreeIter
i (Ptr () -> m ()) -> Ptr () -> m ()
forall a b. (a -> b) -> a -> b
$ Word32 -> Ptr ()
forall a b. a -> b
unsafeCoerce Word32
u1
TreeIter -> Ptr () -> m ()
forall (m :: * -> *). MonadIO m => TreeIter -> Ptr () -> m ()
setTreeIterUserData2 TreeIter
i (Ptr () -> m ()) -> Ptr () -> m ()
forall a b. (a -> b) -> a -> b
$ Word32 -> Ptr ()
forall a b. a -> b
unsafeCoerce Word32
u2
TreeIter -> Ptr () -> m ()
forall (m :: * -> *). MonadIO m => TreeIter -> Ptr () -> m ()
setTreeIterUserData3 TreeIter
i (Ptr () -> m ()) -> Ptr () -> m ()
forall a b. (a -> b) -> a -> b
$ Word32 -> Ptr ()
forall a b. a -> b
unsafeCoerce Word32
u3
TreeIter -> m TreeIter
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return TreeIter
i
toForestStoreIter :: MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter :: forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter TreeIter
iter = do
Int32
stamp <- TreeIter -> m Int32
forall (m :: * -> *). MonadIO m => TreeIter -> m Int32
getTreeIterStamp TreeIter
iter
Ptr ()
u1 <- TreeIter -> m (Ptr ())
forall (m :: * -> *). MonadIO m => TreeIter -> m (Ptr ())
getTreeIterUserData TreeIter
iter
Ptr ()
u2 <- TreeIter -> m (Ptr ())
forall (m :: * -> *). MonadIO m => TreeIter -> m (Ptr ())
getTreeIterUserData2 TreeIter
iter
Ptr ()
u3 <- TreeIter -> m (Ptr ())
forall (m :: * -> *). MonadIO m => TreeIter -> m (Ptr ())
getTreeIterUserData3 TreeIter
iter
ForestStoreIter -> m ForestStoreIter
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForestStoreIter -> m ForestStoreIter)
-> ForestStoreIter -> m ForestStoreIter
forall a b. (a -> b) -> a -> b
$ Int32 -> Word32 -> Word32 -> Word32 -> ForestStoreIter
ForestStoreIter Int32
stamp (Ptr () -> Word32
forall a b. a -> b
unsafeCoerce Ptr ()
u1) (Ptr () -> Word32
forall a b. a -> b
unsafeCoerce Ptr ()
u2) (Ptr () -> Word32
forall a b. a -> b
unsafeCoerce Ptr ()
u3)
forestStoreIterSetStamp :: ForestStoreIter -> Int32 -> ForestStoreIter
forestStoreIterSetStamp :: ForestStoreIter -> Int32 -> ForestStoreIter
forestStoreIterSetStamp (ForestStoreIter Int32
_ Word32
a Word32
b Word32
c) Int32
s = Int32 -> Word32 -> Word32 -> Word32 -> ForestStoreIter
ForestStoreIter Int32
s Word32
a Word32
b Word32
c
newtype ForestStore a = ForestStore (ManagedPtr (CustomStore (IORef (Store a)) a))
mkForestStore :: CustomStore (IORef (Store a)) a -> ForestStore a
mkForestStore :: forall a. CustomStore (IORef (Store a)) a -> ForestStore a
mkForestStore (CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
ptr) = ManagedPtr (CustomStore (IORef (Store a)) a) -> ForestStore a
forall a.
ManagedPtr (CustomStore (IORef (Store a)) a) -> ForestStore a
ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
ptr
instance HasParentTypes (ForestStore a)
type instance ParentTypes (ForestStore a) = '[TreeModel]
instance TypedObject (ForestStore a) where
glibType :: IO GType
glibType = forall a. TypedObject a => IO GType
glibType @TreeModel
instance GObject (ForestStore a)
instance IsTypedTreeModel ForestStore
type Depth = [Int]
data Store a = Store {
forall a. Store a -> Depth
depth :: Depth,
forall a. Store a -> Cache a
content :: Cache a
}
forestStoreNew :: MonadIO m => Forest a -> m (ForestStore a)
forestStoreNew :: forall (m :: * -> *) a. MonadIO m => Forest a -> m (ForestStore a)
forestStoreNew Forest a
forest = Forest a
-> Maybe (DragSourceIface ForestStore a)
-> Maybe (DragDestIface ForestStore a)
-> m (ForestStore a)
forall (m :: * -> *) a.
MonadIO m =>
Forest a
-> Maybe (DragSourceIface ForestStore a)
-> Maybe (DragDestIface ForestStore a)
-> m (ForestStore a)
forestStoreNewDND Forest a
forest
(DragSourceIface ForestStore a
-> Maybe (DragSourceIface ForestStore a)
forall a. a -> Maybe a
Just DragSourceIface ForestStore a
forall row. DragSourceIface ForestStore row
forestStoreDefaultDragSourceIface)
(DragDestIface ForestStore a -> Maybe (DragDestIface ForestStore a)
forall a. a -> Maybe a
Just DragDestIface ForestStore a
forall row. DragDestIface ForestStore row
forestStoreDefaultDragDestIface)
forestStoreNewDND :: MonadIO m => Forest a
-> Maybe (DragSourceIface ForestStore a)
-> Maybe (DragDestIface ForestStore a)
-> m (ForestStore a)
forestStoreNewDND :: forall (m :: * -> *) a.
MonadIO m =>
Forest a
-> Maybe (DragSourceIface ForestStore a)
-> Maybe (DragDestIface ForestStore a)
-> m (ForestStore a)
forestStoreNewDND Forest a
forest Maybe (DragSourceIface ForestStore a)
mDSource Maybe (DragDestIface ForestStore a)
mDDest = IO (ForestStore a) -> m (ForestStore a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ForestStore a) -> m (ForestStore a))
-> IO (ForestStore a) -> m (ForestStore a)
forall a b. (a -> b) -> a -> b
$ do
(IORef (Store a)
storeRef :: IORef (Store a)) <- Store a -> IO (IORef (Store a))
forall a. a -> IO (IORef a)
newIORef Store {
depth :: Depth
depth = Forest a -> Depth
forall a. Forest a -> Depth
calcForestDepth Forest a
forest,
content :: Cache a
content = Forest a -> Cache a
forall a. Forest a -> Cache a
storeToCache Forest a
forest
}
let withStore :: (Store a -> IO result) -> IO result
withStore :: forall result. (Store a -> IO result) -> IO result
withStore Store a -> IO result
f = IORef (Store a) -> IO (Store a)
forall a. IORef a -> IO a
readIORef IORef (Store a)
storeRef IO (Store a) -> (Store a -> IO result) -> IO result
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Store a -> IO result
f
withStoreUpdateCache :: (Store a -> (result, Cache a)) -> IO result
withStoreUpdateCache :: forall result. (Store a -> (result, Cache a)) -> IO result
withStoreUpdateCache Store a -> (result, Cache a)
f = do
Store a
store <- IORef (Store a) -> IO (Store a)
forall a. IORef a -> IO a
readIORef IORef (Store a)
storeRef
let (result
result, Cache a
cache') = Store a -> (result, Cache a)
f Store a
store
IORef (Store a) -> Store a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Store a)
storeRef Store a
store { content :: Cache a
content = Cache a
cache' }
result -> IO result
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return result
result
IORef (Store a)
-> (CustomStore (IORef (Store a)) a -> ForestStore a)
-> TreeModelIface a
-> Maybe (DragSourceIface ForestStore a)
-> Maybe (DragDestIface ForestStore a)
-> IO (ForestStore a)
forall (m :: * -> *) (model :: * -> *) row private.
(MonadIO m, IsTreeModel (model row), IsTypedTreeModel model) =>
private
-> (CustomStore private row -> model row)
-> TreeModelIface row
-> Maybe (DragSourceIface model row)
-> Maybe (DragDestIface model row)
-> m (model row)
customStoreNew IORef (Store a)
storeRef CustomStore (IORef (Store a)) a -> ForestStore a
forall a. CustomStore (IORef (Store a)) a -> ForestStore a
mkForestStore TreeModelIface {
treeModelIfaceGetFlags :: IO [TreeModelFlags]
treeModelIfaceGetFlags = [TreeModelFlags] -> IO [TreeModelFlags]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [],
treeModelIfaceGetIter :: TreePath -> IO (Maybe TreeIter)
treeModelIfaceGetIter = \TreePath
path -> (Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter)
forall result. (Store a -> IO result) -> IO result
withStore ((Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter))
-> (Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter)
forall a b. (a -> b) -> a -> b
$
\Store { depth :: forall a. Store a -> Depth
depth = Depth
d } -> Depth -> [Int32] -> Maybe ForestStoreIter
fromPath Depth
d ([Int32] -> Maybe ForestStoreIter)
-> IO [Int32] -> IO (Maybe ForestStoreIter)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TreePath -> IO [Int32]
forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
treePathGetIndices' TreePath
path IO (Maybe ForestStoreIter)
-> (Maybe ForestStoreIter -> IO (Maybe TreeIter))
-> IO (Maybe TreeIter)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ForestStoreIter -> IO TreeIter)
-> Maybe ForestStoreIter -> IO (Maybe TreeIter)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Maybe a -> m (Maybe b)
mapM ForestStoreIter -> IO TreeIter
forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter,
treeModelIfaceGetPath :: TreeIter -> IO TreePath
treeModelIfaceGetPath = TreeIter -> IO ForestStoreIter
forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter (TreeIter -> IO ForestStoreIter)
-> (ForestStoreIter -> IO TreePath) -> TreeIter -> IO TreePath
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ForestStoreIter
iter -> (Store a -> IO TreePath) -> IO TreePath
forall result. (Store a -> IO result) -> IO result
withStore ((Store a -> IO TreePath) -> IO TreePath)
-> (Store a -> IO TreePath) -> IO TreePath
forall a b. (a -> b) -> a -> b
$
\Store { depth :: forall a. Store a -> Depth
depth = Depth
d } -> [Int32] -> IO TreePath
forall (m :: * -> *). MonadIO m => [Int32] -> m TreePath
treePathNewFromIndices' ([Int32] -> IO TreePath) -> [Int32] -> IO TreePath
forall a b. (a -> b) -> a -> b
$ Depth -> ForestStoreIter -> [Int32]
toPath Depth
d ForestStoreIter
iter,
treeModelIfaceGetRow :: TreeIter -> IO a
treeModelIfaceGetRow = TreeIter -> IO ForestStoreIter
forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter (TreeIter -> IO ForestStoreIter)
-> (ForestStoreIter -> IO a) -> TreeIter -> IO a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ForestStoreIter
iter -> (Store a -> (a, Cache a)) -> IO a
forall result. (Store a -> (result, Cache a)) -> IO result
withStoreUpdateCache ((Store a -> (a, Cache a)) -> IO a)
-> (Store a -> (a, Cache a)) -> IO a
forall a b. (a -> b) -> a -> b
$
\Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } ->
case Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
checkSuccess Depth
d ForestStoreIter
iter Cache a
cache of
(Bool
True, cache' :: Cache a
cache'@((ForestStoreIter
_, (Node { rootLabel :: forall a. Tree a -> a
rootLabel = a
val }:Forest a
_)):Cache a
_)) ->
(a
val, Cache a
cache')
(Bool, Cache a)
_ -> [Char] -> (a, Cache a)
forall a. (?callStack::CallStack) => [Char] -> a
error [Char]
"ForestStore.getRow: iter does not refer to a valid entry",
treeModelIfaceIterNext :: TreeIter -> IO (Maybe TreeIter)
treeModelIfaceIterNext = TreeIter -> IO ForestStoreIter
forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter (TreeIter -> IO ForestStoreIter)
-> (ForestStoreIter -> IO (Maybe TreeIter))
-> TreeIter
-> IO (Maybe TreeIter)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ForestStoreIter
iter -> (Store a -> (Maybe ForestStoreIter, Cache a))
-> IO (Maybe ForestStoreIter)
forall result. (Store a -> (result, Cache a)) -> IO result
withStoreUpdateCache (
\Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } -> Depth
-> ForestStoreIter -> Cache a -> (Maybe ForestStoreIter, Cache a)
forall a.
Depth
-> ForestStoreIter -> Cache a -> (Maybe ForestStoreIter, Cache a)
iterNext Depth
d ForestStoreIter
iter Cache a
cache) IO (Maybe ForestStoreIter)
-> (Maybe ForestStoreIter -> IO (Maybe TreeIter))
-> IO (Maybe TreeIter)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ForestStoreIter -> IO TreeIter)
-> Maybe ForestStoreIter -> IO (Maybe TreeIter)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Maybe a -> m (Maybe b)
mapM ForestStoreIter -> IO TreeIter
forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter,
treeModelIfaceIterChildren :: Maybe TreeIter -> IO (Maybe TreeIter)
treeModelIfaceIterChildren = \Maybe TreeIter
mIter -> do
ForestStoreIter
iter <- IO ForestStoreIter
-> (TreeIter -> IO ForestStoreIter)
-> Maybe TreeIter
-> IO ForestStoreIter
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (ForestStoreIter -> IO ForestStoreIter
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ForestStoreIter
invalidIter) TreeIter -> IO ForestStoreIter
forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter Maybe TreeIter
mIter
(Store a -> (Maybe ForestStoreIter, Cache a))
-> IO (Maybe ForestStoreIter)
forall result. (Store a -> (result, Cache a)) -> IO result
withStoreUpdateCache (
\Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } ->
Depth
-> Int
-> ForestStoreIter
-> Cache a
-> (Maybe ForestStoreIter, Cache a)
forall a.
Depth
-> Int
-> ForestStoreIter
-> Cache a
-> (Maybe ForestStoreIter, Cache a)
iterNthChild Depth
d Int
0 ForestStoreIter
iter Cache a
cache) IO (Maybe ForestStoreIter)
-> (Maybe ForestStoreIter -> IO (Maybe TreeIter))
-> IO (Maybe TreeIter)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ForestStoreIter -> IO TreeIter)
-> Maybe ForestStoreIter -> IO (Maybe TreeIter)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Maybe a -> m (Maybe b)
mapM ForestStoreIter -> IO TreeIter
forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter,
treeModelIfaceIterHasChild :: TreeIter -> IO Bool
treeModelIfaceIterHasChild = TreeIter -> IO ForestStoreIter
forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter (TreeIter -> IO ForestStoreIter)
-> (ForestStoreIter -> IO Bool) -> TreeIter -> IO Bool
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ForestStoreIter
iter -> (Store a -> (Bool, Cache a)) -> IO Bool
forall result. (Store a -> (result, Cache a)) -> IO result
withStoreUpdateCache ((Store a -> (Bool, Cache a)) -> IO Bool)
-> (Store a -> (Bool, Cache a)) -> IO Bool
forall a b. (a -> b) -> a -> b
$
\Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } ->
let (Maybe ForestStoreIter
mIter, Cache a
cache') = Depth
-> Int
-> ForestStoreIter
-> Cache a
-> (Maybe ForestStoreIter, Cache a)
forall a.
Depth
-> Int
-> ForestStoreIter
-> Cache a
-> (Maybe ForestStoreIter, Cache a)
iterNthChild Depth
d Int
0 ForestStoreIter
iter Cache a
cache
in (Maybe ForestStoreIter -> Bool
forall a. Maybe a -> Bool
isJust Maybe ForestStoreIter
mIter, Cache a
cache'),
treeModelIfaceIterNChildren :: Maybe TreeIter -> IO Int
treeModelIfaceIterNChildren = (TreeIter -> IO ForestStoreIter)
-> Maybe TreeIter -> IO (Maybe ForestStoreIter)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Maybe a -> m (Maybe b)
mapM TreeIter -> IO ForestStoreIter
forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter (Maybe TreeIter -> IO (Maybe ForestStoreIter))
-> (Maybe ForestStoreIter -> IO Int) -> Maybe TreeIter -> IO Int
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \Maybe ForestStoreIter
mIter -> (Store a -> (Int, Cache a)) -> IO Int
forall result. (Store a -> (result, Cache a)) -> IO result
withStoreUpdateCache ((Store a -> (Int, Cache a)) -> IO Int)
-> (Store a -> (Int, Cache a)) -> IO Int
forall a b. (a -> b) -> a -> b
$
\Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } ->
let iter :: ForestStoreIter
iter = ForestStoreIter -> Maybe ForestStoreIter -> ForestStoreIter
forall a. a -> Maybe a -> a
fromMaybe ForestStoreIter
invalidIter Maybe ForestStoreIter
mIter
in Depth -> ForestStoreIter -> Cache a -> (Int, Cache a)
forall a. Depth -> ForestStoreIter -> Cache a -> (Int, Cache a)
iterNChildren Depth
d ForestStoreIter
iter Cache a
cache,
treeModelIfaceIterNthChild :: Maybe TreeIter -> Int -> IO (Maybe TreeIter)
treeModelIfaceIterNthChild = \Maybe TreeIter
mIter Int
idx -> do
ForestStoreIter
iter <- IO ForestStoreIter
-> (TreeIter -> IO ForestStoreIter)
-> Maybe TreeIter
-> IO ForestStoreIter
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (ForestStoreIter -> IO ForestStoreIter
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ForestStoreIter
invalidIter) TreeIter -> IO ForestStoreIter
forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter Maybe TreeIter
mIter
(Store a -> (Maybe ForestStoreIter, Cache a))
-> IO (Maybe ForestStoreIter)
forall result. (Store a -> (result, Cache a)) -> IO result
withStoreUpdateCache (
\Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } ->
Depth
-> Int
-> ForestStoreIter
-> Cache a
-> (Maybe ForestStoreIter, Cache a)
forall a.
Depth
-> Int
-> ForestStoreIter
-> Cache a
-> (Maybe ForestStoreIter, Cache a)
iterNthChild Depth
d Int
idx ForestStoreIter
iter Cache a
cache) IO (Maybe ForestStoreIter)
-> (Maybe ForestStoreIter -> IO (Maybe TreeIter))
-> IO (Maybe TreeIter)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ForestStoreIter -> IO TreeIter)
-> Maybe ForestStoreIter -> IO (Maybe TreeIter)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Maybe a -> m (Maybe b)
mapM ForestStoreIter -> IO TreeIter
forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter,
treeModelIfaceIterParent :: TreeIter -> IO (Maybe TreeIter)
treeModelIfaceIterParent = TreeIter -> IO ForestStoreIter
forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
toForestStoreIter (TreeIter -> IO ForestStoreIter)
-> (ForestStoreIter -> IO (Maybe TreeIter))
-> TreeIter
-> IO (Maybe TreeIter)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \ForestStoreIter
iter -> (Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter)
forall result. (Store a -> IO result) -> IO result
withStore ((Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter))
-> (Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter)
forall a b. (a -> b) -> a -> b
$
\Store { depth :: forall a. Store a -> Depth
depth = Depth
d } -> (ForestStoreIter -> IO TreeIter)
-> Maybe ForestStoreIter -> IO (Maybe TreeIter)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Maybe a -> m (Maybe b)
mapM ForestStoreIter -> IO TreeIter
forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter (Depth -> ForestStoreIter -> Maybe ForestStoreIter
iterParent Depth
d ForestStoreIter
iter),
treeModelIfaceRefNode :: TreeIter -> IO ()
treeModelIfaceRefNode = \TreeIter
_ -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (),
treeModelIfaceUnrefNode :: TreeIter -> IO ()
treeModelIfaceUnrefNode = \TreeIter
_ -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
} Maybe (DragSourceIface ForestStore a)
mDSource Maybe (DragDestIface ForestStore a)
mDDest
forestStoreDefaultDragSourceIface :: DragSourceIface ForestStore row
forestStoreDefaultDragSourceIface :: forall row. DragSourceIface ForestStore row
forestStoreDefaultDragSourceIface = DragSourceIface {
customDragSourceRowDraggable :: ForestStore row -> TreePath -> IO Bool
customDragSourceRowDraggable = \ForestStore row
_ TreePath
_-> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True,
customDragSourceDragDataGet :: ForestStore row -> TreePath -> SelectionData -> IO Bool
customDragSourceDragDataGet = \ForestStore row
model TreePath
path SelectionData
sel -> SelectionData -> ForestStore row -> TreePath -> IO Bool
forall (m :: * -> *) a.
(?callStack::CallStack, MonadIO m, IsTreeModel a) =>
SelectionData -> a -> TreePath -> m Bool
treeSetRowDragData SelectionData
sel ForestStore row
model TreePath
path,
customDragSourceDragDataDelete :: ForestStore row -> TreePath -> IO Bool
customDragSourceDragDataDelete = \ForestStore row
model TreePath
path -> TreePath -> IO [Int32]
forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
treePathGetIndices' TreePath
path IO [Int32] -> ([Int32] -> IO Bool) -> IO Bool
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \dest :: [Int32]
dest@(Int32
_:[Int32]
_) -> do
IO Bool -> IO Bool
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> IO Bool) -> IO Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ ForestStore row -> TreePath -> IO Bool
forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> m Bool
forestStoreRemove ForestStore row
model TreePath
path
Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
}
forestStoreDefaultDragDestIface :: DragDestIface ForestStore row
forestStoreDefaultDragDestIface :: forall row. DragDestIface ForestStore row
forestStoreDefaultDragDestIface = DragDestIface {
customDragDestRowDropPossible :: ForestStore row -> TreePath -> SelectionData -> IO Bool
customDragDestRowDropPossible = \ForestStore row
model TreePath
path SelectionData
sel -> do
(Bool, Maybe TreeModel, Maybe TreePath)
mModelPath <- SelectionData -> IO (Bool, Maybe TreeModel, Maybe TreePath)
forall (m :: * -> *).
(?callStack::CallStack, MonadIO m) =>
SelectionData -> m (Bool, Maybe TreeModel, Maybe TreePath)
treeGetRowDragData SelectionData
sel
case (Bool, Maybe TreeModel, Maybe TreePath)
mModelPath of
(Bool
True, Just TreeModel
model', Maybe TreePath
source) -> do
TreeModel
tm <- ForestStore row -> IO TreeModel
forall (m :: * -> *) o.
(MonadIO m, IsTreeModel o) =>
o -> m TreeModel
toTreeModel ForestStore row
model
TreeModel -> (Ptr TreeModel -> IO Bool) -> IO Bool
forall a c.
(?callStack::CallStack, ManagedPtrNewtype a) =>
a -> (Ptr a -> IO c) -> IO c
withManagedPtr TreeModel
tm ((Ptr TreeModel -> IO Bool) -> IO Bool)
-> (Ptr TreeModel -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr TreeModel
m ->
TreeModel -> (Ptr TreeModel -> IO Bool) -> IO Bool
forall a c.
(?callStack::CallStack, ManagedPtrNewtype a) =>
a -> (Ptr a -> IO c) -> IO c
withManagedPtr TreeModel
model' ((Ptr TreeModel -> IO Bool) -> IO Bool)
-> (Ptr TreeModel -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr TreeModel
m' -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Ptr TreeModel
mPtr TreeModel -> Ptr TreeModel -> Bool
forall a. Eq a => a -> a -> Bool
==Ptr TreeModel
m')
(Bool, Maybe TreeModel, Maybe TreePath)
_ -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False,
customDragDestDragDataReceived :: ForestStore row -> TreePath -> SelectionData -> IO Bool
customDragDestDragDataReceived = \ForestStore row
model TreePath
path SelectionData
sel -> do
dest :: [Int32]
dest@(Int32
_:[Int32]
_) <- TreePath -> IO [Int32]
forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
treePathGetIndices' TreePath
path
(Bool, Maybe TreeModel, Maybe TreePath)
mModelPath <- SelectionData -> IO (Bool, Maybe TreeModel, Maybe TreePath)
forall (m :: * -> *).
(?callStack::CallStack, MonadIO m) =>
SelectionData -> m (Bool, Maybe TreeModel, Maybe TreePath)
treeGetRowDragData SelectionData
sel
case (Bool, Maybe TreeModel, Maybe TreePath)
mModelPath of
(Bool
True, Just TreeModel
model', Just TreePath
path) -> do
source :: [Int32]
source@(Int32
_:[Int32]
_) <- TreePath -> IO [Int32]
forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
treePathGetIndices' TreePath
path
TreeModel
tm <- ForestStore row -> IO TreeModel
forall (m :: * -> *) o.
(MonadIO m, IsTreeModel o) =>
o -> m TreeModel
toTreeModel ForestStore row
model
TreeModel -> (Ptr TreeModel -> IO Bool) -> IO Bool
forall a c.
(?callStack::CallStack, ManagedPtrNewtype a) =>
a -> (Ptr a -> IO c) -> IO c
withManagedPtr TreeModel
tm ((Ptr TreeModel -> IO Bool) -> IO Bool)
-> (Ptr TreeModel -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr TreeModel
m ->
TreeModel -> (Ptr TreeModel -> IO Bool) -> IO Bool
forall a c.
(?callStack::CallStack, ManagedPtrNewtype a) =>
a -> (Ptr a -> IO c) -> IO c
withManagedPtr TreeModel
model' ((Ptr TreeModel -> IO Bool) -> IO Bool)
-> (Ptr TreeModel -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr TreeModel
m' ->
if Ptr TreeModel
mPtr TreeModel -> Ptr TreeModel -> Bool
forall a. Eq a => a -> a -> Bool
/=Ptr TreeModel
m' then Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
else do
Tree row
row <- ForestStore row -> TreePath -> IO (Tree row)
forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> m (Tree a)
forestStoreGetTree ForestStore row
model (TreePath -> IO (Tree row)) -> IO TreePath -> IO (Tree row)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [Int32] -> IO TreePath
forall (m :: * -> *). MonadIO m => [Int32] -> m TreePath
treePathNewFromIndices' [Int32]
source
TreePath
initPath <- [Int32] -> IO TreePath
forall (m :: * -> *). MonadIO m => [Int32] -> m TreePath
treePathNewFromIndices' ([Int32] -> [Int32]
forall a. (?callStack::CallStack) => [a] -> [a]
init [Int32]
dest)
ForestStore row -> TreePath -> Int -> Tree row -> IO ()
forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> Int -> Tree a -> m ()
forestStoreInsertTree ForestStore row
model TreePath
initPath (Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> Int) -> Int32 -> Int
forall a b. (a -> b) -> a -> b
$ [Int32] -> Int32
forall a. (?callStack::CallStack) => [a] -> a
last [Int32]
dest) Tree row
row
Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
(Bool, Maybe TreeModel, Maybe TreePath)
_ -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
}
bitsNeeded :: Word32 -> Int
bitsNeeded :: Word32 -> Int
bitsNeeded Word32
n = Int -> Word32 -> Int
forall {t} {t}. (Num t, Num t, Bits t) => t -> t -> t
bitsNeeded' Int
0 Word32
n
where bitsNeeded' :: t -> t -> t
bitsNeeded' t
b t
0 = t
b
bitsNeeded' t
b t
n = t -> t -> t
bitsNeeded' (t
bt -> t -> t
forall a. Num a => a -> a -> a
+t
1) (t
n t -> Int -> t
forall a. Bits a => a -> Int -> a
`shiftR` Int
1)
getBitSlice :: ForestStoreIter -> Int -> Int -> Word32
getBitSlice :: ForestStoreIter -> Int -> Int -> Word32
getBitSlice (ForestStoreIter Int32
_ Word32
a Word32
b Word32
c) Int
off Int
count =
Word32 -> Int -> Int -> Word32
getBitSliceWord Word32
a Int
off Int
count
Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Int -> Word32
getBitSliceWord Word32
b (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
32) Int
count
Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Int -> Word32
getBitSliceWord Word32
c (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
64) Int
count
where getBitSliceWord :: Word32 -> Int -> Int -> Word32
getBitSliceWord :: Word32 -> Int -> Int -> Word32
getBitSliceWord Word32
word Int
off Int
count =
Word32
word Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shift` (-Int
off) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. (Word32
1 Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
count Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
1)
setBitSlice :: ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
setBitSlice :: ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
setBitSlice (ForestStoreIter Int32
stamp Word32
a Word32
b Word32
c) Int
off Int
count Word32
value =
Bool -> ForestStoreIter -> ForestStoreIter
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Word32
value Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
< Word32
1 Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
count) (ForestStoreIter -> ForestStoreIter)
-> ForestStoreIter -> ForestStoreIter
forall a b. (a -> b) -> a -> b
$
Int32 -> Word32 -> Word32 -> Word32 -> ForestStoreIter
ForestStoreIter Int32
stamp
(Word32 -> Int -> Int -> Word32 -> Word32
setBitSliceWord Word32
a Int
off Int
count Word32
value)
(Word32 -> Int -> Int -> Word32 -> Word32
setBitSliceWord Word32
b (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
32) Int
count Word32
value)
(Word32 -> Int -> Int -> Word32 -> Word32
setBitSliceWord Word32
c (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
64) Int
count Word32
value)
where setBitSliceWord :: Word32 -> Int -> Int -> Word32 -> Word32
setBitSliceWord :: Word32 -> Int -> Int -> Word32 -> Word32
setBitSliceWord Word32
word Int
off Int
count Word32
value =
let mask :: Word32
mask = (Word32
1 Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
count Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
1) Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shift` Int
off
in (Word32
word Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32 -> Word32
forall a. Bits a => a -> a
complement Word32
mask) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. (Word32
value Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shift` Int
off)
invalidIter :: ForestStoreIter
invalidIter :: ForestStoreIter
invalidIter = Int32 -> Word32 -> Word32 -> Word32 -> ForestStoreIter
ForestStoreIter Int32
0 Word32
0 Word32
0 Word32
0
calcForestDepth :: Forest a -> Depth
calcForestDepth :: forall a. Forest a -> Depth
calcForestDepth Forest a
f = (Word32 -> Int) -> [Word32] -> Depth
forall a b. (a -> b) -> [a] -> [b]
map Word32 -> Int
bitsNeeded ([Word32] -> Depth) -> [Word32] -> Depth
forall a b. (a -> b) -> a -> b
$
(Word32 -> Bool) -> [Word32] -> [Word32]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
/=Word32
0) ([Word32] -> [Word32]) -> [Word32] -> [Word32]
forall a b. (a -> b) -> a -> b
$
(Tree a -> [Word32] -> [Word32])
-> [Word32] -> Forest a -> [Word32]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tree a -> [Word32] -> [Word32]
forall {a} {a}. (Num a, Ord a) => Tree a -> [a] -> [a]
calcTreeDepth (Word32 -> [Word32]
forall a. a -> [a]
repeat Word32
0) Forest a
f
where
calcTreeDepth :: Tree a -> [a] -> [a]
calcTreeDepth Node { subForest :: forall a. Tree a -> [Tree a]
subForest = [Tree a]
f } (a
d:[a]
ds) =
(a
da -> a -> a
forall a. Num a => a -> a -> a
+a
1)a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> a -> a) -> [a] -> [a] -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> a -> a
forall a. Ord a => a -> a -> a
max [a]
ds ((Tree a -> [a] -> [a]) -> [a] -> [Tree a] -> [a]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tree a -> [a] -> [a]
calcTreeDepth (a -> [a]
forall a. a -> [a]
repeat a
0) [Tree a]
f)
toPath :: Depth -> ForestStoreIter -> [Int32]
toPath :: Depth -> ForestStoreIter -> [Int32]
toPath Depth
d ForestStoreIter
iter = Int -> Depth -> [Int32]
gP Int
0 Depth
d
where
gP :: Int -> Depth -> [Int32]
gP Int
pos [] = []
gP Int
pos (Int
d:Depth
ds) = let idx :: Word32
idx = ForestStoreIter -> Int -> Int -> Word32
getBitSlice ForestStoreIter
iter Int
pos Int
d in
if Word32
idxWord32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
0 then [] else Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
idxWord32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
-Word32
1) Int32 -> [Int32] -> [Int32]
forall a. a -> [a] -> [a]
: Int -> Depth -> [Int32]
gP (Int
posInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) Depth
ds
fromPath :: Depth -> [Int32] -> Maybe ForestStoreIter
fromPath :: Depth -> [Int32] -> Maybe ForestStoreIter
fromPath = Int -> ForestStoreIter -> Depth -> [Int32] -> Maybe ForestStoreIter
forall {a}.
Integral a =>
Int -> ForestStoreIter -> Depth -> [a] -> Maybe ForestStoreIter
fP Int
0 ForestStoreIter
invalidIter
where
fP :: Int -> ForestStoreIter -> Depth -> [a] -> Maybe ForestStoreIter
fP Int
pos ForestStoreIter
ti Depth
_ [] = ForestStoreIter -> Maybe ForestStoreIter
forall a. a -> Maybe a
Just ForestStoreIter
ti
fP Int
pos ForestStoreIter
ti [] [a]
_ = Maybe ForestStoreIter
forall a. Maybe a
Nothing
fP Int
pos ForestStoreIter
ti (Int
d:Depth
ds) (a
p:[a]
ps) = let idx :: Word32
idx = a -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
pa -> a -> a
forall a. Num a => a -> a -> a
+a
1) in
if Word32
idx Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Int -> Word32
forall a. Bits a => Int -> a
bit Int
d then Maybe ForestStoreIter
forall a. Maybe a
Nothing else
Int -> ForestStoreIter -> Depth -> [a] -> Maybe ForestStoreIter
fP (Int
posInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) (ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
setBitSlice ForestStoreIter
ti Int
pos Int
d Word32
idx) Depth
ds [a]
ps
type Cache a = [(ForestStoreIter, Forest a)]
storeToCache :: Forest a -> Cache a
storeToCache :: forall a. Forest a -> Cache a
storeToCache [] = []
storeToCache [Tree a]
forest = [(ForestStoreIter
invalidIter, [a -> [Tree a] -> Tree a
forall a. a -> [Tree a] -> Tree a
Node a
forall {a}. a
root [Tree a]
forest])]
where
root :: a
root = [Char] -> a
forall a. (?callStack::CallStack) => [Char] -> a
error [Char]
"ForestStore.storeToCache: accessed non-exitent root of tree"
cacheToStore :: Cache a -> Forest a
cacheToStore :: forall a. Cache a -> Forest a
cacheToStore [] = []
cacheToStore [(ForestStoreIter, Forest a)]
cache = case [(ForestStoreIter, Forest a)] -> (ForestStoreIter, Forest a)
forall a. (?callStack::CallStack) => [a] -> a
last [(ForestStoreIter, Forest a)]
cache of (ForestStoreIter
_, [Node a
_ Forest a
forest]) -> Forest a
forest
advanceCache :: Depth -> ForestStoreIter -> Cache a -> Cache a
advanceCache :: forall a. Depth -> ForestStoreIter -> Cache a -> Cache a
advanceCache Depth
depth ForestStoreIter
goal [] = []
advanceCache Depth
depth ForestStoreIter
goal cache :: [(ForestStoreIter, Forest a)]
cache@((ForestStoreIter
rootIter,Forest a
_):[(ForestStoreIter, Forest a)]
_) =
Int -> Depth -> [(ForestStoreIter, Forest a)]
moveToSameLevel Int
0 Depth
depth
where
moveToSameLevel :: Int -> Depth -> [(ForestStoreIter, Forest a)]
moveToSameLevel Int
pos [] = [(ForestStoreIter, Forest a)]
cache
moveToSameLevel Int
pos (Int
d:Depth
ds) =
let
goalIdx :: Word32
goalIdx = ForestStoreIter -> Int -> Int -> Word32
getBitSlice ForestStoreIter
goal Int
pos Int
d
curIdx :: Word32
curIdx = ForestStoreIter -> Int -> Int -> Word32
getBitSlice ForestStoreIter
rootIter Int
pos Int
d
isNonZero :: Int -> Int -> (ForestStoreIter, b) -> Bool
isNonZero Int
pos Int
d (ForestStoreIter
ti,b
_) = ForestStoreIter -> Int -> Int -> Word32
getBitSlice ForestStoreIter
ti Int
pos Int
dWord32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
/=Word32
0
in
if Word32
goalIdxWord32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
curIdx then Int -> Depth -> [(ForestStoreIter, Forest a)]
moveToSameLevel (Int
posInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) Depth
ds else
if Word32
goalIdxWord32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
0 then ((ForestStoreIter, Forest a) -> Bool)
-> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Int -> Int -> (ForestStoreIter, Forest a) -> Bool
forall {b}. Int -> Int -> (ForestStoreIter, b) -> Bool
isNonZero Int
pos Int
d) [(ForestStoreIter, Forest a)]
cache else
if Word32
curIdxWord32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
0 then Int
-> Depth
-> [(ForestStoreIter, Forest a)]
-> [(ForestStoreIter, Forest a)]
forall a. Int -> Depth -> Cache a -> Cache a
moveToChild Int
pos (Int
dInt -> Depth -> Depth
forall a. a -> [a] -> [a]
:Depth
ds) [(ForestStoreIter, Forest a)]
cache else
if Word32
goalIdxWord32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
<Word32
curIdx then
Int
-> Depth
-> [(ForestStoreIter, Forest a)]
-> [(ForestStoreIter, Forest a)]
forall a. Int -> Depth -> Cache a -> Cache a
moveToChild Int
pos (Int
dInt -> Depth -> Depth
forall a. a -> [a] -> [a]
:Depth
ds) (((ForestStoreIter, Forest a) -> Bool)
-> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Int -> Int -> (ForestStoreIter, Forest a) -> Bool
forall {b}. Int -> Int -> (ForestStoreIter, b) -> Bool
isNonZero Int
pos Int
d) [(ForestStoreIter, Forest a)]
cache)
else let
moveWithinLevel :: Int
-> Int
-> [(ForestStoreIter, Forest a)]
-> [(ForestStoreIter, Forest a)]
moveWithinLevel Int
pos Int
d ((ForestStoreIter
ti,Forest a
forest):[(ForestStoreIter, Forest a)]
parents) = let
diff :: Int
diff = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
goalIdxWord32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
-Word32
curIdx)
(Forest a
dropped, Forest a
remain) = Int -> Forest a -> (Forest a, Forest a)
forall a. Int -> [a] -> ([a], [a])
splitAt Int
diff Forest a
forest
advance :: Int
advance = Forest a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Forest a
dropped
ti' :: ForestStoreIter
ti' = ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
setBitSlice ForestStoreIter
ti Int
pos Int
d (Word32
curIdxWord32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
advance)
in
if Int
advanceInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
diff then Int
-> Depth
-> [(ForestStoreIter, Forest a)]
-> [(ForestStoreIter, Forest a)]
forall a. Int -> Depth -> Cache a -> Cache a
moveToChild (Int
posInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) Depth
ds ((ForestStoreIter
ti',Forest a
remain)(ForestStoreIter, Forest a)
-> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
forall a. a -> [a] -> [a]
:[(ForestStoreIter, Forest a)]
parents)
else (ForestStoreIter
ti',Forest a
remain)(ForestStoreIter, Forest a)
-> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
forall a. a -> [a] -> [a]
:[(ForestStoreIter, Forest a)]
parents
in Int
-> Int
-> [(ForestStoreIter, Forest a)]
-> [(ForestStoreIter, Forest a)]
moveWithinLevel Int
pos Int
d ([(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)])
-> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
forall a b. (a -> b) -> a -> b
$ case Depth
ds of
[] -> [(ForestStoreIter, Forest a)]
cache
(Int
d':Depth
_) -> ((ForestStoreIter, Forest a) -> Bool)
-> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Int -> Int -> (ForestStoreIter, Forest a) -> Bool
forall {b}. Int -> Int -> (ForestStoreIter, b) -> Bool
isNonZero (Int
posInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) Int
d') [(ForestStoreIter, Forest a)]
cache
moveToChild :: Int -> Depth -> Cache a -> Cache a
moveToChild :: forall a. Int -> Depth -> Cache a -> Cache a
moveToChild Int
pos [] Cache a
cache = Cache a
cache
moveToChild Int
pos (Int
d:Depth
ds) cache :: Cache a
cache@((ForestStoreIter
ti,Forest a
forest):Cache a
parents)
| ForestStoreIter -> Int -> Int -> Word32
getBitSlice ForestStoreIter
goal Int
pos Int
d Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
0 = Cache a
cache
| Bool
otherwise = case Forest a
forest of
[] -> Cache a
cache
Node { subForest :: forall a. Tree a -> [Tree a]
subForest = Forest a
children }:Forest a
_ ->
let
childIdx :: Int
childIdx :: Int
childIdx = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ForestStoreIter -> Int -> Int -> Word32
getBitSlice ForestStoreIter
goal Int
pos Int
d)Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1
(Forest a
dropped, Forest a
remain) = Int -> Forest a -> (Forest a, Forest a)
forall a. Int -> [a] -> ([a], [a])
splitAt Int
childIdx Forest a
children
advanced :: Int
advanced = Forest a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Forest a
dropped
ti' :: ForestStoreIter
ti' = ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
setBitSlice ForestStoreIter
ti Int
pos Int
d (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
advancedWord32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+Word32
1)
in if Int
advancedInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
childIdx then ((ForestStoreIter
ti',Forest a
remain)(ForestStoreIter, Forest a) -> Cache a -> Cache a
forall a. a -> [a] -> [a]
:Cache a
cache) else
Int -> Depth -> Cache a -> Cache a
forall a. Int -> Depth -> Cache a -> Cache a
moveToChild (Int
posInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) Depth
ds ((ForestStoreIter
ti',Forest a
remain)(ForestStoreIter, Forest a) -> Cache a -> Cache a
forall a. a -> [a] -> [a]
:Cache a
cache)
checkSuccess :: Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
checkSuccess :: forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
checkSuccess Depth
depth ForestStoreIter
iter Cache a
cache = case Depth -> ForestStoreIter -> Cache a -> Cache a
forall a. Depth -> ForestStoreIter -> Cache a -> Cache a
advanceCache Depth
depth ForestStoreIter
iter Cache a
cache of
cache' :: Cache a
cache'@((ForestStoreIter
cur,Forest a
sibs):Cache a
_) -> (ForestStoreIter -> ForestStoreIter -> Bool
cmp ForestStoreIter
cur ForestStoreIter
iter Bool -> Bool -> Bool
&& Bool -> Bool
not (Forest a -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Forest a
sibs), Cache a
cache')
[] -> (Bool
False, [])
where
cmp :: ForestStoreIter -> ForestStoreIter -> Bool
cmp (ForestStoreIter Int32
_ Word32
a1 Word32
b1 Word32
c1) (ForestStoreIter Int32
_ Word32
a2 Word32
b2 Word32
c2) =
Word32
a1Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
a2 Bool -> Bool -> Bool
&& Word32
b1Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
b2 Bool -> Bool -> Bool
&& Word32
c2Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
c2
getTreeIterLeaf :: Depth -> ForestStoreIter -> (Int, Int, Int)
getTreeIterLeaf :: Depth -> ForestStoreIter -> (Int, Int, Int)
getTreeIterLeaf Depth
ds ForestStoreIter
ti = Int -> Int -> Depth -> (Int, Int, Int)
gTIL Int
0 Int
0 Depth
ds
where
gTIL :: Int -> Int -> Depth -> (Int, Int, Int)
gTIL Int
pos Int
dCur (Int
dNext:Depth
ds)
| ForestStoreIter -> Int -> Int -> Word32
getBitSlice ForestStoreIter
ti (Int
posInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
dCur) Int
dNextWord32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
0 = (Int
pos,Int
dCur,Int
dNext)
| Bool
otherwise = Int -> Int -> Depth -> (Int, Int, Int)
gTIL (Int
posInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
dCur) Int
dNext Depth
ds
gTIL Int
pos Int
d [] = (Int
pos, Int
d, Int
0)
iterNext :: Depth -> ForestStoreIter -> Cache a -> (Maybe ForestStoreIter, Cache a)
iterNext :: forall a.
Depth
-> ForestStoreIter -> Cache a -> (Maybe ForestStoreIter, Cache a)
iterNext Depth
depth ForestStoreIter
iter Cache a
cache = let
(Int
pos,Int
leaf,Int
_child) = Depth -> ForestStoreIter -> (Int, Int, Int)
getTreeIterLeaf Depth
depth ForestStoreIter
iter
curIdx :: Word32
curIdx = ForestStoreIter -> Int -> Int -> Word32
getBitSlice ForestStoreIter
iter Int
pos Int
leaf
nextIdx :: Word32
nextIdx = Word32
curIdxWord32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+Word32
1
nextIter :: ForestStoreIter
nextIter = ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
setBitSlice ForestStoreIter
iter Int
pos Int
leaf Word32
nextIdx
in
if Word32
nextIdxWord32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Int -> Word32
forall a. Bits a => Int -> a
bit Int
leaf then (Maybe ForestStoreIter
forall a. Maybe a
Nothing, Cache a
cache) else
case Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
checkSuccess Depth
depth ForestStoreIter
nextIter Cache a
cache of
(Bool
True, Cache a
cache) -> (ForestStoreIter -> Maybe ForestStoreIter
forall a. a -> Maybe a
Just ForestStoreIter
nextIter, Cache a
cache)
(Bool
False, Cache a
cache) -> (Maybe ForestStoreIter
forall a. Maybe a
Nothing, Cache a
cache)
iterNthChild :: Depth -> Int -> ForestStoreIter -> Cache a ->
(Maybe ForestStoreIter, Cache a)
iterNthChild :: forall a.
Depth
-> Int
-> ForestStoreIter
-> Cache a
-> (Maybe ForestStoreIter, Cache a)
iterNthChild Depth
depth Int
childIdx_ ForestStoreIter
iter Cache a
cache = let
(Int
pos,Int
leaf,Int
child) = Depth -> ForestStoreIter -> (Int, Int, Int)
getTreeIterLeaf Depth
depth ForestStoreIter
iter
childIdx :: Word32
childIdx = Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
childIdx_Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+Word32
1
nextIter :: ForestStoreIter
nextIter = ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
setBitSlice ForestStoreIter
iter (Int
posInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
leaf) Int
child Word32
childIdx
in
if Word32
childIdxWord32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>=Int -> Word32
forall a. Bits a => Int -> a
bit Int
child then (Maybe ForestStoreIter
forall a. Maybe a
Nothing, Cache a
cache) else
case Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
checkSuccess Depth
depth ForestStoreIter
nextIter Cache a
cache of
(Bool
True, Cache a
cache) -> (ForestStoreIter -> Maybe ForestStoreIter
forall a. a -> Maybe a
Just ForestStoreIter
nextIter, Cache a
cache)
(Bool
False, Cache a
cache) -> (Maybe ForestStoreIter
forall a. Maybe a
Nothing, Cache a
cache)
iterNChildren :: Depth -> ForestStoreIter -> Cache a -> (Int, Cache a)
iterNChildren :: forall a. Depth -> ForestStoreIter -> Cache a -> (Int, Cache a)
iterNChildren Depth
depth ForestStoreIter
iter Cache a
cache = case Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
checkSuccess Depth
depth ForestStoreIter
iter Cache a
cache of
(Bool
True, cache :: Cache a
cache@((ForestStoreIter
_,Node { subForest :: forall a. Tree a -> [Tree a]
subForest = Forest a
forest}:Forest a
_):Cache a
_)) -> (Forest a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Forest a
forest, Cache a
cache)
(Bool
_, Cache a
cache) -> (Int
0, Cache a
cache)
iterParent :: Depth -> ForestStoreIter -> Maybe ForestStoreIter
iterParent :: Depth -> ForestStoreIter -> Maybe ForestStoreIter
iterParent Depth
depth ForestStoreIter
iter = let
(Int
pos,Int
leaf,Int
_child) = Depth -> ForestStoreIter -> (Int, Int, Int)
getTreeIterLeaf Depth
depth ForestStoreIter
iter
in if Int
posInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0 then Maybe ForestStoreIter
forall a. Maybe a
Nothing else
if ForestStoreIter -> Int -> Int -> Word32
getBitSlice ForestStoreIter
iter Int
pos Int
leafWord32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
0 then Maybe ForestStoreIter
forall a. Maybe a
Nothing else
ForestStoreIter -> Maybe ForestStoreIter
forall a. a -> Maybe a
Just (ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
setBitSlice ForestStoreIter
iter Int
pos Int
leaf Word32
0)
forestStoreInsertForest :: MonadIO m
=> ForestStore a
-> TreePath
-> Int
-> Forest a
-> m ()
forestStoreInsertForest :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> Int -> Forest a -> m ()
forestStoreInsertForest (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
path Int
pos Forest a
nodes = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
[Int32]
ipath <- TreePath -> IO [Int32]
forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
treePathGetIndices' TreePath
path
CustomStore (IORef (Store a)) a -> IO ()
forall (m :: * -> *) private row.
MonadIO m =>
CustomStore private row -> m ()
customStoreInvalidateIters (CustomStore (IORef (Store a)) a -> IO ())
-> CustomStore (IORef (Store a)) a -> IO ()
forall a b. (a -> b) -> a -> b
$ ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model
(Int
idx, Bool
toggle) <- IORef (Store a)
-> (Store a -> (Store a, (Int, Bool))) -> IO (Int, Bool)
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (CustomStore (IORef (Store a)) a -> IORef (Store a))
-> CustomStore (IORef (Store a)) a -> IORef (Store a)
forall a b. (a -> b) -> a -> b
$ ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) ((Store a -> (Store a, (Int, Bool))) -> IO (Int, Bool))
-> (Store a -> (Store a, (Int, Bool))) -> IO (Int, Bool)
forall a b. (a -> b) -> a -> b
$
\store :: Store a
store@Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } ->
case Forest a
-> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
forall a.
Forest a
-> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
insertIntoForest (Cache a -> Forest a
forall a. Cache a -> Forest a
cacheToStore Cache a
cache) Forest a
nodes [Int32]
ipath Int
pos of
Maybe (Forest a, Int, Bool)
Nothing -> [Char] -> (Store a, (Int, Bool))
forall a. (?callStack::CallStack) => [Char] -> a
error ([Char]
"forestStoreInsertForest: path does not exist " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Int32] -> [Char]
forall a. Show a => a -> [Char]
show [Int32]
ipath)
Just (Forest a
newForest, Int
idx, Bool
toggle) ->
let depth :: Depth
depth = Forest a -> Depth
forall a. Forest a -> Depth
calcForestDepth Forest a
newForest
in (Store { depth :: Depth
depth = Depth
depth,
content :: Cache a
content = Forest a -> Cache a
forall a. Forest a -> Cache a
storeToCache Forest a
newForest },
(Int
idx, Bool
toggle))
Store { depth :: forall a. Store a -> Depth
depth = Depth
depth } <- IORef (Store a) -> IO (Store a)
forall a. IORef a -> IO a
readIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (CustomStore (IORef (Store a)) a -> IORef (Store a))
-> CustomStore (IORef (Store a)) a -> IORef (Store a)
forall a b. (a -> b) -> a -> b
$ ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)
let rpath :: [Int32]
rpath = [Int32] -> [Int32]
forall a. [a] -> [a]
reverse [Int32]
ipath
Int32
stamp <- CustomStore (IORef (Store a)) a -> IO Int32
forall (m :: * -> *) private row.
MonadIO m =>
CustomStore private row -> m Int32
customStoreGetStamp (CustomStore (IORef (Store a)) a -> IO Int32)
-> CustomStore (IORef (Store a)) a -> IO Int32
forall a b. (a -> b) -> a -> b
$ ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model
[IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [ let p' :: [Int32]
p' = [Int32] -> [Int32]
forall a. [a] -> [a]
reverse [Int32]
p
Just ForestStoreIter
iter = Depth -> [Int32] -> Maybe ForestStoreIter
fromPath Depth
depth [Int32]
p'
in do
TreePath
p'' <- [Int32] -> IO TreePath
forall (m :: * -> *). MonadIO m => [Int32] -> m TreePath
treePathNewFromIndices' [Int32]
p'
CustomStore (IORef (Store a)) a -> TreePath -> TreeIter -> IO ()
forall (m :: * -> *) a.
(?callStack::CallStack, MonadIO m, IsTreeModel a) =>
a -> TreePath -> TreeIter -> m ()
treeModelRowInserted (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
p'' (TreeIter -> IO ()) -> IO TreeIter -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ForestStoreIter -> IO TreeIter
forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter (ForestStoreIter -> Int32 -> ForestStoreIter
forestStoreIterSetStamp ForestStoreIter
iter Int32
stamp)
| (Int
i, Tree a
node) <- Depth -> Forest a -> [(Int, Tree a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
idx..] Forest a
nodes
, [Int32]
p <- [Int32] -> Tree a -> [[Int32]]
forall a. [Int32] -> Tree a -> [[Int32]]
paths (Int -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i Int32 -> [Int32] -> [Int32]
forall a. a -> [a] -> [a]
: [Int32]
rpath) Tree a
node ]
let Just ForestStoreIter
iter = Depth -> [Int32] -> Maybe ForestStoreIter
fromPath Depth
depth [Int32]
ipath
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
toggle (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ CustomStore (IORef (Store a)) a -> TreePath -> TreeIter -> IO ()
forall (m :: * -> *) a.
(?callStack::CallStack, MonadIO m, IsTreeModel a) =>
a -> TreePath -> TreeIter -> m ()
treeModelRowHasChildToggled (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
path
(TreeIter -> IO ()) -> IO TreeIter -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ForestStoreIter -> IO TreeIter
forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter (ForestStoreIter -> Int32 -> ForestStoreIter
forestStoreIterSetStamp ForestStoreIter
iter Int32
stamp)
where paths :: [Int32] -> Tree a -> [[Int32]]
paths :: forall a. [Int32] -> Tree a -> [[Int32]]
paths [Int32]
path Node { subForest :: forall a. Tree a -> [Tree a]
subForest = [Tree a]
ts } =
[Int32]
path [Int32] -> [[Int32]] -> [[Int32]]
forall a. a -> [a] -> [a]
: [[[Int32]]] -> [[Int32]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ [Int32] -> Tree a -> [[Int32]]
forall a. [Int32] -> Tree a -> [[Int32]]
paths (Int32
nInt32 -> [Int32] -> [Int32]
forall a. a -> [a] -> [a]
:[Int32]
path) Tree a
t | (Int32
n, Tree a
t) <- [Int32] -> [Tree a] -> [(Int32, Tree a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int32
0..] [Tree a]
ts ]
forestStoreInsertTree :: MonadIO m
=> ForestStore a
-> TreePath
-> Int
-> Tree a
-> m ()
forestStoreInsertTree :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> Int -> Tree a -> m ()
forestStoreInsertTree ForestStore a
store TreePath
path Int
pos Tree a
node =
ForestStore a -> TreePath -> Int -> Forest a -> m ()
forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> Int -> Forest a -> m ()
forestStoreInsertForest ForestStore a
store TreePath
path Int
pos [Tree a
node]
forestStoreInsert :: MonadIO m
=> ForestStore a
-> TreePath
-> Int
-> a
-> m ()
forestStoreInsert :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> Int -> a -> m ()
forestStoreInsert ForestStore a
store TreePath
path Int
pos a
node =
ForestStore a -> TreePath -> Int -> Forest a -> m ()
forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> Int -> Forest a -> m ()
forestStoreInsertForest ForestStore a
store TreePath
path Int
pos [a -> Forest a -> Tree a
forall a. a -> [Tree a] -> Tree a
Node a
node []]
insertIntoForest :: Forest a -> Forest a -> [Int32] -> Int ->
Maybe (Forest a, Int, Bool)
insertIntoForest :: forall a.
Forest a
-> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
insertIntoForest Forest a
forest Forest a
nodes [] Int
pos
| Int
posInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
0 = (Forest a, Int, Bool) -> Maybe (Forest a, Int, Bool)
forall a. a -> Maybe a
Just (Forest a
forestForest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++Forest a
nodes, Forest a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Forest a
forest, Forest a -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Forest a
forest)
| Bool
otherwise = (Forest a, Int, Bool) -> Maybe (Forest a, Int, Bool)
forall a. a -> Maybe a
Just (Forest a
prevForest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++Forest a
nodesForest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++Forest a
next, Forest a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Forest a
prev, Forest a -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Forest a
forest)
where (Forest a
prev, Forest a
next) = Int -> Forest a -> (Forest a, Forest a)
forall a. Int -> [a] -> ([a], [a])
splitAt Int
pos Forest a
forest
insertIntoForest Forest a
forest Forest a
nodes (Int32
p:[Int32]
ps) Int
pos = case Int -> Forest a -> (Forest a, Forest a)
forall a. Int -> [a] -> ([a], [a])
splitAt (Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
p) Forest a
forest of
(Forest a
prev, []) -> Maybe (Forest a, Int, Bool)
forall a. Maybe a
Nothing
(Forest a
prev, Node { rootLabel :: forall a. Tree a -> a
rootLabel = a
val,
subForest :: forall a. Tree a -> [Tree a]
subForest = Forest a
for}:Forest a
next) ->
case Forest a
-> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
forall a.
Forest a
-> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
insertIntoForest Forest a
for Forest a
nodes [Int32]
ps Int
pos of
Maybe (Forest a, Int, Bool)
Nothing -> Maybe (Forest a, Int, Bool)
forall a. Maybe a
Nothing
Just (Forest a
for, Int
pos, Bool
toggle) -> (Forest a, Int, Bool) -> Maybe (Forest a, Int, Bool)
forall a. a -> Maybe a
Just (Forest a
prevForest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++Node { rootLabel :: a
rootLabel = a
val,
subForest :: Forest a
subForest = Forest a
for }Tree a -> Forest a -> Forest a
forall a. a -> [a] -> [a]
:Forest a
next,
Int
pos, Bool
toggle)
forestStoreRemove :: MonadIO m => ForestStore a -> TreePath -> m Bool
forestStoreRemove :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> m Bool
forestStoreRemove ForestStore a
model TreePath
path = TreePath -> m [Int32]
forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
treePathGetIndices' TreePath
path m [Int32] -> ([Int32] -> m Bool) -> m Bool
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ForestStore a -> TreePath -> [Int32] -> m Bool
forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> [Int32] -> m Bool
forestStoreRemoveImpl ForestStore a
model TreePath
path
forestStoreRemoveImpl :: MonadIO m => ForestStore a -> TreePath -> [Int32] -> m Bool
forestStoreRemoveImpl :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> [Int32] -> m Bool
forestStoreRemoveImpl (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
_ [] = Bool -> m Bool
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
forestStoreRemoveImpl (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
path [Int32]
ipath = IO Bool -> m Bool
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> m Bool) -> IO Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ do
CustomStore (IORef (Store a)) a -> IO ()
forall (m :: * -> *) private row.
MonadIO m =>
CustomStore private row -> m ()
customStoreInvalidateIters (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)
(Bool
found, Bool
toggle) <- IORef (Store a)
-> (Store a -> (Store a, (Bool, Bool))) -> IO (Bool, Bool)
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)) ((Store a -> (Store a, (Bool, Bool))) -> IO (Bool, Bool))
-> (Store a -> (Store a, (Bool, Bool))) -> IO (Bool, Bool)
forall a b. (a -> b) -> a -> b
$
\store :: Store a
store@Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } ->
if Cache a -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Cache a
cache then (Store a
store, (Bool
False, Bool
False)) else
case Forest a -> [Int32] -> Maybe (Forest a, Bool)
forall a. Forest a -> [Int32] -> Maybe (Forest a, Bool)
deleteFromForest (Cache a -> Forest a
forall a. Cache a -> Forest a
cacheToStore Cache a
cache) [Int32]
ipath of
Maybe (Forest a, Bool)
Nothing -> (Store a
store, (Bool
False, Bool
False))
Just (Forest a
newForest, Bool
toggle) ->
(Store { depth :: Depth
depth = Depth
d,
content :: Cache a
content = Forest a -> Cache a
forall a. Forest a -> Cache a
storeToCache Forest a
newForest }, (Bool
True, Bool
toggle))
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
found (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
toggle Bool -> Bool -> Bool
&& Bool -> Bool
not ([Int32] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int32]
ipath)) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Store { depth :: forall a. Store a -> Depth
depth = Depth
depth } <- IORef (Store a) -> IO (Store a)
forall a. IORef a -> IO a
readIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model))
let iparent :: [Int32]
iparent = [Int32] -> [Int32]
forall a. (?callStack::CallStack) => [a] -> [a]
init [Int32]
ipath
Just ForestStoreIter
iter = Depth -> [Int32] -> Maybe ForestStoreIter
fromPath Depth
depth [Int32]
iparent
TreePath
parent <- [Int32] -> IO TreePath
forall (m :: * -> *). MonadIO m => [Int32] -> m TreePath
treePathNewFromIndices' [Int32]
iparent
CustomStore (IORef (Store a)) a -> TreePath -> TreeIter -> IO ()
forall (m :: * -> *) a.
(?callStack::CallStack, MonadIO m, IsTreeModel a) =>
a -> TreePath -> TreeIter -> m ()
treeModelRowHasChildToggled (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
parent (TreeIter -> IO ()) -> IO TreeIter -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ForestStoreIter -> IO TreeIter
forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter ForestStoreIter
iter
CustomStore (IORef (Store a)) a -> TreePath -> IO ()
forall (m :: * -> *) a.
(?callStack::CallStack, MonadIO m, IsTreeModel a) =>
a -> TreePath -> m ()
treeModelRowDeleted (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
path
Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
found
forestStoreClear :: MonadIO m => ForestStore a -> m ()
forestStoreClear :: forall (m :: * -> *) a. MonadIO m => ForestStore a -> m ()
forestStoreClear (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
CustomStore (IORef (Store a)) a -> IO ()
forall (m :: * -> *) private row.
MonadIO m =>
CustomStore private row -> m ()
customStoreInvalidateIters (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)
Store { content :: forall a. Store a -> Cache a
content = Cache a
cache } <- IORef (Store a) -> IO (Store a)
forall a. IORef a -> IO a
readIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model))
let forest :: Forest a
forest = Cache a -> Forest a
forall a. Cache a -> Forest a
cacheToStore Cache a
cache
IORef (Store a) -> Store a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)) Store {
depth :: Depth
depth = Forest Any -> Depth
forall a. Forest a -> Depth
calcForestDepth [],
content :: Cache a
content = Forest a -> Cache a
forall a. Forest a -> Cache a
storeToCache []
}
let loop :: Int -> IO ()
loop (-1) = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
loop Int
n = [Int32] -> IO TreePath
forall (m :: * -> *). MonadIO m => [Int32] -> m TreePath
treePathNewFromIndices' [Int -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n] IO TreePath -> (TreePath -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CustomStore (IORef (Store a)) a -> TreePath -> IO ()
forall (m :: * -> *) a.
(?callStack::CallStack, MonadIO m, IsTreeModel a) =>
a -> TreePath -> m ()
treeModelRowDeleted (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> IO ()
loop (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
Int -> IO ()
loop (Forest a -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Forest a
forest Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
deleteFromForest :: Forest a -> [Int32] -> Maybe (Forest a, Bool)
deleteFromForest :: forall a. Forest a -> [Int32] -> Maybe (Forest a, Bool)
deleteFromForest Forest a
forest [] = (Forest a, Bool) -> Maybe (Forest a, Bool)
forall a. a -> Maybe a
Just ([], Bool
False)
deleteFromForest Forest a
forest (Int32
p:[Int32]
ps) =
case Int -> Forest a -> (Forest a, Forest a)
forall a. Int -> [a] -> ([a], [a])
splitAt (Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
p) Forest a
forest of
(Forest a
prev, kill :: Tree a
kill@Node { rootLabel :: forall a. Tree a -> a
rootLabel = a
val,
subForest :: forall a. Tree a -> [Tree a]
subForest = Forest a
for}:Forest a
next) ->
if [Int32] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int32]
ps then (Forest a, Bool) -> Maybe (Forest a, Bool)
forall a. a -> Maybe a
Just (Forest a
prevForest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++Forest a
next, Forest a -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Forest a
prev Bool -> Bool -> Bool
&& Forest a -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Forest a
next) else
case Forest a -> [Int32] -> Maybe (Forest a, Bool)
forall a. Forest a -> [Int32] -> Maybe (Forest a, Bool)
deleteFromForest Forest a
for [Int32]
ps of
Maybe (Forest a, Bool)
Nothing -> Maybe (Forest a, Bool)
forall a. Maybe a
Nothing
Just (Forest a
for,Bool
toggle) -> (Forest a, Bool) -> Maybe (Forest a, Bool)
forall a. a -> Maybe a
Just (Forest a
prevForest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++Node {rootLabel :: a
rootLabel = a
val,
subForest :: Forest a
subForest = Forest a
for }Tree a -> Forest a -> Forest a
forall a. a -> [a] -> [a]
:Forest a
next, Bool
toggle)
(Forest a
prev, []) -> Maybe (Forest a, Bool)
forall a. Maybe a
Nothing
forestStoreSetValue :: MonadIO m => ForestStore a -> TreePath -> a -> m ()
forestStoreSetValue :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> a -> m ()
forestStoreSetValue ForestStore a
store TreePath
path a
value = ForestStore a -> TreePath -> (a -> m a) -> m Bool
forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> (a -> m a) -> m Bool
forestStoreChangeM ForestStore a
store TreePath
path (\a
_ -> a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
value)
m Bool -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
forestStoreChange :: MonadIO m => ForestStore a -> TreePath -> (a -> a) -> m Bool
forestStoreChange :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> (a -> a) -> m Bool
forestStoreChange ForestStore a
store TreePath
path a -> a
func = ForestStore a -> TreePath -> (a -> m a) -> m Bool
forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> (a -> m a) -> m Bool
forestStoreChangeM ForestStore a
store TreePath
path (a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> (a -> a) -> a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
func)
forestStoreChangeM :: MonadIO m => ForestStore a -> TreePath -> (a -> m a) -> m Bool
forestStoreChangeM :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> (a -> m a) -> m Bool
forestStoreChangeM (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
path a -> m a
act = do
[Int32]
ipath <- TreePath -> m [Int32]
forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
treePathGetIndices' TreePath
path
CustomStore (IORef (Store a)) a -> m ()
forall (m :: * -> *) private row.
MonadIO m =>
CustomStore private row -> m ()
customStoreInvalidateIters (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)
store :: Store a
store@Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } <-
IO (Store a) -> m (Store a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Store a) -> m (Store a)) -> IO (Store a) -> m (Store a)
forall a b. (a -> b) -> a -> b
$ IORef (Store a) -> IO (Store a)
forall a. IORef a -> IO a
readIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model))
(store' :: Store a
store'@Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache }, Bool
found) <- do
Maybe (Forest a)
mRes <- Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
forall (m :: * -> *) a.
MonadIO m =>
Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
changeForest (Cache a -> Forest a
forall a. Cache a -> Forest a
cacheToStore Cache a
cache) a -> m a
act [Int32]
ipath
(Store a, Bool) -> m (Store a, Bool)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Store a, Bool) -> m (Store a, Bool))
-> (Store a, Bool) -> m (Store a, Bool)
forall a b. (a -> b) -> a -> b
$ case Maybe (Forest a)
mRes of
Maybe (Forest a)
Nothing -> (Store a
store, Bool
False)
Just Forest a
newForest -> (Store { depth :: Depth
depth = Depth
d,
content :: Cache a
content = Forest a -> Cache a
forall a. Forest a -> Cache a
storeToCache Forest a
newForest }, Bool
True)
IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ IORef (Store a) -> Store a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)) Store a
store'
let Just ForestStoreIter
iter = Depth -> [Int32] -> Maybe ForestStoreIter
fromPath Depth
d [Int32]
ipath
Int32
stamp <- CustomStore (IORef (Store a)) a -> m Int32
forall (m :: * -> *) private row.
MonadIO m =>
CustomStore private row -> m Int32
customStoreGetStamp (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
found (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ CustomStore (IORef (Store a)) a -> TreePath -> TreeIter -> m ()
forall (m :: * -> *) a.
(?callStack::CallStack, MonadIO m, IsTreeModel a) =>
a -> TreePath -> TreeIter -> m ()
treeModelRowChanged (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
path (TreeIter -> m ()) -> m TreeIter -> m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ForestStoreIter -> m TreeIter
forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
fromForestStoreIter (ForestStoreIter -> Int32 -> ForestStoreIter
forestStoreIterSetStamp ForestStoreIter
iter Int32
stamp)
Bool -> m Bool
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
found
changeForest :: MonadIO m => Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
changeForest :: forall (m :: * -> *) a.
MonadIO m =>
Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
changeForest Forest a
forest a -> m a
act [] = Maybe (Forest a) -> m (Maybe (Forest a))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Forest a)
forall a. Maybe a
Nothing
changeForest Forest a
forest a -> m a
act (Int32
p:[Int32]
ps) = case Int -> Forest a -> (Forest a, Forest a)
forall a. Int -> [a] -> ([a], [a])
splitAt (Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
p) Forest a
forest of
(Forest a
prev, []) -> Maybe (Forest a) -> m (Maybe (Forest a))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Forest a)
forall a. Maybe a
Nothing
(Forest a
prev, Node { rootLabel :: forall a. Tree a -> a
rootLabel = a
val,
subForest :: forall a. Tree a -> [Tree a]
subForest = Forest a
for}:Forest a
next) ->
if [Int32] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int32]
ps then do
a
val' <- a -> m a
act a
val
Maybe (Forest a) -> m (Maybe (Forest a))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Forest a -> Maybe (Forest a)
forall a. a -> Maybe a
Just (Forest a
prevForest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++Node { rootLabel :: a
rootLabel = a
val',
subForest :: Forest a
subForest = Forest a
for }Tree a -> Forest a -> Forest a
forall a. a -> [a] -> [a]
:Forest a
next))
else do
Maybe (Forest a)
mFor <- Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
forall (m :: * -> *) a.
MonadIO m =>
Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
changeForest Forest a
for a -> m a
act [Int32]
ps
case Maybe (Forest a)
mFor of
Maybe (Forest a)
Nothing -> Maybe (Forest a) -> m (Maybe (Forest a))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Forest a)
forall a. Maybe a
Nothing
Just Forest a
for -> Maybe (Forest a) -> m (Maybe (Forest a))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Forest a) -> m (Maybe (Forest a)))
-> Maybe (Forest a) -> m (Maybe (Forest a))
forall a b. (a -> b) -> a -> b
$ Forest a -> Maybe (Forest a)
forall a. a -> Maybe a
Just (Forest a
prevForest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++Node { rootLabel :: a
rootLabel = a
val,
subForest :: Forest a
subForest = Forest a
for }Tree a -> Forest a -> Forest a
forall a. a -> [a] -> [a]
:Forest a
next)
forestStoreGetValue :: (Applicative m, MonadIO m) => ForestStore a -> TreePath -> m a
forestStoreGetValue :: forall (m :: * -> *) a.
(Applicative m, MonadIO m) =>
ForestStore a -> TreePath -> m a
forestStoreGetValue ForestStore a
model TreePath
path = Tree a -> a
forall a. Tree a -> a
rootLabel (Tree a -> a) -> m (Tree a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ForestStore a -> TreePath -> m (Tree a)
forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> m (Tree a)
forestStoreGetTree ForestStore a
model TreePath
path
forestStoreGetTree :: MonadIO m => ForestStore a -> TreePath -> m (Tree a)
forestStoreGetTree :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> m (Tree a)
forestStoreGetTree (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
path = IO (Tree a) -> m (Tree a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Tree a) -> m (Tree a)) -> IO (Tree a) -> m (Tree a)
forall a b. (a -> b) -> a -> b
$ do
[Int32]
ipath <- TreePath -> IO [Int32]
forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
treePathGetIndices' TreePath
path
store :: Store a
store@Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } <-
IORef (Store a) -> IO (Store a)
forall a. IORef a -> IO a
readIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model))
case Depth -> [Int32] -> Maybe ForestStoreIter
fromPath Depth
d [Int32]
ipath of
(Just ForestStoreIter
iter) -> do
let (Bool
res, Cache a
cache') = Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
checkSuccess Depth
d ForestStoreIter
iter Cache a
cache
IORef (Store a) -> Store a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)) Store a
store { content :: Cache a
content = Cache a
cache' }
case Cache a
cache' of
((ForestStoreIter
_,Tree a
node:Forest a
_):Cache a
_) | Bool
res -> Tree a -> IO (Tree a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Tree a
node
Cache a
_ -> [Char] -> IO (Tree a)
forall a. [Char] -> IO a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char]
"forestStoreGetTree: path does not exist " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Int32] -> [Char]
forall a. Show a => a -> [Char]
show [Int32]
ipath)
Maybe ForestStoreIter
_ -> [Char] -> IO (Tree a)
forall a. [Char] -> IO a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char]
"forestStoreGetTree: path does not exist " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Int32] -> [Char]
forall a. Show a => a -> [Char]
show [Int32]
ipath)
forestStoreGetForest :: MonadIO m => ForestStore a -> m (Forest a)
forestStoreGetForest :: forall (m :: * -> *) a. MonadIO m => ForestStore a -> m (Forest a)
forestStoreGetForest (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) = IO (Forest a) -> m (Forest a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Forest a) -> m (Forest a)) -> IO (Forest a) -> m (Forest a)
forall a b. (a -> b) -> a -> b
$ do
store :: Store a
store@Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } <-
IORef (Store a) -> IO (Store a)
forall a. IORef a -> IO a
readIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model))
Forest a -> IO (Forest a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Forest a -> IO (Forest a)) -> Forest a -> IO (Forest a)
forall a b. (a -> b) -> a -> b
$ Cache a -> Forest a
forall a. Cache a -> Forest a
cacheToStore Cache a
cache
forestStoreLookup :: MonadIO m => ForestStore a -> TreePath -> m (Maybe (Tree a))
forestStoreLookup :: forall (m :: * -> *) a.
MonadIO m =>
ForestStore a -> TreePath -> m (Maybe (Tree a))
forestStoreLookup (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
model) TreePath
path = IO (Maybe (Tree a)) -> m (Maybe (Tree a))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe (Tree a)) -> m (Maybe (Tree a)))
-> IO (Maybe (Tree a)) -> m (Maybe (Tree a))
forall a b. (a -> b) -> a -> b
$ do
[Int32]
ipath <- TreePath -> IO [Int32]
forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
treePathGetIndices' TreePath
path
store :: Store a
store@Store { depth :: forall a. Store a -> Depth
depth = Depth
d, content :: forall a. Store a -> Cache a
content = Cache a
cache } <-
IORef (Store a) -> IO (Store a)
forall a. IORef a -> IO a
readIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model))
case Depth -> [Int32] -> Maybe ForestStoreIter
fromPath Depth
d [Int32]
ipath of
(Just ForestStoreIter
iter) -> do
let (Bool
res, Cache a
cache') = Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
checkSuccess Depth
d ForestStoreIter
iter Cache a
cache
IORef (Store a) -> Store a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
forall private row. CustomStore private row -> private
customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
-> CustomStore (IORef (Store a)) a
forall private row.
ManagedPtr (CustomStore private row) -> CustomStore private row
CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
model)) Store a
store { content :: Cache a
content = Cache a
cache' }
case Cache a
cache' of
((ForestStoreIter
_,Tree a
node:Forest a
_):Cache a
_) | Bool
res -> Maybe (Tree a) -> IO (Maybe (Tree a))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Tree a -> Maybe (Tree a)
forall a. a -> Maybe a
Just Tree a
node)
Cache a
_ -> Maybe (Tree a) -> IO (Maybe (Tree a))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Tree a)
forall a. Maybe a
Nothing
Maybe ForestStoreIter
_ -> Maybe (Tree a) -> IO (Maybe (Tree a))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Tree a)
forall a. Maybe a
Nothing