Liking cljdoc? Tell your friends :D

dvlopt.dsim

Idiomatic, purely-functional discrete event simulation.

A transition is pure stepwise function gradually modifying some arbitrary state map. Transitions are part of the state itself and are located under the transition-key key. They can be organized in arbitrarily nested maps. It is both common and desired for transitions to mirror the data they act upon :

{dvlopt.dsim/transition-key {:asteroids {42 {:x ... :y ...}}} :asteroids {42 {:x 450 :y 1420}}}

This pattern is so common that in this example, [:asteroids 42 :x] would be called the data-path of the :x transition of asteroid 42. Such a transition accepts 3 arguments: a state map, its data-path, and a step. It returns a new state which, although not enforced, should somehow modify the :x value of asteroid 42.

For doing so, a transition is created by providing an on-step function which also accepts 3 arguments: a state map, the data-path, and a percentage of completion. This percentage depends on the first step of the transition, how many steps it lasts, and the current step: (current-step - first-step) / n-steps.

After reaching 100%, if it was provided in the first place, the on-complete function of the transition is called. It accepts 4 arguments: the current state map, the data-path, the completion step, and the current step. It is useful when action must be taken after a transition, for instance for creating a new one. If some steps are missed or skipped, the completion step and the current step will not match. Hence it is useful to provide both. Completed transitions are removed automatically.

Cf. infinite once repeating

A poly-transition is a higher-order transition composed of several transitions. At the end of each sub-transition, the poly-transition takes care of creating the next one at the right moment. Hence, it would be easy to animate asteroid 42 to sequentially move in different directions, or to sequentially rotate in some complex manner. It is also trivial to create nested poly-transitions.

Cf. poly poly-infinite poly-repeating

Scaling a percentage to a value such as the :x position of an asteroid is facilitated by using scale and fn-scale. It is often needed for a transition to behave non-linearly. This can be simply done by modifying the percentage of completion, which is a linear progression, to be non-linear. For example, if an asteroid has to move faster and faster along the :x axis from 500 to 1000 pixels in a 100 steps starting from step 0:

(dvlopt.dsim/once 0 100 (let [scale' (dvlopt.dsim/fn-scale 500 1000)] (fn on-step [state data-path percent] (assoc-in state data-path (scale' (Math/pow percent 2))))))

The most straightforward way to add or remove transitions to a state is by using merge-transitions. A series of helpers for on-step and on-complete functions is provided. For example, improving the last example and removing the asteroid when done :

