packages feed

hylogen 0.1.0.6 → 0.1.0.8

raw patch · 5 files changed

+136/−88 lines, 5 filesdep +fsnotifydep −hinotifyPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: fsnotify

Dependencies removed: hinotify

API changes (from Hackage documentation)

+ Hylogen.Globals: mix :: Vec1 -> Vec4 -> Vec4 -> Vec4
+ Hylogen.Globals: resolution :: Vec2
+ Hylogen.Globals: vec2 :: (Show tc, ConstructFrom tc Vec2) => tc -> Vec2
+ Hylogen.Globals: vec3 :: (Show tc, ConstructFrom tc Vec3) => tc -> Vec3
+ Hylogen.Globals: vec4 :: (Show tc, ConstructFrom tc Vec4) => tc -> Vec4
+ Hylogen.Types: Bcomp_ :: String -> Vec1 -> Vec1 -> Booly
+ Hylogen.Types: Dot :: a -> a -> Vec1
+ Hylogen.Types: instance Data.VectorSpace.InnerSpace Hylogen.Types.Vec1
+ Hylogen.Types: instance Data.VectorSpace.InnerSpace Hylogen.Types.Vec2
+ Hylogen.Types: instance Data.VectorSpace.InnerSpace Hylogen.Types.Vec3
+ Hylogen.Types: instance Data.VectorSpace.InnerSpace Hylogen.Types.Vec4
+ Hylogen.Types: toList :: HyloPrim v => v -> [Vec1]
- Hylogen.Types: Vec2 :: (Vec1, Vec1) -> Vec2
+ Hylogen.Types: Vec2 :: tc -> Vec2
- Hylogen.Types: Vec3 :: (Vec1, Vec1, Vec1) -> Vec3
+ Hylogen.Types: Vec3 :: tc -> Vec3
- Hylogen.Types: Vec4 :: (Vec1, Vec1, Vec1, Vec1) -> Vec4
+ Hylogen.Types: Vec4 :: tc -> Vec4
- Hylogen.Types: vec :: HyloPrim v => HyloConstructor v -> v
+ Hylogen.Types: vec :: (HyloPrim v, Show tc, ConstructFrom tc v) => tc -> v

Files

