packages feed

elerea-examples-1.2.0: doc/Chase.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title></title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><meta name="generator" content="pandoc" /><link rel="stylesheet" href="hscolour.css" type="text/css" media="all" />
</head><body><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html><head><!-- Generated by HsColour, http://www.cs.york.ac.uk/fp/darcs/hscolour/ --><title>Haskell code</title> <link type='text/css' rel='stylesheet' href='hscolour.css' /> </head><body><div id="elerea-chase-example"><h1>Elerea Chase example</h1><p>This is a minimal example to show how to define signals that can be mutually recursive and can optionally depend on user input too. The grey square accelerates towards the red square at a rate proportional to their relative position, and it can be given a momentary impulse with the left mouse button.</p><p>For a slightly more complex example check out <code>Breakout.lhs</code>.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-comment'>{-# LANGUAGE RecursiveDo #-}</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>module</span> <span class='hs-conid'>Main</span> <span class='hs-keyword'>where</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Applicative</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>IORef</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>FRP</span><span class='hs-varop'>.</span><span class='hs-conid'>Elerea</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Graphics</span><span class='hs-varop'>.</span><span class='hs-conid'>UI</span><span class='hs-varop'>.</span><span class='hs-conid'>GLFW</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>GLFW</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Graphics</span><span class='hs-varop'>.</span><span class='hs-conid'>Rendering</span><span class='hs-varop'>.</span><span class='hs-conid'>OpenGL</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Vector</span>
</pre><p>The <code>main</code> function contains the whole reactive logic. Note that <code>driveNetwork</code> is just a wrapper around the <code>superstep</code> function of the core library, and you can see its source below in the <code>Utils</code> module.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-varid'>main</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>initialize</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>openWindow</span> <span class='hs-layout'>(</span><span class='hs-conid'>Size</span> <span class='hs-num'>640</span> <span class='hs-num'>480</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>DisplayRGBBits</span> <span class='hs-num'>8</span> <span class='hs-num'>8</span> <span class='hs-num'>8</span><span class='hs-layout'>,</span> <span class='hs-conid'>DisplayAlphaBits</span> <span class='hs-num'>8</span><span class='hs-layout'>,</span> <span class='hs-conid'>DisplayDepthBits</span> <span class='hs-num'>24</span><span class='hs-keyglyph'>]</span> <span class='hs-conid'>Window</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>windowTitle</span> <span class='hs-varop'>$=</span> <span class='hs-str'>"Elerea Chase"</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span>   <span class='hs-layout'>(</span><span class='hs-varid'>windowSize</span><span class='hs-layout'>,</span><span class='hs-varid'>windowSizeSink</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>external</span> <span class='hs-varid'>vnull</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-layout'>(</span><span class='hs-varid'>mousePosition</span><span class='hs-layout'>,</span><span class='hs-varid'>mousePositionSink</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>external</span> <span class='hs-varid'>vnull</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-layout'>(</span><span class='hs-varid'>mousePress</span><span class='hs-layout'>,</span><span class='hs-varid'>mousePressSink</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>external</span> <span class='hs-conid'>False</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>closed</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>newIORef</span> <span class='hs-conid'>False</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>windowSizeCallback</span> <span class='hs-varop'>$=</span> <span class='hs-varid'>resizeGLScene</span> <span class='hs-varid'>windowSizeSink</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>windowCloseCallback</span> <span class='hs-varop'>$=</span> <span class='hs-varid'>writeIORef</span> <span class='hs-varid'>closed</span> <span class='hs-conid'>True</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>initGL</span> <span class='hs-num'>640</span> <span class='hs-num'>480</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>greyPos</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>createSignal</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>mdo</span>
<span class='hs-varop'>&gt;</span>         <span class='hs-varid'>mouseClick</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>edge</span> <span class='hs-varid'>mousePress</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span>         <span class='hs-keyword'>let</span> <span class='hs-varid'>acc</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>mousePosition</span><span class='hs-varop'>^-^</span><span class='hs-varid'>pos</span><span class='hs-layout'>)</span><span class='hs-varop'>^*.</span><span class='hs-num'>0.3</span>
<span class='hs-varop'>&gt;</span>         <span class='hs-varid'>pos</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>integralVec</span> <span class='hs-varid'>vnull</span> <span class='hs-varid'>vel</span>
<span class='hs-varop'>&gt;</span>         <span class='hs-varid'>vel0</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>integralVec</span> <span class='hs-varid'>vnull</span> <span class='hs-varid'>acc</span>
<span class='hs-varop'>&gt;</span>         <span class='hs-varid'>vel</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>sampler</span> <span class='hs-varop'>&lt;$&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>storeJust</span> <span class='hs-varid'>vel0</span> <span class='hs-varop'>.</span> <span class='hs-varid'>generator</span> <span class='hs-varid'>mouseClick</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>                <span class='hs-layout'>(</span><span class='hs-varid'>integralVec</span> <span class='hs-varop'>&lt;$&gt;</span> <span class='hs-varid'>vel</span><span class='hs-varop'>^+^</span><span class='hs-varid'>pos</span><span class='hs-varop'>^-^</span><span class='hs-varid'>mousePosition</span> <span class='hs-varop'>&lt;*&gt;</span> <span class='hs-varid'>pure</span> <span class='hs-varid'>acc</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span>         <span class='hs-varid'>return</span> <span class='hs-varid'>pos</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>driveNetwork</span> <span class='hs-layout'>(</span><span class='hs-varid'>render</span> <span class='hs-varop'>&lt;$&gt;</span> <span class='hs-varid'>windowSize</span> <span class='hs-varop'>&lt;*&gt;</span> <span class='hs-varid'>mousePosition</span> <span class='hs-varop'>&lt;*&gt;</span> <span class='hs-varid'>greyPos</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>                <span class='hs-layout'>(</span><span class='hs-varid'>readInput</span> <span class='hs-varid'>mousePositionSink</span> <span class='hs-varid'>mousePressSink</span> <span class='hs-varid'>closed</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>closeWindow</span>
</pre><p>The <code>render</code> function takes a snapshot of the system (window size and the positions of the squares) and turns it into OpenGL calls. The signal executed by the <code>driveNetwork</code> function is the time-varying version of the IO action returned here.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-varid'>render</span> <span class='hs-layout'>(</span><span class='hs-conid'>V</span> <span class='hs-varid'>w</span> <span class='hs-varid'>h</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>V</span> <span class='hs-varid'>cx</span> <span class='hs-varid'>cy</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>V</span> <span class='hs-varid'>ox</span> <span class='hs-varid'>oy</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-keyword'>let</span> <span class='hs-varid'>drawSquare</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<span class='hs-varop'>&gt;</span>         <span class='hs-varid'>loadIdentity</span>
<span class='hs-varop'>&gt;</span>         <span class='hs-varid'>translate</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Vector3</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-varop'>/</span><span class='hs-varid'>w</span><span class='hs-varop'>*</span><span class='hs-num'>2</span><span class='hs-comment'>-</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>h</span><span class='hs-varop'>/</span><span class='hs-varid'>w</span><span class='hs-comment'>-</span><span class='hs-varid'>y</span><span class='hs-varop'>/</span><span class='hs-varid'>w</span><span class='hs-varop'>*</span><span class='hs-num'>2</span><span class='hs-layout'>)</span> <span class='hs-num'>0</span>
<span class='hs-varop'>&gt;</span>         <span class='hs-varid'>renderPrimitive</span> <span class='hs-conid'>Quads</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span>
<span class='hs-varop'>&gt;</span>           <span class='hs-varid'>vertex</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Vertex3</span> <span class='hs-layout'>(</span><span class='hs-comment'>-</span><span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-comment'>-</span><span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>GLfloat</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>           <span class='hs-varid'>vertex</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Vertex3</span> <span class='hs-layout'>(</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-comment'>-</span><span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>GLfloat</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>           <span class='hs-varid'>vertex</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Vertex3</span> <span class='hs-layout'>(</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>GLfloat</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>           <span class='hs-varid'>vertex</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Vertex3</span> <span class='hs-layout'>(</span><span class='hs-comment'>-</span><span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>GLfloat</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>clear</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>ColorBuffer</span><span class='hs-keyglyph'>]</span>
<span class='hs-varop'>&gt;</span>  
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>color</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Color4</span> <span class='hs-num'>1</span> <span class='hs-num'>0</span> <span class='hs-num'>0</span> <span class='hs-layout'>(</span><span class='hs-num'>0.5</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>GLfloat</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>drawSquare</span> <span class='hs-varid'>cx</span> <span class='hs-varid'>cy</span> <span class='hs-num'>0.05</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>color</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Color4</span> <span class='hs-num'>1</span> <span class='hs-num'>1</span> <span class='hs-num'>1</span> <span class='hs-layout'>(</span><span class='hs-num'>0.6</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>GLfloat</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>drawSquare</span> <span class='hs-varid'>ox</span> <span class='hs-varid'>oy</span> <span class='hs-num'>0.03</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>flush</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>swapBuffers</span>
</pre><p>The <code>readInput</code> function provides the driver layer. It feeds the peripheral-bound signals and also decides when to stop execution by returning <code>Nothing</code> instead of the time elapsed since its last call.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-varid'>readInput</span> <span class='hs-varid'>mousePos</span> <span class='hs-varid'>mouseBut</span> <span class='hs-varid'>closed</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>t</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>get</span> <span class='hs-conid'>GLFW</span><span class='hs-varop'>.</span><span class='hs-varid'>time</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-conid'>GLFW</span><span class='hs-varop'>.</span><span class='hs-varid'>time</span> <span class='hs-varop'>$=</span> <span class='hs-num'>0</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-conid'>Position</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>get</span> <span class='hs-conid'>GLFW</span><span class='hs-varop'>.</span><span class='hs-varid'>mousePos</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>mousePos</span> <span class='hs-layout'>(</span><span class='hs-conid'>V</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>b</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-conid'>GLFW</span><span class='hs-varop'>.</span><span class='hs-varid'>getMouseButton</span> <span class='hs-conid'>GLFW</span><span class='hs-varop'>.</span><span class='hs-conid'>ButtonLeft</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>mouseBut</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span> <span class='hs-varop'>==</span> <span class='hs-conid'>GLFW</span><span class='hs-varop'>.</span><span class='hs-conid'>Press</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>k</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>getKey</span> <span class='hs-conid'>ESC</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>c</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>closed</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-keyword'>if</span> <span class='hs-varid'>c</span> <span class='hs-varop'>||</span> <span class='hs-varid'>k</span> <span class='hs-varop'>==</span> <span class='hs-conid'>Press</span> <span class='hs-keyword'>then</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyword'>else</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>t</span><span class='hs-layout'>)</span>
</pre><p>OpenGL is initialised with practically everything turned off. Only alpha blending is needed to be able to use translucent colours.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-varid'>initGL</span> <span class='hs-varid'>width</span> <span class='hs-varid'>height</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>clearColor</span> <span class='hs-varop'>$=</span> <span class='hs-conid'>Color4</span> <span class='hs-num'>0</span> <span class='hs-num'>0</span> <span class='hs-num'>0</span> <span class='hs-num'>1</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>blend</span> <span class='hs-varop'>$=</span> <span class='hs-conid'>Enabled</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>blendFunc</span> <span class='hs-varop'>$=</span> <span class='hs-layout'>(</span><span class='hs-conid'>SrcAlpha</span><span class='hs-layout'>,</span><span class='hs-conid'>OneMinusSrcAlpha</span><span class='hs-layout'>)</span>
</pre><p>The window size callback takes care of the <code>windowSize</code> signal and the projection matrix.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-varid'>resizeGLScene</span> <span class='hs-varid'>winSize</span> <span class='hs-varid'>size</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Size</span> <span class='hs-varid'>w</span> <span class='hs-varid'>h</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>winSize</span> <span class='hs-layout'>(</span><span class='hs-conid'>V</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>h</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>viewport</span> <span class='hs-varop'>$=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Position</span> <span class='hs-num'>0</span> <span class='hs-num'>0</span><span class='hs-layout'>,</span><span class='hs-varid'>size</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span> 
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>matrixMode</span> <span class='hs-varop'>$=</span> <span class='hs-conid'>Projection</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>loadIdentity</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>scale</span> <span class='hs-num'>1</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>w</span><span class='hs-varop'>/</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>h</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-num'>1</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>GLfloat</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>  
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>matrixMode</span> <span class='hs-varop'>$=</span> <span class='hs-conid'>Modelview</span> <span class='hs-num'>0</span>
</pre></div><div id="utils-module"><h1>Utils module</h1><p>This module contains some functions that might make it into the core library eventually.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-keyword'>module</span> <span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span> <span class='hs-keyword'>where</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Applicative</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>FRP</span><span class='hs-varop'>.</span><span class='hs-conid'>Elerea</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Vector</span>
</pre><p>The <code>driveNetwork</code> function simply executes the supersteps while the <code>driver</code> function keeps returning valid delta time values.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-varid'>driveNetwork</span> <span class='hs-varid'>network</span> <span class='hs-varid'>driver</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-varid'>dt</span> <span class='hs-keyglyph'>&larr;</span> <span class='hs-varid'>driver</span>
<span class='hs-varop'>&gt;</span>   <span class='hs-keyword'>case</span> <span class='hs-varid'>dt</span> <span class='hs-keyword'>of</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-conid'>Just</span> <span class='hs-varid'>dt</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>join</span> <span class='hs-varop'>$</span> <span class='hs-varid'>superstep</span> <span class='hs-varid'>network</span> <span class='hs-varid'>dt</span>
<span class='hs-varop'>&gt;</span>                   <span class='hs-varid'>driveNetwork</span> <span class='hs-varid'>network</span> <span class='hs-varid'>driver</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
</pre><p>A scalar integral function for <code>Fractional</code> instances.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-varid'>integral</span> <span class='hs-varid'>v0</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>transfer</span> <span class='hs-varid'>v0</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>dt</span> <span class='hs-varid'>v</span> <span class='hs-varid'>v0</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v0</span><span class='hs-varop'>+</span><span class='hs-varid'>v</span><span class='hs-varop'>*</span><span class='hs-varid'>realToFrac</span> <span class='hs-varid'>dt</span><span class='hs-layout'>)</span> <span class='hs-varid'>s</span>
</pre><p>An integral function for two-dimensional vectors defined in the <code>Vector</code> module.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-varid'>integralVec</span> <span class='hs-varid'>v0</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>transfer</span> <span class='hs-varid'>v0</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>dt</span> <span class='hs-varid'>v</span> <span class='hs-varid'>v0</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v0</span><span class='hs-varop'>^+^</span><span class='hs-layout'>(</span><span class='hs-varid'>v</span><span class='hs-varop'>^*.</span><span class='hs-varid'>realToFrac</span> <span class='hs-varid'>dt</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>s</span>
</pre></div><div id="vector-module"><h1>Vector module</h1><p>This module contains a class for two-dimensional vectors, a strict datatype to instantiate it, and another instance for signals of the same type.</p><pre><span class='hs-varop'>&gt;</span> <span class='hs-comment'>{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, TypeSynonymInstances #-}</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>module</span> <span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Vector</span> <span class='hs-keyword'>where</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Applicative</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>FRP</span><span class='hs-varop'>.</span><span class='hs-conid'>Elerea</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>import</span> <span class='hs-conid'>Graphics</span><span class='hs-varop'>.</span><span class='hs-conid'>Rendering</span><span class='hs-varop'>.</span><span class='hs-conid'>OpenGL</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>data</span> <span class='hs-conid'>Vec</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>V</span> <span class='hs-layout'>{</span> <span class='hs-varid'>getX</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>GLfloat</span><span class='hs-layout'>,</span> <span class='hs-varid'>getY</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>GLfloat</span> <span class='hs-layout'>}</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>infixl</span> <span class='hs-num'>7</span> <span class='hs-varop'>^*.</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>infixl</span> <span class='hs-num'>7</span> <span class='hs-varop'>.*^</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>infixl</span> <span class='hs-num'>7</span> <span class='hs-varop'>`dot`</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>infixl</span> <span class='hs-num'>7</span> <span class='hs-varop'>`cross`</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>infixl</span> <span class='hs-num'>6</span> <span class='hs-varop'>^+^</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>infixl</span> <span class='hs-num'>6</span> <span class='hs-varop'>^-^</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>class</span> <span class='hs-conid'>Vector2D</span> <span class='hs-varid'>v</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>c</span> <span class='hs-keyword'>where</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-layout'>(</span><span class='hs-varop'>^+^</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-layout'>(</span><span class='hs-varop'>^-^</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-layout'>(</span><span class='hs-varop'>^*.</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-layout'>(</span><span class='hs-varop'>.*^</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-varid'>vnull</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>v</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-varid'>dot</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>c</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-varid'>cross</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>&rarr;</span> <span class='hs-varid'>c</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>instance</span> <span class='hs-conid'>Vector2D</span> <span class='hs-conid'>Vec</span> <span class='hs-conid'>GLfloat</span> <span class='hs-keyword'>where</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-conid'>V</span> <span class='hs-varid'>x1</span> <span class='hs-varid'>y1</span> <span class='hs-varop'>^+^</span> <span class='hs-conid'>V</span> <span class='hs-varid'>x2</span> <span class='hs-varid'>y2</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>V</span> <span class='hs-layout'>(</span><span class='hs-varid'>x1</span><span class='hs-varop'>+</span><span class='hs-varid'>x2</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>y1</span><span class='hs-varop'>+</span><span class='hs-varid'>y2</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-conid'>V</span> <span class='hs-varid'>x1</span> <span class='hs-varid'>y1</span> <span class='hs-varop'>^-^</span> <span class='hs-conid'>V</span> <span class='hs-varid'>x2</span> <span class='hs-varid'>y2</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>V</span> <span class='hs-layout'>(</span><span class='hs-varid'>x1</span><span class='hs-comment'>-</span><span class='hs-varid'>x2</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>y1</span><span class='hs-comment'>-</span><span class='hs-varid'>y2</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-conid'>V</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-varop'>^*.</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>V</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-varop'>*</span><span class='hs-varid'>t</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>y</span><span class='hs-varop'>*</span><span class='hs-varid'>t</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-varid'>t</span> <span class='hs-varop'>.*^</span> <span class='hs-conid'>V</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>V</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-varop'>*</span><span class='hs-varid'>t</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>y</span><span class='hs-varop'>*</span><span class='hs-varid'>t</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-varid'>vnull</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>V</span> <span class='hs-num'>0</span> <span class='hs-num'>0</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-conid'>V</span> <span class='hs-varid'>x1</span> <span class='hs-varid'>y1</span> <span class='hs-varop'>`dot`</span> <span class='hs-conid'>V</span> <span class='hs-varid'>x2</span> <span class='hs-varid'>y2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x1</span><span class='hs-varop'>*</span><span class='hs-varid'>y1</span><span class='hs-varop'>+</span><span class='hs-varid'>x2</span><span class='hs-varop'>*</span><span class='hs-varid'>y2</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-conid'>V</span> <span class='hs-varid'>x1</span> <span class='hs-varid'>y1</span> <span class='hs-varop'>`cross`</span> <span class='hs-conid'>V</span> <span class='hs-varid'>x2</span> <span class='hs-varid'>y2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x1</span><span class='hs-varop'>*</span><span class='hs-varid'>y2</span><span class='hs-comment'>-</span><span class='hs-varid'>x2</span><span class='hs-varop'>*</span><span class='hs-varid'>y1</span>
<span class='hs-varop'>&gt;</span>
<span class='hs-varop'>&gt;</span> <span class='hs-keyword'>instance</span> <span class='hs-conid'>Vector2D</span> <span class='hs-layout'>(</span><span class='hs-conid'>Signal</span> <span class='hs-conid'>Vec</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>Signal</span> <span class='hs-conid'>GLfloat</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-layout'>(</span><span class='hs-varop'>^+^</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>liftA2</span> <span class='hs-layout'>(</span><span class='hs-varop'>^+^</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-layout'>(</span><span class='hs-varop'>^-^</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>liftA2</span> <span class='hs-layout'>(</span><span class='hs-varop'>^-^</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-layout'>(</span><span class='hs-varop'>^*.</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>liftA2</span> <span class='hs-layout'>(</span><span class='hs-varop'>^*.</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-layout'>(</span><span class='hs-varop'>.*^</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>liftA2</span> <span class='hs-layout'>(</span><span class='hs-varop'>.*^</span><span class='hs-layout'>)</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-varid'>vnull</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>pure</span> <span class='hs-varid'>vnull</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-varid'>dot</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>liftA2</span> <span class='hs-varid'>dot</span>
<span class='hs-varop'>&gt;</span>     <span class='hs-varid'>cross</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>liftA2</span> <span class='hs-varid'>cross</span>
</pre></body>
</html>

</div></body></html>