(dvlopt.dsim/once 0 100 (dsim/fn-mirror-percent (comp (dvlopt.dsim/fn-scale 500 1000) #(Math/pow % 2))) dsim/remove-pre-data)

The most basic way of moving a state to some step is done by using move. move-seq facilitates the process of iteratively moving through a sequence of steps. However, the most useful way is probably move-events which also takes into account events happening at some particular steps, each modifying the state is some way. Any non-trivial simulation involves such events.

Idiomatic, purely-functional discrete event simulation.


A transition is pure stepwise function gradually modifying some arbitrary state map. Transitions are part of the state itself
and are located under the `transition-key` key. They can be organized in arbitrarily nested maps. It is both common and desired
for transitions to mirror the data they act upon :


  {dvlopt.dsim/transition-key {:asteroids {42 {:x ...
                                               :y ...}}}
   :asteroids {42 {:x 450
                   :y 1420}}}

This pattern is so common that in this example, [:asteroids 42 :x] would be called the `data-path` of the :x transition of
asteroid 42. Such a transition accepts 3 arguments: a state map, its data-path, and a step. It returns a new state which, although
not enforced, should somehow modify the :x value of asteroid 42.

For doing so, a transition is created by providing an `on-step` function which also accepts 3 arguments: a state map, the data-path,
and a percentage of completion. This percentage depends on the first step of the transition, how many steps it lasts, and the
current step:  (current-step - first-step) / n-steps.

After reaching 100%, if it was provided in the first place, the `on-complete` function of the transition is called. It accepts
4 arguments: the current state map, the data-path, the completion step, and the current step. It is useful when action must be
taken after a transition, for instance for creating a new one. If some steps are missed or skipped, the completion step and the
current step will not match. Hence it is useful to provide both. Completed transitions are removed automatically.

  Cf. `infinite`
      `once`
      `repeating`

A poly-transition is a higher-order transition composed of several transitions. At the end of each sub-transition, the poly-transition
takes care of creating the next one at the right moment. Hence, it would be easy to animate asteroid 42 to sequentially move in
different directions, or to sequentially rotate in some complex manner. It is also trivial to create nested poly-transitions.

  Cf. `poly`
      `poly-infinite`
      `poly-repeating`


Scaling a percentage to a value such as the :x position of an asteroid is facilitated by using `scale` and `fn-scale`. It is often
needed for a transition to behave non-linearly. This can be simply done by modifying the percentage of completion, which is a linear
progression, to be non-linear. For example, if an asteroid has to move faster and faster along the :x axis from 500 to 1000 pixels in a
100 steps starting from step 0:

  (dvlopt.dsim/once 0
                    100
                    (let [scale' (dvlopt.dsim/fn-scale 500
                                                       1000)]
                      (fn on-step [state data-path percent]
                        (assoc-in state
                                  data-path
                                  (scale' (Math/pow percent
                                                    2))))))

The most straightforward way to add or remove transitions to a state is by using `merge-transitions`. A series of helpers for `on-step`
and `on-complete` functions is provided. For example, improving the last example and removing the asteroid when done :

  (dvlopt.dsim/once 0
                    100
                    (dsim/fn-mirror-percent (comp (dvlopt.dsim/fn-scale 500
                                                                        1000)
                                                  #(Math/pow %
                                                             2)))
                    dsim/remove-pre-data)


The most basic way of moving a state to some step is done by using `move`. `move-seq` facilitates the process of iteratively moving
through a sequence of steps. However, the most useful way is probably `move-events` which also takes into account events happening at
some particular steps, each modifying the state is some way. Any non-trivial simulation involves such events.
raw docstring

deep-mergeclj

(deep-merge hmap-1 hmap-2)

Deep merges two maps.

Deep merges two maps.
sourceraw docstring

dissoc-inclj

(dissoc-in hmap [k & ks :as path])

Deep dissoc, natural counterpart of Clojure's assoc-in.

Empty maps are removed.

Ex. (dissoc-in {:a {:b 42} :c :ok} [:a :b])

=> {:c :ok}
Deep dissoc, natural counterpart of Clojure's `assoc-in`.

Empty maps are removed.


Ex. (dissoc-in {:a {:b 42}
                :c :ok}
               [:a :b])

    => {:c :ok}
sourceraw docstring

fn-assoc-dataclj

(fn-assoc-data data)

Returns a function assoc'ing the given data at the data-path of a transition.

Useful when some steps might be skipped but it is needed for a transition to reach 100%. For instance, during a live animation, a frame will probably not be drawn at the exact millisecond a transition should complete but some milliseconds later. The returned function can be used as an on-complete function so that the state will always reflect the last step of such a transition.

Returns a function assoc'ing the given data at the data-path of a transition.

Useful when some steps might be skipped but it is needed for a transition to reach 100%. For instance,
during a live animation, a frame will probably not be drawn at the exact millisecond a transition should
complete but some milliseconds later. The returned function can be used as an `on-complete` function
so that the state will always reflect the last step of such a transition.
sourceraw docstring

fn-infiniteclj

(fn-infinite n-steps on-step)

Returns a function returning an infinite transition.

Useful for poly-transitions.

Cf. infinite poly

Returns a function returning an infinite transition.

Useful for poly-transitions.


Cf. `infinite`
    `poly`
sourceraw docstring

fn-mirrorclj

(fn-mirror map-percent)

