<commit_before>#!/usr/bin/env hy

(require core.macros)

; update impure config
(let [[conf (get-config)]]
  (import [core [conf :as impure-conf]])
  (setv impure-conf.RENDER-SIZE conf.RENDER-SIZE)
  (setv impure-conf.OSC-EYE     conf.OSC-EYE))

(import
  [time [sleep]]
  [core.windows [new-renderer new-master new-overview]]
  [core.nerve [nerve-cb! nerve-start]]
  [core.pyexec [pyexec]])


(runner Eye [conf log]
        "
        Handles and draws the different visions

        Recives from Coder:
        * `/eye/code    [filename code]`
        * `/eye/delete  [filename]` (not yet implemented)
        * `/eye/move    [oldname newname]`

        Recives from Ear:
        * `/eye/audio/[cmd]  [value]`
        "
        (log.info "starting eye.hy")

        (setv visions {})

        (setv renderer (new-renderer visions
                                     conf.RENDER-SIZE))
        (new-master renderer)
        (new-overview renderer)

        (nerve-cb! "/eye/code"
                   (fn [path args]
                     (setv [name code] args)
                     (if (in name (visions.keys))
                       (.load (get visions name)
                              code)
                       (assoc visions
                         name
                         (new-vision name code)))))

        (setv nerve-stop (nerve-start))

        (import [pyglet])
        (.schedule_interval pyglet.clock
                            (fn [dt]
                              (when (stopped?)
                                (.exit pyglet.app)))
                            (/ 1 120))
        (try
          (.run pyglet.app)
          (catch [KeyboardInterrupt]
            None))

        (log.info "stopping eye.hy")
        (nerve-stop))


(defn new-vision [path code]
  (setv name
    (get (.split path "/") -1))

  (setv log (new-logger))  ; TODO pass name

  ; stack here the loaded codes,
  ; so when everything explodes, we can
  ; always restore the last (opefully) working vision
  (setv stack [])

  (defclass Box []
    "A small sandbox where to run the livecoded part"
    [[draw
      (fn [self])]])

  (setv box (Box))

  (defclass Vision []
    "
    The vision instance
    "
    [[load
      (fn [self code]
        (log.info (% "loading: %s" name))
        (setv filename (% "visions/%s" name))
        (try
          (pyexec code box.__dict__)
          (except [e Exception]
            (log.error name e))
          (else
            (.append stack code))))]

     [iteration
      (fn [self]
        (try
          (.draw box)
          ; if there is an error and stack is empty
          ; the FIRST loaded vision is broken
          (except [e Exception]
            (log.error name name e)
            (.pop stack)

            (if stack
              (pyexec (get stack -1)
                      box.__dict__)
              (log.error name "BROKEN!")))))]])

  (setv vision (Vision))
  (.load vision code)
  vision)<commit_msg>just one call to pyexec<commit_after>#!/usr/bin/env hy

(require core.macros)

; update impure config
(let [[conf (get-config)]]
  (import [core [conf :as impure-conf]])
  (setv impure-conf.RENDER-SIZE conf.RENDER-SIZE)
  (setv impure-conf.OSC-EYE     conf.OSC-EYE))

(import
  [core.windows [new-renderer new-master new-overview]]
  [core.nerve [nerve-cb! nerve-start]])


(runner Eye [conf log]
        "
        Handles and draws the different visions

        Recives from Coder:
        * `/eye/code    [filename code]`
        * `/eye/delete  [filename]` (not yet implemented)
        * `/eye/move    [oldname newname]`

        Recives from Ear:
        * `/eye/audio/[cmd]  [value]`
        "
        (log.info "starting eye.hy")

        (setv visions {})

        (setv renderer (new-renderer visions
                                     conf.RENDER-SIZE))
        (new-master renderer)
        (new-overview renderer)

        (nerve-cb! "/eye/code"
                   (fn [path args]
                     (setv [name code] args)
                     (if (in name (visions.keys))
                       (.load (get visions name)
                              code)
                       (assoc visions
                         name
                         (new-vision name code)))))

        (setv nerve-stop (nerve-start))

        (import [pyglet])
        (.schedule_interval pyglet.clock
                            (fn [dt]
                              (when (stopped?)
                                (.exit pyglet.app)))
                            (/ 1 120))
        (try
          (.run pyglet.app)
          (catch [KeyboardInterrupt]
            None))

        (log.info "stopping eye.hy")
        (nerve-stop))


(defn new-vision [path code]
  (setv name
    (get (.split path "/") -1))

  (setv log (new-logger))  ; TODO pass name

  ; stack here the loaded codes,
  ; so when everything explodes, we can
  ; always restore the last (opefully) working vision
  (setv stack [])

  (defclass Box []
    "A small sandbox where to run the livecoded part"
    [[draw
      (fn [self])]])

  (setv box (Box))

  (defclass Vision []
    "
    The vision instance
    "
    [[load
      (fn [self code]
        (log.info (% "loading: %s" name))
        (import [core.pyexec [pyexec]])
        (try
          (pyexec code box.__dict__)
          (except [e Exception]
            (log.error name e))
          (else
            (.append stack code))))]

     [iteration
      (fn [self]
        (try
          (.draw box)
          ; if there is an error and stack is empty
          ; the FIRST loaded vision is broken
          (except [e Exception]
            (log.error name name e)
            (.pop stack)

            (if stack
              (.load self (get stack -1))
              (log.error name "BROKEN!")))))]])

  (setv vision (Vision))
  (.load vision code)
  vision)
{'fraction_non_alphanumeric': 0.12106248935807934, 'fraction_numerical': 0.002043248765537204, 'mean_word_length': 1.4113300492610839, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '24980', 'n_tokens_mistral': 1856, 'n_tokens_neox': 1747, 'n_words': 510}