keera-hails-mvc-model-protectedmodel-0.8.0: Rapid Gtk Application Development - Protected Reactive Models
Safe HaskellSafe-Inferred
LanguageHaskell2010

Hails.MVC.Model.ReactiveModel

Description

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.

Copyright : (C) Keera Studios Ltd, 2013 License : BSD3 Maintainer : support@keera.co.uk

Synopsis

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

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

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