Given an on-step function returning some arbitrary value instead of a new state, returns an on-step function assoc'ing this value at the data-path in the state.

Idiomatic.

Given an `on-step` function returning some arbitrary value instead of a new state, returns an `on-step`
function assoc'ing this value at the data-path in the state.

Idiomatic.
sourceraw docstring

fn-mirror-percentclj

(fn-mirror-percent map-only-percent)

Behaves just like fn-mirror but the function provided in the first place simply maps a percent value to an arbitrary one instead of being an on-step function.

Small convenient helper when the current state and data-path are not needed.

Behaves just like `fn-mirror` but the function provided in the first place simply maps a percent value to
an arbitrary one instead of being an `on-step` function.

Small convenient helper when the current state and data-path are not needed.
sourceraw docstring

fn-onceclj

(fn-once n-steps on-step)
(fn-once n-steps on-step on-complete)

Returns a function returning a transition.

Useful for poly-transitions.

Cf. once poly

Returns a function returning a transition.

Useful for poly-transitions.


Cf. `once`
    `poly`
sourceraw docstring

fn-polyclj

(fn-poly fn-transitions)
(fn-poly fn-transitions on-complete)

Returns a function returning a poly-transition.

Useful for nested poly-transitions.

Cf. poly

Returns a function returning a poly-transition.

Useful for nested poly-transitions.


Cf. `poly`
sourceraw docstring

fn-poly-infiniteclj

(fn-poly-infinite fn-transitions)

Returns a function returning an infinite poly-transition.

Useful for nested poly-transitions.

Cf. poly poly-infinite

Returns a function returning an infinite poly-transition.

Useful for nested poly-transitions.


Cf. `poly`
    `poly-infinite`
sourceraw docstring

fn-poly-repeatingclj

(fn-poly-repeating n-times fn-transitions)
(fn-poly-repeating n-times fn-transitions on-complete)

Returns a function returning a repeating poly-transition.

Useful for nested poly-transitions.

Cf. poly poly-repeating

Returns a function returning a repeating poly-transition.

Useful for nested poly-transitions.


Cf. `poly`
    `poly-repeating`
sourceraw docstring

fn-repeatingclj

(fn-repeating n-times n-steps on-step)
(fn-repeating n-times n-steps on-step on-complete)

Returns a function returning a repeating transition.

Useful for poly-transitions.

Cf. repeating poly

Returns a function returning a repeating transition.

Useful for poly-transitions.


Cf. `repeating`
    `poly`
sourceraw docstring

fn-scaleclj

(fn-scale scaled-a scaled-b)
(fn-scale scaled-a scaled-b a b)

Exactly like scale but does not accept a value to scale. Instead, returns a function which does so.

Particularly useful when working with the percentage of completion of transitions.

Exactly like `scale` but does not accept a value to scale. Instead, returns a function which does so.

Particularly useful when working with the percentage of completion of transitions.
sourceraw docstring

in-transition?clj

(in-transition? state)
(in-transition? state data-path)

Is the given state or some part of it currently in transition?

Is the given state or some part of it currently in transition?
sourceraw docstring

infiniteclj

(infinite first-step n-steps on-step)

Returns a transition endlessly repeating cycles of n-steps steps.

Obviously, it does not need an on-complete function.

Returns a transition endlessly repeating cycles of `n-steps` steps.

Obviously, it does not need an `on-complete` function.
sourceraw docstring

last-stepclj

(last-step first-step n-steps)

Simplify provides the last step of a transition given its first-step and the number of steps it lasts.

Simplify provides the last step of a transition given its first-step and the number of steps it lasts.
sourceraw docstring

merge-transitionsclj

(merge-transitions state transitions)

Deep merges the provided - often nested - map of transitions in the given state.

Very useful for adding or removing several transitions at once. Indeed, nil values are simply removed when moving the state.

Deep merges the provided - often nested - map of transitions in the given state.

Very useful for adding or removing several transitions at once. Indeed, nil values are simply removed when moving the state.
sourceraw docstring

