-
Notifications
You must be signed in to change notification settings - Fork 47
Open
Labels
Description
explGetis currently guarded byexplMembersandexplExists.explSetis obliged to work whenever the component exists or not.
I've been thinking, what if explExists could instead return some key into the store, so explGet would know how to fetch data without traversing the store again?
This could give array-backed stores a boost:
type instance Elem (Buffer a) = a
type instance Key (Buffer a) = Ptr a -- new type family
instance _ => ExplGet m (Store a) where
explExists :: Store a -> Int -> m (Maybe (Key (Store a)))
explExists Store{slots} ety =
liftIO $
fmap (IntMap.lookup ety) $ -- `lookup` instead `member`, same O(), wraps in Maybe
readIORef slots
explGet :: Store a -> Key (Store a) -> m a
explGet _store key =
liftIO $
peek key -- aaand... done.
instance _ => ExplSet (Store a) where
explSet _store key value =
liftIO $
poke key value -- 🎉
instance _ => ExplMembers (Store a) where
explMembers Store{slots} =
liftIO $
fmap (U.fromList . IntMap.toList) $ -- `toList` instead of `keys`, wraps in `(,)` (pairs have `Unbox`).
readIORef slotsOf course this is all irrelevant for the "pure functional data structures"...
type instance Elem (Buffer a) = a
type instance Key (Map a) = Int -- The entity id is the component key
instance _ => ExplGet (Map a) where
explExists (Map ref) ety =
liftIO $
fmap (bool Nothing (Just ety) . IntMap.member key) $ -- just handling the wrapping
readIORef ref
explGet (Map ref) key =
liftIO $
flip fmap (M.lookup key <$> readIORef ref) >>= -- not helpful
maybe notFound pure
instance _ => ExplMembers (Map a) where
explMembers (Map ref) =
liftIO $
fmap (U.fromList . (\ety -> (ety, ety)) . M.keys) $ -- now this is just embarrassing 😅
readIORef refSo, there is a tension between
- pure structures -- where you can't cut any corners by passing extra data between tests and reads/writes.
- "unsafe" stores -- where existence witness is necessary and sufficient to go for the data directly.
Reactions are currently unavailable