packages feed

essence-of-live-coding-gloss-example (empty) → 0.2.1

raw patch · 5 files changed

+285/−0 lines, 5 filesdep +basedep +essence-of-live-codingdep +essence-of-live-coding-glosssetup-changed

Dependencies added: base, essence-of-live-coding, essence-of-live-coding-gloss, gloss, syb, transformers

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for essence-of-live-coding-gloss-example++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2019, Manuel Bärenz++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Manuel Bärenz nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,199 @@+{-# LANGUAGE Arrows #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE StandaloneDeriving #-}+-- base+import qualified Control.Arrow as Arrow++import Data.Data++import Prelude hiding (Bounded)++-- transformers+import Control.Monad.Trans.Accum++import Control.Monad.Trans.Class+import Control.Monad.Trans.Reader (ask)+import Control.Monad.Trans.State.Strict (StateT)+import Control.Monad.Trans.Writer.Strict++-- syb+import Data.Generics.Aliases (ext2Q)++-- gloss+import Graphics.Gloss hiding (translate)+import qualified Graphics.Gloss as Gloss++-- essence-of-live-coding+import LiveCoding hiding (left, right)++-- essence-of-live-coding-gloss+import LiveCoding.Gloss hiding (statePicture, every, translate)++main :: IO ()+main = runHandlingStateT $ foreground liveProgram++liveProgram :: LiveProgram (HandlingStateT IO)+liveProgram = liveCell $ glossWrapC defaultSettings { debugEvents = True } glossCell++glossCell' :: Cell PictureM () ()+glossCell'+  = speed+  >>> integrate+  >>> arr sin+  >>> arr (*10)+  >>> arr realToFrac+  >>> arr circleThing+  >>> addPicture+  where+    circleThing x+      = (Gloss.translate (x * 10 - 90) 0 $ color green $ thickCircle 10 20)+      <> (Gloss.translate (-x * 10 - 90) (-40) $ color red $ thickCircle 10 20)++speed ::  Cell PictureM () Float+speed = proc () -> do+  events <- arrM (const ask) -< ()+  sumC -< sum $ isEventMouseClick <$> events++isEventMouseClick :: Event -> Float+isEventMouseClick (EventKey (MouseButton LeftButton) _ _ _) = 1+isEventMouseClick (EventKey (MouseButton RightButton) _ _ _) = -1+isEventMouseClick _ = 0+++glossCell :: Cell PictureM () ()+glossCell = withDebuggerC glossCell' glossDebugger++-- * To be ported to essence-of-live-coding-gloss (and delete the Arrows)++statePicture :: Data s => s -> Picture+statePicture = Gloss.translate (-100) 100 . scale 0.1 0.1 . color red . getPic . stateBoundedPic++stateBoundedPic :: Data s => s -> BoundedPic+stateBoundedPic =+  (boundPic . text . stateShow)+  `ext2Q` compPic++data Bounds = Bounds+  { left   :: Float+  , right  :: Float+  , bottom :: Float+  , top    :: Float+  }++instance Semigroup Bounds where+  bounds1 <> bounds2 = Bounds+    { left   = min (left   bounds1) (left   bounds2)+    , right  = max (right  bounds1) (right  bounds2)+    , bottom = min (bottom bounds1) (bottom bounds2)+    , top    = max (top    bounds1) (top    bounds2)+    }++instance Monoid Bounds where+  mempty = boundPoint (0, 0)++boundPoint :: Point -> Bounds+boundPoint (x, y) = Bounds x x y y++boundPath :: Path -> Bounds+boundPath path = mconcat $ boundPoint <$> path++pad :: Float -> Bounds -> Bounds+pad padding Bounds { .. } = Bounds+  { left   = left   - padding+  , right  = right  + padding+  , bottom = bottom - padding+  , top    = top    + padding+  }++translateBounds :: Point -> Bounds -> Bounds+translateBounds (x, y) Bounds { .. } = Bounds+  { left   = left   + x+  , right  = right  + x+  , bottom = bottom + y+  , top    = top    + y+  }++scaleBounds :: Float -> Float -> Bounds -> Bounds+scaleBounds x y Bounds { .. } = Bounds+  { left   = left   * x+  , right  = right  * x+  , bottom = bottom * y+  , top    = top    * y+  }++type Bounded a = Accum Bounds a++type BoundedPic = Bounded Picture++-- deriving via Ap Bounded Picture instance Monoid BoundedPic++getBounds :: BoundedPic -> Bounds+getBounds = flip execAccum mempty++getPic :: BoundedPic -> Picture+getPic  = flip evalAccum mempty++transformBounds :: (Bounds -> Bounds) -> BoundedPic -> BoundedPic+transformBounds f = mapAccumT $ fmap $ Arrow.second f++transformPic :: (Picture -> Picture) -> BoundedPic -> BoundedPic+transformPic = fmap++translate :: Float -> Float -> BoundedPic -> BoundedPic+translate x y = transformBounds (translateBounds (x, y)) . transformPic (Gloss.translate x y)++bounds :: Picture -> Bounds+bounds Blank = mempty+bounds (Polygon path) = boundPath path+bounds (Line path) = boundPath path+bounds (Circle r) = Bounds r r r r+bounds (ThickCircle _ r) = Bounds r r r r+bounds (Arc _ _ r) = Bounds r r r r -- TODO Not the tightest bound+bounds (ThickArc _ _ _ r) = Bounds r r r r -- TODO Not the tightest bound+bounds (Text s) = Bounds 0 (fromIntegral $ length s * 105) (-33.3) (120) -- TODO Only rough estimates from https://hackage.haskell.org/package/GLUT-2.7.0.12/docs/Graphics-UI-GLUT-Fonts.html+bounds (Bitmap bitmapData) = let (right, top) = bitmapSize bitmapData in Bounds 0 (fromIntegral right) 0 (fromIntegral top) -- TODO Untested+bounds (BitmapSection _ bitmapData) = let (right, top) = bitmapSize bitmapData in Bounds 0 (fromIntegral right) 0 (fromIntegral top) -- TODO Untested+bounds (Color _ pic) = bounds pic+bounds (Translate x y pic) = translateBounds (x, y) $ bounds pic+bounds (Rotate angle pic) = error "Too hard right now" -- TODO+bounds (Scale x y pic) = scaleBounds x y $ bounds pic+bounds (Pictures pics) = mconcat $ bounds <$> pics++boundPic :: Picture -> BoundedPic+boundPic picture = accum $ const (picture, bounds picture)++resetLeft :: BoundedPic -> BoundedPic+resetLeft boundedPic = translate (- (left $ getBounds boundedPic)) 0 boundedPic++distance = 5++addRight :: BoundedPic -> BoundedPic -> BoundedPic+addRight bpic1 bpic2 = do+  pic1 <- bpic1+  x <- looks right+  pic2 <- translate (x + distance) 0 $ resetLeft bpic2+  return $ pic1 <> pic2++center :: BoundedPic -> BoundedPic+center boundPic = let Bounds { .. } = getBounds boundPic in translate (left + right) (bottom + top) boundPic++compPic :: (Data s1, Data s2) => Composition s1 s2 -> BoundedPic+compPic (Composition (s1, s2))+  | isUnit s1 = stateBoundedPic s2+  | isUnit s2 = stateBoundedPic s1+  | otherwise = stateBoundedPic s1 `addRight` stateBoundedPic s2++glossDebugger :: Debugger PictureM+glossDebugger = Debugger $ liveCell $ every 100 >>> keep blank >>> arrM (lift . lift . tell)++every :: Data s => Integer -> Cell (StateT s PictureM) () (Maybe Picture)+every maxN = proc () -> do+  n <- sumC -< 1+  if n `mod` maxN == 0+  then do+    s <- getC -< ()+    let pic = statePicture s+    returnA -< Just pic+  else+    returnA  -< Nothing
+ essence-of-live-coding-gloss-example.cabal view
@@ -0,0 +1,49 @@+name:                essence-of-live-coding-gloss-example+version:             0.2.1+synopsis: General purpose live coding framework - Gloss example+description:+  essence-of-live-coding is a general purpose and type safe live coding framework.+  .+  You can run programs in it, and edit, recompile and reload them while they're running.+  Internally, the state of the live program is automatically migrated when performing hot code swap.+  .+  The library also offers an easy to use FRP interface.+  It is parametrized by its side effects,+  separates data flow cleanly from control flow,+  and allows to develop live programs from reusable, modular components.+  There are also useful utilities for debugging and quickchecking.+  .+  This package contains a little example using the Gloss backend.++license:             BSD3+license-file:        LICENSE+author:              Manuel Bärenz+maintainer:          programming@manuelbaerenz.de+homepage:            https://www.manuelbaerenz.de/#computerscience+category:            FRP, Live coding+build-type:          Simple+extra-source-files:  CHANGELOG.md+cabal-version:       >=1.10++source-repository head+  type:     git+  location: git@github.com:turion/essence-of-live-coding.git++source-repository this+  type:     git+  location: git@github.com:turion/essence-of-live-coding.git+  tag:      v0.2.1+++executable essence-of-live-coding-gloss-example+  main-is:             Main.hs+  build-depends:+      base >= 4.11 && < 5+    , transformers >= 0.5+    , gloss >= 1.13+    , essence-of-live-coding >= 0.2.1+    , essence-of-live-coding-gloss >= 0.2.1+    , syb >= 0.7+  hs-source-dirs:      app+  default-language:    Haskell2010+  default-extensions: StrictData