module NanoUI.Store
( WidgetStore (..)
, emptyWidgetStore
, mirrorStoresChanged
, bumpMirror
, slotKey
, Slot (..)
, boolInt
, intBool
, anySelectOpen
, isSelectOpen
, setSelectOpen
, closeSelects
, ptrEq
, eqByPtr
)
where
import Data.Dynamic (Dynamic)
import Data.IntMap.Strict (IntMap)
import Data.IntSet (IntSet)
import Data.Text (Text)
import Data.Word (Word64)
import qualified Data.IntMap.Strict as IM
import GHC.Exts (isTrue#, reallyUnsafePtrEquality#)
import NanoUI.Id (mix64)
{-# INLINE ptrEq #-}
ptrEq :: a -> a -> Bool
ptrEq :: forall a. a -> a -> Bool
ptrEq a
a a
b = Int# -> Bool
isTrue# (a -> a -> Int#
forall a b. a -> b -> Int#
reallyUnsafePtrEquality# a
a a
b)
{-# INLINE eqByPtr #-}
eqByPtr :: Eq a => a -> a -> Bool
eqByPtr :: forall a. Eq a => a -> a -> Bool
eqByPtr a
a a
b = a -> a -> Bool
forall a. a -> a -> Bool
ptrEq a
a a
b Bool -> Bool -> Bool
|| a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
b
{-# INLINE eqDynMap #-}
eqDynMap :: IntMap Dynamic -> IntMap Dynamic -> Bool
eqDynMap :: IntMap Dynamic -> IntMap Dynamic -> Bool
eqDynMap IntMap Dynamic
a IntMap Dynamic
b =
IntMap Dynamic -> IntMap Dynamic -> Bool
forall a. a -> a -> Bool
ptrEq IntMap Dynamic
a IntMap Dynamic
b
Bool -> Bool -> Bool
|| (IntMap Dynamic -> Int
forall a. IntMap a -> Int
IM.size IntMap Dynamic
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== IntMap Dynamic -> Int
forall a. IntMap a -> Int
IM.size IntMap Dynamic
b Bool -> Bool -> Bool
&& (Dynamic -> Dynamic -> Bool)
-> IntMap Dynamic -> IntMap Dynamic -> Bool
forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
IM.isSubmapOfBy Dynamic -> Dynamic -> Bool
forall a. a -> a -> Bool
ptrEq IntMap Dynamic
a IntMap Dynamic
b)
data WidgetStore = WidgetStore
{ WidgetStore -> Word64
storeMirrorGen :: {-# UNPACK #-} !Word64
, WidgetStore -> Int
storeOpenSelect :: {-# UNPACK #-} !Int
, WidgetStore -> IntMap Int
storeInt :: !(IntMap Int)
, WidgetStore -> IntMap Float
storeFloat :: !(IntMap Float)
, WidgetStore -> IntMap Double
storeDouble :: !(IntMap Double)
, WidgetStore -> IntMap (Float, Float)
storePoint :: !(IntMap (Float, Float))
, WidgetStore -> IntMap Text
storeText :: !(IntMap Text)
, WidgetStore -> IntMap IntSet
storeIntSet :: !(IntMap IntSet)
, WidgetStore -> IntMap [Float]
storeFloatList :: !(IntMap [Float])
, WidgetStore -> IntMap [Int]
storeIntList :: !(IntMap [Int])
, WidgetStore -> IntMap Dynamic
storeDyn :: !(IntMap Dynamic)
}
instance Eq WidgetStore where
WidgetStore
a == :: WidgetStore -> WidgetStore -> Bool
== WidgetStore
b =
WidgetStore -> Word64
storeMirrorGen WidgetStore
a Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetStore -> Word64
storeMirrorGen WidgetStore
b
Bool -> Bool -> Bool
&& WidgetStore -> Int
storeOpenSelect WidgetStore
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetStore -> Int
storeOpenSelect WidgetStore
b
Bool -> Bool -> Bool
&& IntMap Int -> IntMap Int -> Bool
forall a. Eq a => a -> a -> Bool
eqByPtr (WidgetStore -> IntMap Int
storeInt WidgetStore
a) (WidgetStore -> IntMap Int
storeInt WidgetStore
b)
Bool -> Bool -> Bool
&& IntMap Float -> IntMap Float -> Bool
forall a. Eq a => a -> a -> Bool
eqByPtr (WidgetStore -> IntMap Float
storeFloat WidgetStore
a) (WidgetStore -> IntMap Float
storeFloat WidgetStore
b)
Bool -> Bool -> Bool
&& IntMap Double -> IntMap Double -> Bool
forall a. Eq a => a -> a -> Bool
eqByPtr (WidgetStore -> IntMap Double
storeDouble WidgetStore
a) (WidgetStore -> IntMap Double
storeDouble WidgetStore
b)
Bool -> Bool -> Bool
&& IntMap (Float, Float) -> IntMap (Float, Float) -> Bool
forall a. Eq a => a -> a -> Bool
eqByPtr (WidgetStore -> IntMap (Float, Float)
storePoint WidgetStore
a) (WidgetStore -> IntMap (Float, Float)
storePoint WidgetStore
b)
Bool -> Bool -> Bool
&& IntMap Text -> IntMap Text -> Bool
forall a. Eq a => a -> a -> Bool
eqByPtr (WidgetStore -> IntMap Text
storeText WidgetStore
a) (WidgetStore -> IntMap Text
storeText WidgetStore
b)
Bool -> Bool -> Bool
&& IntMap IntSet -> IntMap IntSet -> Bool
forall a. Eq a => a -> a -> Bool
eqByPtr (WidgetStore -> IntMap IntSet
storeIntSet WidgetStore
a) (WidgetStore -> IntMap IntSet
storeIntSet WidgetStore
b)
Bool -> Bool -> Bool
&& IntMap [Float] -> IntMap [Float] -> Bool
forall a. Eq a => a -> a -> Bool
eqByPtr (WidgetStore -> IntMap [Float]
storeFloatList WidgetStore
a) (WidgetStore -> IntMap [Float]
storeFloatList WidgetStore
b)
Bool -> Bool -> Bool
&& IntMap [Int] -> IntMap [Int] -> Bool
forall a. Eq a => a -> a -> Bool
eqByPtr (WidgetStore -> IntMap [Int]
storeIntList WidgetStore
a) (WidgetStore -> IntMap [Int]
storeIntList WidgetStore
b)
Bool -> Bool -> Bool
&& IntMap Dynamic -> IntMap Dynamic -> Bool
eqDynMap (WidgetStore -> IntMap Dynamic
storeDyn WidgetStore
a) (WidgetStore -> IntMap Dynamic
storeDyn WidgetStore
b)
instance Show WidgetStore where
show :: WidgetStore -> String
show WidgetStore
st =
String
"WidgetStore { "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"storeMirrorGen = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show (WidgetStore -> Word64
storeMirrorGen WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storeOpenSelect = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (WidgetStore -> Int
storeOpenSelect WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storeInt = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ IntMap Int -> String
forall a. Show a => a -> String
show (WidgetStore -> IntMap Int
storeInt WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storeFloat = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ IntMap Float -> String
forall a. Show a => a -> String
show (WidgetStore -> IntMap Float
storeFloat WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storeDouble = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ IntMap Double -> String
forall a. Show a => a -> String
show (WidgetStore -> IntMap Double
storeDouble WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storePoint = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ IntMap (Float, Float) -> String
forall a. Show a => a -> String
show (WidgetStore -> IntMap (Float, Float)
storePoint WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storeText = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ IntMap Text -> String
forall a. Show a => a -> String
show (WidgetStore -> IntMap Text
storeText WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storeIntSet = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ IntMap IntSet -> String
forall a. Show a => a -> String
show (WidgetStore -> IntMap IntSet
storeIntSet WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storeFloatList = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ IntMap [Float] -> String
forall a. Show a => a -> String
show (WidgetStore -> IntMap [Float]
storeFloatList WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storeIntList = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ IntMap [Int] -> String
forall a. Show a => a -> String
show (WidgetStore -> IntMap [Int]
storeIntList WidgetStore
st)
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", storeDynCount = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (IntMap Dynamic -> Int
forall a. IntMap a -> Int
IM.size (WidgetStore -> IntMap Dynamic
storeDyn WidgetStore
st))
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" }"
emptyWidgetStore :: WidgetStore
emptyWidgetStore :: WidgetStore
emptyWidgetStore =
WidgetStore
{ storeMirrorGen :: Word64
storeMirrorGen = Word64
0
, storeOpenSelect :: Int
storeOpenSelect = Int
0
, storeInt :: IntMap Int
storeInt = IntMap Int
forall a. IntMap a
IM.empty
, storeFloat :: IntMap Float
storeFloat = IntMap Float
forall a. IntMap a
IM.empty
, storeDouble :: IntMap Double
storeDouble = IntMap Double
forall a. IntMap a
IM.empty
, storePoint :: IntMap (Float, Float)
storePoint = IntMap (Float, Float)
forall a. IntMap a
IM.empty
, storeText :: IntMap Text
storeText = IntMap Text
forall a. IntMap a
IM.empty
, storeIntSet :: IntMap IntSet
storeIntSet = IntMap IntSet
forall a. IntMap a
IM.empty
, storeFloatList :: IntMap [Float]
storeFloatList = IntMap [Float]
forall a. IntMap a
IM.empty
, storeIntList :: IntMap [Int]
storeIntList = IntMap [Int]
forall a. IntMap a
IM.empty
, storeDyn :: IntMap Dynamic
storeDyn = IntMap Dynamic
forall a. IntMap a
IM.empty
}
{-# INLINE mirrorStoresChanged #-}
mirrorStoresChanged :: WidgetStore -> WidgetStore -> Bool
mirrorStoresChanged :: WidgetStore -> WidgetStore -> Bool
mirrorStoresChanged WidgetStore
old WidgetStore
new = WidgetStore -> Word64
storeMirrorGen WidgetStore
old Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
/= WidgetStore -> Word64
storeMirrorGen WidgetStore
new
{-# INLINE bumpMirror #-}
bumpMirror :: WidgetStore -> WidgetStore
bumpMirror :: WidgetStore -> WidgetStore
bumpMirror WidgetStore
st = WidgetStore
st {storeMirrorGen = storeMirrorGen st + 1}
{-# INLINE slotKey #-}
slotKey :: Slot -> Int -> Int
slotKey :: Slot -> Int -> Int
slotKey Slot
s Int
k = Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word64 -> Word64
mix64 (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k) (Slot -> Word64
slotTag Slot
s))
data Slot
= SlotCursor
| SlotAnchor
| SlotDrag
| SlotDragW
| SlotDrop
| SlotDropPos
| SlotWinSize
|
|
| SlotScrollCfg
| SlotScrollOff
| SlotScrollCross
| SlotScrollLinkX
| SlotScrollLinkY
| SlotScrollStep
| SlotScrollAxes
| SlotScrollViewPos
| SlotScrollViewSize
| SlotScrollRange
| SlotScrollContent
| SlotTextAreaRow
| SlotTextAreaCol
| SlotTextAreaPrefCol
| SlotTextAreaScroll
| SlotTextAreaViewport
| SlotTextAreaAnchorRow
| SlotTextAreaAnchorCol
|
SlotTextAreaContentW
| SlotTextAreaContentH
| SlotTextAreaContentFont
|
SlotTextAreaBuffer
|
SlotTextAreaChanged
|
SlotTextHistory
|
SlotTextMode
|
SlotTextAreaWidths
| SlotTextInputScroll
|
SlotSearchCommitted
| SlotSearchAge
|
SlotComboHighlight
| SlotComboScroll
| SlotComboCount
| SlotComboScrollX
| SlotComboContentW
| SlotComboDrag
| SlotComboDragOff
|
SlotComboCommitted
|
SlotComboFocus
|
SlotComboLive
|
SlotPaneGest
|
SlotPaneGrab
|
SlotPaneFocus
|
SlotPaneMax
|
SlotPaneResize
|
SlotPaneNext
|
SlotSeen
|
SlotColorBase
|
SlotNumericHeld
|
SlotNumericRepeat
deriving (Int -> Slot
Slot -> Int
Slot -> [Slot]
Slot -> Slot
Slot -> Slot -> [Slot]
Slot -> Slot -> Slot -> [Slot]
(Slot -> Slot)
-> (Slot -> Slot)
-> (Int -> Slot)
-> (Slot -> Int)
-> (Slot -> [Slot])
-> (Slot -> Slot -> [Slot])
-> (Slot -> Slot -> [Slot])
-> (Slot -> Slot -> Slot -> [Slot])
-> Enum Slot
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Slot -> Slot
succ :: Slot -> Slot
$cpred :: Slot -> Slot
pred :: Slot -> Slot
$ctoEnum :: Int -> Slot
toEnum :: Int -> Slot
$cfromEnum :: Slot -> Int
fromEnum :: Slot -> Int
$cenumFrom :: Slot -> [Slot]
enumFrom :: Slot -> [Slot]
$cenumFromThen :: Slot -> Slot -> [Slot]
enumFromThen :: Slot -> Slot -> [Slot]
$cenumFromTo :: Slot -> Slot -> [Slot]
enumFromTo :: Slot -> Slot -> [Slot]
$cenumFromThenTo :: Slot -> Slot -> Slot -> [Slot]
enumFromThenTo :: Slot -> Slot -> Slot -> [Slot]
Enum)
{-# INLINE slotTag #-}
slotTag :: Slot -> Word64
slotTag :: Slot -> Word64
slotTag Slot
s = Word64 -> Word64 -> Word64
mix64 Word64
0x534C4F5454414753 (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Slot -> Int
forall a. Enum a => a -> Int
fromEnum Slot
s))
boolInt :: Bool -> Int
boolInt :: Bool -> Int
boolInt Bool
b = if Bool
b then Int
1 else Int
0
intBool :: Int -> Bool
intBool :: Int -> Bool
intBool Int
n = Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0
{-# INLINE anySelectOpen #-}
anySelectOpen :: WidgetStore -> Bool
anySelectOpen :: WidgetStore -> Bool
anySelectOpen WidgetStore
st = WidgetStore -> Int
storeOpenSelect WidgetStore
st Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0
{-# INLINE isSelectOpen #-}
isSelectOpen :: WidgetStore -> Int -> Bool
isSelectOpen :: WidgetStore -> Int -> Bool
isSelectOpen WidgetStore
st Int
k = Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0 Bool -> Bool -> Bool
&& WidgetStore -> Int
storeOpenSelect WidgetStore
st Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
k
{-# INLINE setSelectOpen #-}
setSelectOpen :: WidgetStore -> Int -> Bool -> WidgetStore
setSelectOpen :: WidgetStore -> Int -> Bool -> WidgetStore
setSelectOpen WidgetStore
st Int
k Bool
True = WidgetStore
st {storeOpenSelect = k}
setSelectOpen WidgetStore
st Int
k Bool
False
| WidgetStore -> Int -> Bool
isSelectOpen WidgetStore
st Int
k = WidgetStore -> WidgetStore
closeSelects WidgetStore
st
| Bool
otherwise = WidgetStore
st
{-# INLINE closeSelects #-}
closeSelects :: WidgetStore -> WidgetStore
closeSelects :: WidgetStore -> WidgetStore
closeSelects WidgetStore
st = WidgetStore
st {storeOpenSelect = 0}