millis->n-stepsclj

(millis->n-steps millis hz)

Computes the number of steps needed for completing a transition in millis milliseconds for a phenomenon, such as the frame-rate, happening hz per second.

Ex. Computing the number of frames needed in order to last 2000 milliseconds with a frame-rate of 60.

(millis->n-steps 2000
                 60)

=> 120
Computes the number of steps needed for completing a transition in `millis` milliseconds for a phenomenon,
such as the frame-rate, happening `hz` per second.


Ex. Computing the number of frames needed in order to last 2000 milliseconds with a frame-rate of 60.

    (millis->n-steps 2000
                     60)

    => 120
sourceraw docstring

moveclj

(move state step)

Moves a state to the given step (ie. returns a new state representing the given state at the given step).

It belongs to the user to ensure steps are not skipped if it is the needed behavior.

Moves a state to the given step (ie. returns a new state representing the given state at the given step).

It belongs to the user to ensure steps are not skipped if it is the needed behavior.
sourceraw docstring

move-eventsclj

(move-events state step-seq events handle-event)

Merely moving a state is often not enough. Typically, some events happen which modify the state in some way, add, remove, or replace transitions. This function does exactly that.

It behaves like move-seq in that it moves an initial state following a sequence of steps. However, the state is also modified by following a sequence of events and an event handler.

An event is an arbitrary map which describes something happening at some arbitrary step. As such, it must have a step associated under the step-key key. Events are assumed to be sorted in chronological order (ie. by step).

handle-event takes the current state and an event, it must return a new state. It is called everytime an event happens.

