Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell98 |
This module holds a reactive program model. It holds a program model, but includes events that other threads can listen to, so that a change in a part of the model is notified to another part of the program. The reactive model is not necessarily concurrent (it doesn't have its own thread), although a facility is included to make it also concurrent (so that event handlers can be called as soon as they are present).
This type includes operations to handle undoing-redoing and tracking which notifications must be triggered in each undo-redo step.
- data Event b => ReactiveModel a b c
- class (Eq a, Ord a) => Event a where
- emptyRM :: Event b => a -> ReactiveModel a b c
- pendingEvents :: ReactiveModel a b c -> Seq b
- pendingHandlers :: ReactiveModel a b c -> Seq c
- nextModels :: ReactiveModel a b c -> Stack (a, Seq b)
- previousModels :: ReactiveModel a b c -> Stack (a, Seq b)
- onBasicModel :: Event b => ReactiveModel a b c -> (a -> a) -> ReactiveModel a b c
- onEvent :: Event b => ReactiveModel a b c -> b -> c -> ReactiveModel a b c
- onEvents :: (Foldable container, Event b) => ReactiveModel a b c -> container b -> c -> ReactiveModel a b c
- getPendingHandler :: Event b => ReactiveModel a b c -> (ReactiveModel a b c, Maybe c)
- eventHandlers :: ReactiveModel a b c -> Map b (Seq c)
- prepareEventHandlers :: Event b => ReactiveModel a b c -> ReactiveModel a b c
- triggerEvent :: Event b => ReactiveModel a b c -> b -> ReactiveModel a b c
- triggerEvents :: Event b => ReactiveModel a b c -> Seq b -> ReactiveModel a b c
- recordChange :: Event b => ReactiveModel a b c -> (a -> a) -> [b] -> ReactiveModel a b c
- onUndo :: Event b => ReactiveModel a b c -> [b] -> ReactiveModel a b c
- undo :: Event b => ReactiveModel a b c -> ReactiveModel a b c
- redo :: Event b => ReactiveModel a b c -> ReactiveModel a b c
- clearUndoStack :: Event b => ReactiveModel a b c -> ReactiveModel a b c
- onUndoStack :: Event b => ReactiveModel a b c -> (a -> a) -> ReactiveModel a b c
Documentation
data Event b => ReactiveModel a b c Source
A model of kind a with a stack of events of kind b
Construction
class (Eq a, Ord a) => Event a where Source
A reactive model uses an event datatype with all the events that our model must trigger. An heterogenous container cannot be used because we need an Eq operation that is efficient (a string comparison is not).
Therefore, we can declare operations that require certain events, as long as we create a typeclass for Event types that have a constructor for the kind of events we require. This reactive model handles Undo/Redo internally, and changes to the undo-stack are notified automatically. All Event types must declare an undo event, even if it's not used.
NOTE: This is experimental code. Undo/Redo support may not be necessary in many programs, and another Reactive Model definition could be provided with no support for undo-redo if this bothers you too much.
emptyRM :: Event b => a -> ReactiveModel a b c Source
Default constructor (with an empty model, no events and no handlers installed)
Access
pendingEvents :: ReactiveModel a b c -> Seq b Source
pendingHandlers :: ReactiveModel a b c -> Seq c Source
nextModels :: ReactiveModel a b c -> Stack (a, Seq b) Source
previousModels :: ReactiveModel a b c -> Stack (a, Seq b) Source
Modification
onBasicModel :: Event b => ReactiveModel a b c -> (a -> a) -> ReactiveModel a b c Source
Apply a modification to the internal model (no events are triggered)
onEvent :: Event b => ReactiveModel a b c -> b -> c -> ReactiveModel a b c Source
Install a handler for an event
onEvents :: (Foldable container, Event b) => ReactiveModel a b c -> container b -> c -> ReactiveModel a b c Source
getPendingHandler :: Event b => ReactiveModel a b c -> (ReactiveModel a b c, Maybe c) Source
If any pending handler exists or can be obtained, it is returned and removed from the queue
eventHandlers :: ReactiveModel a b c -> Map b (Seq c) Source
prepareEventHandlers :: Event b => ReactiveModel a b c -> ReactiveModel a b c Source
Return a reactive model that has no pending events. All the pending events have been looked up in the eventHandlers table and the handlers have been added to the field pendingHandlers.
triggerEvent :: Event b => ReactiveModel a b c -> b -> ReactiveModel a b c Source
Trigger an event (execute all handlers associated to it)
triggerEvents :: Event b => ReactiveModel a b c -> Seq b -> ReactiveModel a b c Source
Trigger many events in sequence (execute all handlers associated to them)
Handling the Undo/Redo stack
recordChange :: Event b => ReactiveModel a b c -> (a -> a) -> [b] -> ReactiveModel a b c Source
Record a change in the undo stack, with a list of associated events for that change. Events are expected to work bi-directionally (the same event will be triggered when the change is redone or undone).
onUndo :: Event b => ReactiveModel a b c -> [b] -> ReactiveModel a b c Source
Install a handler in the previous model's event list
undo :: Event b => ReactiveModel a b c -> ReactiveModel a b c Source
Undo one step
redo :: Event b => ReactiveModel a b c -> ReactiveModel a b c Source
Redo one step
clearUndoStack :: Event b => ReactiveModel a b c -> ReactiveModel a b c Source
Clear the undo stack (remove all known previous and next models)
onUndoStack :: Event b => ReactiveModel a b c -> (a -> a) -> ReactiveModel a b c Source
Apply a change to all the models in the undo stack