app/Main.hs view
@@ -17,8 +17,9 @@ import Network.WebSockets import System.Environment (getArgs) import System.FilePath-import System.INotify+import System.FSNotify import System.Process+ -- import System.Random  main :: IO ()@@ -27,25 +28,21 @@   _ -> error "Name a file to watch!"  main' :: FilePath ->  IO ()-main' pathToWatch = do+main' pathToWatch = withManager $ \mgr -> do   _ <- forkIO $ serveIndex-  runServer "127.0.0.1" 8080 $ handleConnection pathToWatch+  runServer "127.0.0.1" 8080 $ handleConnection pathToWatch mgr -handleConnection :: FilePath -> PendingConnection -> IO ()-handleConnection pathToWatch pending = do+handleConnection :: FilePath -> WatchManager -> PendingConnection -> IO ()+handleConnection pathToWatch mgr pending = do    let (dirToWatch, fileToWatch) = splitFileName pathToWatch-   inotify <- initINotify-   print inotify    connection <- acceptRequest pending+    (sendTextData connection . T.pack) =<< getNewSource pathToWatch-   -- withINotify $ \inotify ->-   _ <- addWatch inotify [Modify] dirToWatch $ \case-      Modified False (Just f) | f == fileToWatch ->-         (sendTextData connection . T.pack) =<< getNewSource pathToWatch-      _ -> return ()---  print wd---  removeWatch wd---  receiveDataMessage connection++   let onChange e = case e of+         Modified _ _ -> (sendTextData connection . T.pack) =<< getNewSource pathToWatch+         _ -> return ()+   _ <- watchDir mgr dirToWatch (const True) onChange    _ <- getLine -- temp hack to keep the socket open    return () 
app/index.html view
@@ -85,34 +85,31 @@      <canvas id="canvas"></canvas>     <script>-     const vsSource = `-attribute vec3 aPosition;-varying vec2 uvN;-void main() {-  gl_Position = vec4(aPosition, 1.0);-  uvN = aPosition.xy;-}-`;-     const fsHeader=`-precision mediump float;-const float pi = 3.141592653589793238462643383;-uniform float time;-uniform vec2 mouse;-uniform vec4 audio;-uniform sampler2D backBuffer;-varying vec2 uvN;--vec2 uv() {-  return 0.5 * uvN  + 0.5;-}+     var vsSource = [ "attribute vec3 aPosition;"+                    , "varying vec2 uvN;"+                    , "void main() {"+                    , "  gl_Position = vec4(aPosition, 1.0);"+                    , "  uvN = aPosition.xy;"+                    , "}"+     ].join("\n"); -`+     var fsHeader= [ "precision mediump float;"+                   , "const float pi = 3.141592653589793238462643383;"+                   , "uniform float time;"+                   , "uniform vec2 mouse;"+                   , "uniform vec2 resolution;"+                   , "uniform vec4 audio;"+                   , "uniform sampler2D backBuffer;"+                   , "varying vec2 uvN;"+                   , "vec2 uv() {"+                   , "  return 0.5 * uvN  + 0.5;"+                   , "}"+     ].join("\n"); -     const initialFsSource = `-void main() {-    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);-}-`;+     var initialFsSource = [ "void main() {"+                           , "    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);"+                           , "}"+     ].join("\n");        function loadProgram (gl, state, vsSource, fsSource) {@@ -123,13 +120,13 @@        function compileShader (gl, source, shaderType) {          //assert(shaderType === gl.FRAGMENT_SHADER || shaderType === g.VERTEXT_SHADER); -         let shader = gl.createShader(shaderType);+         var shader = gl.createShader(shaderType);           gl.shaderSource(shader, source);          gl.compileShader(shader);  -         let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);+         var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);          if (!success) {            console.log(source);            throw "could not compile shader:" + gl.getShaderInfoLog(shader);@@ -140,18 +137,18 @@   -       let vs = compileShader(gl, vsSource, gl.VERTEX_SHADER);-       let fs = compileShader(gl, fsSource, gl.FRAGMENT_SHADER);+       var vs = compileShader(gl, vsSource, gl.VERTEX_SHADER);+       var fs = compileShader(gl, fsSource, gl.FRAGMENT_SHADER);  -       let program = gl.createProgram();+       var program = gl.createProgram();         gl.attachShader(program, vs);        gl.attachShader(program, fs);         gl.linkProgram(program); -       let success = gl.getProgramParameter(program, gl.LINK_STATUS);+       var success = gl.getProgramParameter(program, gl.LINK_STATUS);        if (!success) {          throw ("program failed to link:" + gl.getProgramInfoLog(program));        }@@ -171,7 +168,7 @@         // backBuffer stuff        function createTarget() {-         let target = {+         var target = {            texture: gl.createTexture(),            framebuffer: gl.createFramebuffer()          };@@ -201,18 +198,20 @@        gl.time = gl.getUniformLocation(program, "time");        gl.mouse = gl.getUniformLocation(program, "mouse");        gl.audio = gl.getUniformLocation(program, "audio");+       gl.resolution = gl.getUniformLocation(program, "resolution");        gl.backBuffer = gl.getUniformLocation(program, "backBuffer");         draw(gl, state);         if (state.animationFrameRequest === null) {-         state.animationFrameRequest = requestAnimationFrame(() => animate(gl, state));+         state.animationFrameRequest = requestAnimationFrame(function() {animate(gl, state);});        }      }       function draw (gl, state) {        gl.uniform1f(gl.time, (new Date().getTime() / 1000 - state.time0));        gl.uniform2f(gl.mouse, state.mouse.x, state.mouse.y);+       gl.uniform2f(gl.resolution, WIDTH, HEIGHT);        gl.uniform4f(gl.audio, state.audio.low, state.audio.mid, state.audio.upper, state.audio.high);         gl.uniform1i(gl.backBuffer, 0); // Do I need to check for null?@@ -235,7 +234,7 @@       function animate (gl, state) {        draw(gl, state);-       state.animationFrameRequest = requestAnimationFrame(() => animate(gl, state));+       state.animationFrameRequest = requestAnimationFrame(function() { animate(gl, state);});      };  @@ -250,14 +249,14 @@          function setMouse (event) {-         let r = event.target.getBoundingClientRect();+         var r = event.target.getBoundingClientRect();          state.mouse.x = (event.clientX - r.left) / (r.right - r.left) * 2 -1;          state.mouse.y = (event.clientY - r.bottom) / (r.top - r.bottom) * 2 - 1;        };        /* canvas.onmousedown = (event) => setMouse(event, 1); */        /* canvas.onmouseup = (event) => setMouse(event, 0); */ -       canvas.onmousemove = (event) => setMouse(event);+       canvas.onmousemove = setMouse;        state.mouse = {x: 0, y: 0};  @@ -265,14 +264,14 @@        state.audioAgain = null;         function onAccept (stream) {-         let audioCtx = new (window.AudioContext || window.webkitAudioContext)();-         let source = audioCtx.createMediaStreamSource(stream);-         let analyser = audioCtx.createAnalyser();+         var audioCtx = new (window.AudioContext || window.webkitAudioContext)();+         var source = audioCtx.createMediaStreamSource(stream);+         var analyser = audioCtx.createAnalyser();          source.connect(analyser);           analyser.fftSize = 512;-         let bufferLength = analyser.frequencyBinCount;-         let dataArray = new Uint8Array(bufferLength);+         var bufferLength = analyser.frequencyBinCount;+         var dataArray = new Uint8Array(bufferLength);            function toAudio() {@@ -280,8 +279,8 @@            analyser.getByteFrequencyData(dataArray);             // Taken from The_Force-           let k = 0, f = 0.0;-           let a = 5, b = 11, c = 24, d = bufferLength, i = 0;+           var k = 0, f = 0.0;+           var a = 5, b = 11, c = 24, d = bufferLength, i = 0;             for(; i < a; i++) {              f += dataArray[i];@@ -332,20 +331,20 @@       // stateful variables -     const canvas = document.getElementById("canvas");-     let WIDTH = Math.max(window.innerHeight, window.innerWidth);-     let HEIGHT =  Math.max(window.innerHeight, window.innerWidth);+     var canvas = document.getElementById("canvas");+     var WIDTH = Math.max(window.innerHeight, window.innerWidth);+     var HEIGHT =  Math.max(window.innerHeight, window.innerWidth);      canvas.width = WIDTH;      canvas.height = HEIGHT; -     const gl = canvas.getContext("webgl");+     var gl = canvas.getContext("webgl"); -     const state = {};+     var state = {};       setupState(state, canvas);  -     loadProgram (gl, state,  vsSource, fsHeader + initialFsSource);+     loadProgram (gl, state,  vsSource, fsHeader + "\n" + initialFsSource);        function fadeOut(elem) {@@ -356,13 +355,13 @@      }       function connectToHylogen() {-       const wsConn = new WebSocket("ws://localhost:8080/");+       var wsConn = new WebSocket("ws://localhost:8080/");         wsConn.onopen = function() {-         const landing = document.getElementById("landing");+         var landing = document.getElementById("landing");          if (landing) {            fadeOut(document.getElementById("bg"));-           window.setTimeout(() => {fadeOut(landing);}, 500);+           window.setTimeout(function() {fadeOut(landing);}, 500);          }          console.log('websocket opened'); @@ -375,7 +374,7 @@         wsConn.onmessage = function (m) {          console.log(m.data);-         loadProgram(gl, state,  vsSource, fsHeader + m.data);+         loadProgram(gl, state,  vsSource, fsHeader + "\n" + m.data);        };      } 
hylogen.cabal view
@@ -1,5 +1,5 @@ name:                hylogen-version:             0.1.0.6+version:             0.1.0.8 synopsis:            an EDSL for live-coding fragment shaders description:         an EDSL for live-coding fragment shaders homepage:            https://github.com/sleexyz/hylogen@@ -28,7 +28,7 @@   build-depends:       base                      , bytestring                      , filepath-                     , hinotify+                     , fsnotify                      , network                      , process                      , random
src/Hylogen/Globals.hs view
@@ -3,8 +3,17 @@ module Hylogen.Globals where  import Hylogen.Types+import Data.VectorSpace +vec2 :: (Show tc, ConstructFrom tc Vec2) => tc -> Vec2+vec2 = Vec2 +vec3 :: (Show tc, ConstructFrom tc Vec3) => tc -> Vec3+vec3 = Vec3++vec4 :: (Show tc, ConstructFrom tc Vec4) => tc -> Vec4+vec4 = Vec4+ inverseSqrt :: (HyloPrim a) => a -> a inverseSqrt = vuop "inversesqrt" @@ -43,6 +52,9 @@ uvN :: Vec2 uvN = V2u "uvN" +resolution :: Vec2+resolution = V2u "resolution"+ mouse :: Vec2 mouse = V2u "mouse" @@ -52,6 +64,9 @@  backBuffer :: Texture backBuffer = Tu "backBuffer"++mix :: Vec1 -> Vec4 -> Vec4 -> Vec4+mix p a b = p *^ a + (1 - p) *^ b  -- | Booly's 
src/Hylogen/Types.hs view
@@ -1,25 +1,41 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE NoMonomorphismRestriction #-}-{-# LANGUAGE NoMonoLocalBinds #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ExtendedDefaultRules #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-}  module Hylogen.Types where + import Data.Monoid import Data.VectorSpace+import GHC.Exts (Constraint) --- | Darn I need injective type families.. waiting for GHC8-type family HyloConstructor v where-  HyloConstructor Vec1 = Float-  HyloConstructor Vec2 = (Vec1, Vec1)-  HyloConstructor Vec3 = (Vec1, Vec1, Vec1)-  HyloConstructor Vec4 = (Vec1, Vec1, Vec1, Vec1) +type family (ConstructFrom tc hprim) :: Constraint where+  ConstructFrom a Vec1 = a ~ Float+  ConstructFrom (a, b) Vec2 = (a ~ Vec1, b ~ Vec1)++  ConstructFrom (a, b, c) Vec3 = (a ~ Vec1, b ~ Vec1, c ~ Vec1)+  ConstructFrom (Vec2, b) Vec3 = (b ~ Vec1)+  ConstructFrom (a, Vec2) Vec3 = (a ~ Vec1)++  ConstructFrom (a, b, c, d) Vec4 = (a ~ Vec1, b ~ Vec1, c ~ Vec1, d ~ Vec1)+  ConstructFrom (Vec3, b) Vec4 = (b ~ Vec1)+  ConstructFrom (Vec2, b) Vec4 = (b ~ Vec2)+  ConstructFrom (a, Vec3) Vec4 = (a ~ Vec1)+  ConstructFrom (a, Vec2, c) Vec4 = (a ~ Vec1, c ~ Vec1)+  ConstructFrom (Vec2, b, c) Vec4 = (b ~ Vec1, c ~ Vec1)+  ConstructFrom (a, b, Vec2) Vec4 = (a ~ Vec1, b ~ Vec1)++ class (Show v) => HyloPrim v where-  vec :: HyloConstructor v -> v+  vec :: (Show tc, ConstructFrom tc v) => tc -> v   vu :: String -> v   vuop :: String -> v -> v   vuoppre :: String -> v -> v@@ -27,15 +43,16 @@   vboppre :: String -> v -> v -> v   select :: Booly -> v -> v -> v   fromVec1 :: Vec1 -> v+  toList :: v -> [Vec1]  + class Show a => HasX a class HasX a => HasY a class HasY a => HasZ a class HasZ a => HasW a  - data Vec1 where   Vec1 :: Float -> Vec1   V1u :: String -> Vec1@@ -44,6 +61,7 @@   V1bop :: String -> Vec1 -> Vec1 -> Vec1   V1boppre :: String -> Vec1 -> Vec1 -> Vec1   V1select :: Booly -> Vec1 -> Vec1 -> Vec1+  Dot :: (HyloPrim a) => a -> a -> Vec1   X :: (HasX a) => a -> Vec1   Y :: (HasY a) => a -> Vec1   Z :: (HasZ a) => a -> Vec1@@ -60,6 +78,7 @@     V1bop b x y -> "(" <> show x <> " " <> b <> " " <> show y <> ")"     V1boppre b x y -> b <> "(" <> show x <> ", " <> show y <> ")"     V1select b x y -> "( " <> show b <> " ? " <> show x <> " : " <> show y <> ")"+    Dot x y -> "dot(" <> show x <> ", " <> show y <> ")"     X x ->  show x <> ".x"     Y x ->  show x <> ".y"     Z x ->  show x <> ".z"@@ -75,6 +94,7 @@   vboppre = V1boppre   select = V1select   fromVec1 = id+  toList x = [x]  instance Num Vec1 where   (+) = vbop "+"@@ -119,10 +139,13 @@   type Scalar Vec1 = Vec1   a *^ b = a * b +instance InnerSpace Vec1 where+  (<.>) = Dot+ -- | Vec2:  data Vec2 where-  Vec2 :: (Vec1, Vec1) -> Vec2+  Vec2 :: (Show tc, ConstructFrom tc Vec2) => tc -> Vec2   V2u :: String -> Vec2   V2uop :: String -> Vec2 -> Vec2   V2uoppre :: String -> Vec2 -> Vec2@@ -140,11 +163,12 @@   vboppre = V2boppre   select = V2select   fromVec1 x = Vec2 (x, x)+  toList x = [X x, Y x]   instance Show Vec2 where   show expr = case expr of-    Vec2 (x, y) -> "vec2(" <> show x <> ", " <> show y <> ")"+    Vec2 tc -> "vec2" <> show tc     V2u x -> x     V2uop u x -> u <> "(" <> show x <> ")"     V2uoppre u x -> "(" <> u <> show x <> ")"@@ -196,6 +220,9 @@   type Scalar Vec2 = Vec1   a *^ b = V2bops "*" a b +instance InnerSpace Vec2 where+  (<.>) = Dot+ instance HasX Vec2 instance HasY Vec2 @@ -203,7 +230,7 @@ -- | Vec3:  data Vec3 where-  Vec3 :: (Vec1, Vec1, Vec1) -> Vec3+  Vec3 :: (Show tc, ConstructFrom tc Vec3) => tc -> Vec3   V3u :: String -> Vec3   V3uop :: String -> Vec3 -> Vec3   V3uoppre :: String -> Vec3 -> Vec3@@ -221,10 +248,11 @@   vboppre = V3boppre   select = V3select   fromVec1 x = Vec3 (x, x, x)+  toList x = [X x, Y x, Z x]  instance Show Vec3 where   show expr = case expr of-    Vec3 (x, y, z) -> "vec3(" <> show x <> ", " <> show y <> ", " <> show z <> ")"+    Vec3 tc -> "vec3" <> show tc     V3u x -> x     V3uop u x -> u <> "(" <> show x <> ")"     V3uoppre u x -> "(" <> u <> show x <> ")"@@ -276,6 +304,9 @@   type Scalar Vec3 = Vec1   a *^ b = V3bops "*" a b +instance InnerSpace Vec3 where+  (<.>) = Dot+ instance HasX Vec3 instance HasY Vec3 instance HasZ Vec3@@ -285,7 +316,7 @@ -- | Vec4:  data Vec4 where-  Vec4 :: (Vec1, Vec1, Vec1, Vec1) -> Vec4+  Vec4 :: (Show tc, ConstructFrom tc Vec4) => tc -> Vec4   V4u :: String -> Vec4   V4uop :: String -> Vec4 -> Vec4   V4uoppre :: String -> Vec4 -> Vec4@@ -305,10 +336,11 @@   vboppre = V4boppre   select = V4select   fromVec1 x = Vec4 (x, x, x, x)+  toList x = [X x, Y x, Z x, W x]  instance Show Vec4 where   show expr = case expr of-    Vec4 (x, y, z, w) -> "vec4(" <> show x <> ", " <> show y <> ", " <> show z <> ", " <> show w <> ")"+    Vec4 tc -> "vec4" <> show tc     V4u x -> x     V4uop u x -> u <> "(" <> show x <> ")"     V4uoppre u x -> "(" <> u <> show x <> ")"@@ -361,6 +393,9 @@   type Scalar Vec4 = Vec1   a *^ b = V4bops "*" a b +instance InnerSpace Vec4 where+  (<.>) = Dot+ instance HasX Vec4 instance HasY Vec4 instance HasZ Vec4@@ -381,6 +416,7 @@   Buoppre :: String -> Booly -> Booly   Bbop :: String -> Booly -> Booly -> Booly   Bcomp :: (HyloPrim a) => String -> a -> a -> Booly+  Bcomp_ :: String -> Vec1 -> Vec1 -> Booly  instance Show Booly where   show expr = case expr of@@ -388,7 +424,8 @@     Buop u x -> u <> "(" <> show x <> ")"     Buoppre u x -> "(" <> u <> show x <> ")"     Bbop u x y -> "(" <> show x <> " " <> u <> " " <>  show y <> ")"-    Bcomp u x y -> "(" <> show x <> " " <> u <> " " <>  show y <> ")"+    Bcomp u x y -> show . product $ zipWith (Bcomp_ u) (toList x) (toList y)+    Bcomp_ u x y -> "(" <> show x <> " " <> u <> " " <>  show y <> ")"  instance Num Booly where   (+) = Bbop "||"