Like move-seq, returns a lazy sequence of [state' step].

Merely moving a state is often not enough. Typically, some events happen which modify the state in some way, add, remove,
or replace transitions. This function does exactly that.

It behaves like `move-seq` in that it moves an initial state following a sequence of steps. However, the state is also modified
by following a sequence of events and an event handler.

An event is an arbitrary map which describes something happening at some arbitrary step. As such, it must have a step associated
under the `step-key` key. Events are assumed to be sorted in chronological order (ie. by step).

`handle-event` takes the current state and an event, it must return a new state. It is called everytime an event happens.


Like `move-seq`, returns a lazy sequence of [state' step].
sourceraw docstring

move-seqclj

(move-seq state step-seq)

Returns a lazy sequence of [state' step] by iteratively moving the given state following the given sequence of steps.

Stops as soon as it reaches the end of step-seq or it detects there no more transitions, meaning it is useless to continue.

Returns a lazy sequence of [state' step] by iteratively moving the given state following the given sequence of steps.

Stops as soon as it reaches the end of `step-seq` or it detects there no more transitions, meaning it is useless to
continue.
sourceraw docstring

onceclj

(once first-step n-steps on-step)
(once first-step n-steps on-step on-complete)

Returns a transition lasting n-steps steps.

Returns a transition lasting `n-steps` steps.
sourceraw docstring

pipe-completeclj

(pipe-complete on-completes)

Given a collection of on-complete functions, returns an on-complete function piping arguments into this collection.

Nil values are simply filtered-out.

Given a collection of `on-complete` functions, returns an `on-complete` function piping arguments into this collection.

Nil values are simply filtered-out.
sourceraw docstring

polyclj

(poly state first-step fn-transitions)
(poly state first-step fn-transitions on-complete)

Returns a poly-transition which will follow a collection of functions producing transitions.

Those functions will be provided with the state at the moment the transition is created, the first-step of this transition and an on-complete function which must not be ignored. This on-complete function ensures that the next transition, if there is one, will be created.

Returns a poly-transition which will follow a collection of functions producing transitions.

Those functions will be provided with the state at the moment the transition is created, the first-step 
of this transition and an `on-complete` function which must not be ignored. This `on-complete` function
ensures that the next transition, if there is one, will be created.
sourceraw docstring

poly-infiniteclj

(poly-infinite state first-step fn-transitions)

Union of infinite and poly. Returns a poly-transition endlessly repeating.

Union of `infinite` and `poly`. Returns a poly-transition endlessly repeating.
sourceraw docstring

poly-repeatingclj

(poly-repeating state first-step n-times fn-transitions)
(poly-repeating state first-step n-times fn-transitions on-complete)

Union of repeating and poly. Returns a poly-transition repeating n-times.

Union of `repeating` and `poly`. Returns a poly-transition repeating `n-times`.
sourceraw docstring

remove-dataclj

(remove-data state data-path)
(remove-data state data-path _percent)
(remove-data state data-path _completion-step _step)

Uses dissoc-in for removing what is at some data-path.

More useful when used as an on-complete function and the data needs to be cleaned once the transition completes.

Uses `dissoc-in` for removing what is at some data-path.

More useful when used as an `on-complete` function and the data needs to be cleaned once the transition completes.
sourceraw docstring

remove-pre-dataclj

(remove-pre-data state data-path)
(remove-pre-data state data-path _percent)
(remove-pre-data state data-path _completion-step _step)

A vast majority of modeling involves some form of entities. It is also very common for such entities to be removed once all their transitions completes, meaning they cannot evolve anymore. This function, used as an on-complete function, does exactly that.

For instance, modeling asteroids as {:asteroids {42 {:x 542 :y 1000}}} having :x and :y transitions.

Once it cannot move anymore, an asteroid must be cleaned (ie. removed from the state). By providing this function as an on-complete function to every :x and :y transition garantees that. It will use dissoc-in for removing [:asteroids 42] once it does not have any transitions anymore.

A vast majority of modeling involves some form of entities. It is also very common for such entities to be removed once all
their transitions completes, meaning they cannot evolve anymore. This function, used as an `on-complete` function, does exactly that.

For instance, modeling asteroids as {:asteroids {42 {:x 542
                                                     :y 1000}}} having :x and :y transitions.

Once it cannot move anymore, an asteroid must be cleaned (ie. removed from the state). By providing this function as an `on-complete`
function to every :x and :y transition garantees that. It will use `dissoc-in` for removing [:asteroids 42] once it does not have
any transitions anymore.
sourceraw docstring

remove-transitionclj

(remove-transition state data-path)
(remove-transition state data-path _percent)
(remove-transition state data-path _completion-step _step)

Removes a transition given the data-path.

Removes a transition given the data-path.
sourceraw docstring

repeatingclj

(repeating first-step n-times n-steps on-step)
(repeating first-step n-times n-steps on-step on-complete)

Returns a transition repeating n-steps steps n-times times.

Returns a transition repeating `n-steps` steps `n-times` times.
sourceraw docstring

scaleclj

(scale scaled-a scaled-b percent)
(scale scaled-a scaled-b a b x)

3 args : scales a percent value to a value between scaled-a and scaled-b.

5 args : scales the x value between a and b to be between scaled-a and scaled-b.

Ex. (scale 0 1000 0.5)

=> 500


(scale 0
       1000
       0
       100
       50)

=> 500
3 args : scales a `percent` value to a value between `scaled-a` and `scaled-b`.

5 args : scales the `x` value between `a` and `b` to be between `scaled-a` and `scaled-b`.


Ex. (scale 0
           1000
           0.5)

    => 500


    (scale 0
           1000
           0
           100
           50)

    => 500
sourceraw docstring

step-keyclj

When using move-events, each event must have a step assigned by this key.

When using `move-events`, each event must have a step assigned by this key.
sourceraw docstring

transition-keyclj

All transitions belonging to a state must be under this key.

All transitions belonging to a state must be under this key.
sourceraw docstring

transition-pathclj

(transition-path data-path)

Given a data-path, returns a transition-path

Given a data-path, returns a transition-path
sourceraw docstring

without-transitionsclj

(without-transitions state)

Returns the given state without its transitions.

Returns the given state without its transitions.
sourceraw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close