Refaktor, postavljen reagent in secretary, popravki

master
Jure Podgoršek 2018-08-10 16:35:52 +02:00
parent 29da6fa0d3
commit c8b6ceebdc
12 changed files with 283 additions and 111 deletions

View File

@ -10,7 +10,9 @@
</head>
<body style="margin: 0">
<div id="container"></div>
<!-- script type="text/javascript" src="js/three.min.js"></script-->
<script src="js/compiled/sliva.js" type="text/javascript"></script>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript" src="js/audioRecorder.js"></script>
<script type="text/javascript" src="js/audioRecorderWorker.js"></script>
<script type="text/javascript" src="js/compiled/sliva.js"></script>
</body>
</html>

View File

@ -0,0 +1,65 @@
(function(window) {
var AUDIO_RECORDER_WORKER = 'js/audioRecorderWorker.js';
var AudioRecorder = function(source, cfg) {
this.consumers = [];
var config = cfg || {};
var errorCallback = config.errorCallback || function() {};
var inputBufferLength = config.inputBufferLength || 4096;
var outputBufferLength = config.outputBufferLength || 4000;
this.context = source.context;
this.node = this.context.createScriptProcessor(inputBufferLength);
var worker = new Worker(config.worker || AUDIO_RECORDER_WORKER);
worker.postMessage({
command: 'init',
config: {
sampleRate: this.context.sampleRate,
outputBufferLength: outputBufferLength,
outputSampleRate: (config.outputSampleRate || 16000)
}
});
var recording = false;
this.node.onaudioprocess = function(e) {
if (!recording) return;
worker.postMessage({
command: 'record',
buffer: [
e.inputBuffer.getChannelData(0),
e.inputBuffer.getChannelData(1)
]
});
};
this.start = function(data) {
this.consumers.forEach(function(consumer, y, z) {
consumer.postMessage({ command: 'start', data: data });
recording = true;
return true;
});
recording = true;
return (this.consumers.length > 0);
};
this.stop = function() {
if (recording) {
this.consumers.forEach(function(consumer, y, z) {
consumer.postMessage({ command: 'stop' });
});
recording = false;
}
worker.postMessage({ command: 'clear' });
};
this.cancel = function() {
this.stop();
};
myClosure = this;
worker.onmessage = function(e) {
if (e.data.error && (e.data.error == "silent")) errorCallback("silent");
if ((e.data.command == 'newBuffer') && recording) {
myClosure.consumers.forEach(function(consumer, y, z) {
consumer.postMessage({ command: 'process', data: e.data.data });
});
}
};
source.connect(this.node);
this.node.connect(this.context.destination);
};
window.AudioRecorder = AudioRecorder;
})(window);

View File

@ -0,0 +1,59 @@
var recBuffers = [],
outputSampleRate = 16000,
inSampleRate;
this.onmessage = function(e){
switch(e.data.command){
case 'init':
init(e.data.config);
break;
case 'record':
record(e.data.buffer);
break;
case 'clear':
clear();
break;
}
};
function init(config){
inSampleRate = config.sampleRate;
outputBufferLength = config.outputBufferLength;
outputSampleRate = config.outputSampleRate || outputSampleRate;
}
function record(inputBuffer){
var isSilent = true;
for (var i = 0 ; i < inputBuffer[0].length ; i++) {
recBuffers.push((inputBuffer[0][i] + inputBuffer[1][i]) * 16383.0);
}
while(recBuffers.length * outputSampleRate / inSampleRate > outputBufferLength) {
var result = new Int16Array(outputBufferLength);
var bin = 0,
num = 0,
indexIn = 0,
indexOut = 0;
while(indexIn < outputBufferLength) {
bin = 0;
num = 0;
while(indexOut < Math.min(recBuffers.length, (indexIn + 1) * inSampleRate / outputSampleRate)) {
bin += recBuffers[indexOut];
num += 1;
indexOut++;
}
result[indexIn] = bin / num;
if(isSilent && (result[indexIn] != 0)) isSilent = false;
indexIn++;
}
var output = {};
output.command = 'newBuffer';
output.data = result;
if (isSilent) output.error = "silent";
this.postMessage(output);
recBuffers = recBuffers.slice(indexOut);
}
}
function clear(){
recBuffers = [];
}

View File

@ -1,10 +1,11 @@
(ns sliva.core
(:require
[secretary.core :as secretary :refer-macros [defroute]]
(:require [secretary.core :as secretary :refer-macros [defroute]]
[reagent.core :as reagent]
[sliva.socket :refer [websocket-init click-test]]
[sliva.data :refer [appstate]]
[sliva.routes :refer [app-routes]]
[sliva.pages.hub :refer [hub]])
[sliva.pages.hub :refer [hub]]
[sliva.pages.visual :refer [visual]])
(:require-macros [cljs.core.async.macros :refer [go go-loop]]))
(enable-console-print!)
@ -13,20 +14,20 @@
;; Page switching
(defmulti current-page #(@appstate :page))
(defmethod current-page :hub [] hub)
;;(defn on-js-reload []
;; (stop-render)
;; (start-render)
;; (websocket-init))
(defmethod current-page :hub [] [hub])
(defmethod current-page :visual [] [visual])
;; On figwheel reload do this (reload routes, render currently active page)
(defn init-app []
(app-routes)
(console.log "App (re)init!")
(reagent/render [current-page] (.getElementById js/document "container")))
;; Vstopna tocka
(aset js/document "onreadystatechange"
(fn []
(if (= (.-readyState js/document) "complete")
(init-app))))
(do
(websocket-init)
(click-test)
(init-app)))))

View File

@ -5,6 +5,26 @@
;; App state atom
(def appstate
(reagent/atom
{:clients []}))
(def vtic (atom (chan)))
{:clients []
:vtic (chan)
:vizual {:animiraj false
;;;;; ☭☭☭☭☭☭☭☭☭☭☭☭☭☭ ;;;;;;
;; ☭☭☭☭ Parametri razni ☭☭☭☭ ;;
;;;;; ☭☭☭☭☭☭☭☭☭☭☭☭☭☭ ;;;;;;
:odmik-kamere 100
:rotacija-kamere 1
:bg-barva 0x000000
:FOV 140
:lik-sirina 2
:obj-limit 1000
:objekti []
:stevec 0
:rotacija-x 0.006
:rotacija-y 0.001
:rotacija-z 0.003
:zamik-barve 0.0000666
:zacetna-barva 0.333
:saturacija 1
:svetlost 0.4
:w-diff 0.5
:gostota-obj 2}}))

View File

@ -1,37 +1,20 @@
(ns sliva.gfx)
(ns sliva.gfx
(:require [sliva.data :refer [appstate]]))
;;;;; ☭☭☭☭☭☭☭☭☭☭☭☭☭☭ ;;;;;;
;; ☭☭☭☭ Parametri razni ☭☭☭☭ ;;
;;;;; ☭☭☭☭☭☭☭☭☭☭☭☭☭☭ ;;;;;;
(defn get-param [param]
(get-in @appstate [:vizual param]))
(def odmik-kamere 100)
(def rotacija-kamere 1)
(def FOV 140)
(def lik-sirina 2)
(def obj-limit 1000)
(def objekti (atom []))
(def stevec (atom 0))
(def rotacija-x 0.006)
(def rotacija-y 0.001)
(def rotacija-z 0.003)
(def zamik-barve 0.0000666)
(def zacetna-barva 0.333)
(def saturacija 1)
(def svetlost 0.4)
(def w-diff 0.5)
(def gostota-obj 2)
(defn set-param [param val]
(swap! appstate assoc-in [:vizual param] val))
;; Inicializacija ;;
(def scena (THREE.Scene.))
(def kamera (THREE.PerspectiveCamera. FOV (/ (.-innerWidth js/window)
(def kamera (THREE.PerspectiveCamera.
(get-param :FOV)
(/ (.-innerWidth js/window)
(.-innerHeight js/window)) 0.1 2000))
(aset kamera "position" "z" odmik-kamere)
(aset kamera "position" "z" (get-param :odmik-kamere))
(aset kamera "aspect" (/ (.-innerWidth js/window)
(.-innerHeight js/window)))
(.updateProjectionMatrix kamera)
@ -40,7 +23,7 @@
(.setSize izris (.-innerWidth js/window) (.-innerHeight js/window))
;; Crno ozadje
(.setClearColor izris 0x000000 1)
(.setClearColor izris (get-param :bg-barva) 1)
(defn dodaj-obj [sirina]
(let [barva (js/THREE.Color.)
@ -51,7 +34,11 @@
-zamik (* -1 zamik)]
;; Nastavi barvo novega objekta
(.setHSL barva (* @stevec zacetna-barva) saturacija svetlost)
(.setHSL barva
(* (get-param :stevec)
(get-param :zacetna-barva))
(get-param :saturacija)
(get-param :svetlost))
(aset mat "color" barva)
;; Kvadratek (za nov objekt)
@ -61,55 +48,47 @@
(.push koti (js/THREE.Vector3. zamik 0 0) (js/THREE.Vector3. 0 -zamik 0))
(let [obj (js/THREE.Line. geo mat (.-LineSegments js/THREE))
novi-objekti (conj (take obj-limit @objekti)
novi-objekti (conj (take (get-param :obj-limit) (get-param :objekti))
obj)]
(.add scena obj)
;; pucaj sceno ane
(reset! objekti novi-objekti))))
(set-param :objekti novi-objekti))))
(defn obj-anim [obj]
(.rotateY obj rotacija-y)
(.rotateZ obj rotacija-z)
(.rotateX obj rotacija-x)
(.rotateY obj (get-param :rotacija-y))
(.rotateZ obj (get-param :rotacija-z))
(.rotateX obj (get-param :rotacija-x))
(let [new-scale (+ (aget obj "scale" "x")
w-diff)]
(get-param :w-diff))]
(aset obj "scale" "x" new-scale)
(aset obj "scale" "y" new-scale)
(aset obj "scale" "z" new-scale))
(.offsetHSL (aget obj "material" "color") zamik-barve 0 0))
(.offsetHSL (aget obj "material" "color") (get-param :zamik-barve) 0 0))
(defn cam-rotate []
(.translateX kamera rotacija-kamere)
(.translateZ kamera (- odmik-kamere
(.sqrt js/Math (+ (.pow js/Math odmik-kamere 2)
(.pow js/Math rotacija-kamere 2)))))
(.lookAt kamera scena.position))
(.translateX kamera (get-param :rotacija-kamere))
(.translateZ kamera (- (get-param :odmik-kamere)
(.sqrt js/Math (+ (.pow js/Math (get-param :odmik-kamere) 2)
(.pow js/Math (get-param :rotacija-kamere) 2)))))
(.lookAt kamera (.-position scena)))
(defn render []
(.requestAnimationFrame js/window render)
(if (get-in @appstate [:vizual :animiraj])
(.requestAnimationFrame js/window render))
(reset! stevec (inc @stevec))
(set-param :stevec (inc (get-param :stevec)))
(if (= 0 (rem @stevec gostota-obj))
(dodaj-obj lik-sirina))
(if (= 0 (rem (get-param :stevec) (get-param :gostota-obj)))
(dodaj-obj (get-param :lik-sirina)))
(.render izris scena kamera)
(run! obj-anim @objekti)
(run! obj-anim (get-param :objekti))
(cam-rotate))
(defn start-render []
(let [container (.getElementById js/document "container")]
(.appendChild container (.-domElement izris))))
(defn stop-render []
(let [container (.getElementById js/document "container")]
(.removeChild container (.-firstChild container))))
;; Hendlaj risajz
(defn on-window-resize[]
(let [sirina (.-innerWidth js/window)
@ -117,4 +96,15 @@
(aset kamera "aspect" (/ sirina visina))
(.updateProjectionMatrix kamera)
(.setSize izris sirina visina)))
(defn start-render [container]
(.appendChild container (.-domElement izris))
(swap! appstate assoc-in [:vizual :animiraj] true)
(.addEventListener js/window "resize" on-window-resize false)
(render))
(defn stop-render [container]
(swap! appstate assoc-in [:vizual :animiraj] false)
(.removeEventListener js/window "resize" on-window-resize false)
(.removeChild container (.-firstChild container)))

View File

@ -1,9 +1,6 @@
(ns sliva.pages.hub
(:require [sliva.socket :refer [websocket-init click-test]]
[sliva.data :refer [appstate]]))
(websocket-init)
(click-test)
(:require [sliva.data :refer [appstate]]
[sliva.pages.navigation :refer [navigation]]))
(defn hub []
[:div
@ -12,10 +9,14 @@
[:thead
[:tr
[:th "Client ID"]
[:th "Something else?"]]]
[:th "status"]]]
[:tbody
(map (fn [cid]
[:tr {:key cid}
(let [clients (:clients @appstate)]
(if (empty? clients)
[:tr [:td "No"] [:td "clients"]]
(->> clients
(map-indexed (fn [idx cid]
[:tr {:key idx}
[:td cid]
[:td "connected"]])
(keys (:clients @appstate)))]]])
[:td "connected"]])))))]]
(navigation)])

View File

@ -0,0 +1,8 @@
(ns sliva.pages.navigation)
(defn navigation []
[:div
[:h2 "Navigation"]
[:ul
[:li [:a {:href "#/hub"} "Hub"]]
[:li [:a {:href "#/visual"} "Visual"]]]])

View File

@ -0,0 +1,15 @@
(ns sliva.pages.visual
(:require [reagent.core :as reagent]
[sliva.gfx :refer [start-render stop-render]]
[sliva.pages.navigation :refer [navigation]]))
(defn visual []
(reagent/create-class
{:display-name "vizual-render-plac"
:reagent-render (fn [] [:div
[:div {:ref "vizual"}]
[navigation]])
:component-did-mount (fn [this] (start-render (.. this -refs -vizual)))
:component-will-unmount (fn [this]
(console.log "unmounting?")
(stop-render (.. this -refs -vizual)))}))

View File

@ -14,7 +14,10 @@
(.setEnabled true)))
(defn app-routes []
(secretary/set-config! :prefix "#☭")
(defroute "/" []
(swap! appstate assoc :page :hub))
;;(secretary/set-config! :prefix "#☭")
(secretary/set-config! :prefix "#")
(defroute "/" [] (swap! appstate assoc :page :hub))
(defroute "/hub" [] (swap! appstate assoc :page :hub))
(defroute "/visual" [] (swap! appstate assoc :page :visual))
(defroute "/test" [] (console.log "test!"))
(hook-browser-navigation!))

View File

@ -1,5 +1,6 @@
(ns sliva.server.handlers
(:require [compojure.core :refer [defroutes GET]]
(:require [clojure.java.shell :refer [sh]]
[compojure.core :refer [defroutes GET]]
[compojure.route :refer [resources]]
[clojure.string :as str]
[clojure.core.async :refer [chan <! <!! >! put! close! go go-loop]]
@ -21,7 +22,7 @@
(go
(let [{:keys [message]} (<! ws-ch)]
(println "new connection - " cid)
(>! ws-ch (str "Hello " cid))
(>! ws-ch (str "hello:" cid))
(swap! clients assoc cid ws-ch)
(send-all "open" cid)
(go-loop []
@ -31,7 +32,11 @@
(println "command" cmd "(" args ")")
(condp = cmd
"ping" (>! ws-ch "pong")
"Unknown command :/")) (keys @clients)
(println "DEBUG: msg ignored: " cmd))) (keys @clients)
(recur))))))))
;;(close! ws-ch)))))
;;test
;;(while true
;; (let [return (sh "sudo" "bash" "-c" "iwlist scan | grep ESSID | sed 's/[[:space:]]\\+ESSID://' | sed 's/\"//g' | uniq")]
;; (println "GOT NETWORKS!" (:out return)))

View File

@ -1,35 +1,38 @@
(ns sliva.socket
(:require [chord.client :refer [ws-ch]]
[clojure.string :as str]
[cljs.core.async :refer [<! >! put! close!]]
[sliva.data :refer [vtic]])
[sliva.data :refer [appstate]])
(:require-macros [cljs.core.async.macros :refer [go go-loop]]))
;; Zacetek ;;
;;(aset js/document "onreadystatechange"
;; (fn []
;; (if (= (.-readyState js/document) "complete")
;; (do
;; (start-render)
;; (render)
;; (websocket-init)))))
(defn handle-message [msg-str]
(let [[msg & args] (str/split msg-str #":")]
(console.info "msg" msg "args" args)
(condp = msg
"pong" (console.log "hura, server se odziva")
"open" (swap! appstate assoc :clients (conj (:clients @appstate) (first args)))
(console.info "msg ingored: " msg))))
(defn websocket-init []
(console.log "init webscoket")
(go (let [{:keys [ws-channel error]} (<! (ws-ch "ws://localhost:3449/ws"))]
(go (let [host (aget js/window "location" "hostname")
{:keys [ws-channel error]} (<! (ws-ch (str "ws://" host ":3449/ws")))]
(if-not error
(do
(reset! vtic ws-channel)
(>! ws-channel "Hello server")
(swap! appstate assoc :vtic ws-channel)
(>! ws-channel "hello:server")
;; (go-loop []
;; (let [{:keys [message]} (<! ws-channel)]
;; (console.log "got msg" message)
;; (socket-handler message)
;; (recur))))
)
(go-loop []
(let [{:keys [message]} (<! ws-channel)]
(handle-message message)
(recur))))
(js/console.log "Fejl websocket: " (pr-str error))))))
(defn click-test []
(.addEventListener js/window "click" (fn []
(go []
(>! @vtic "ping")))))
(.addEventListener
js/window
"click"
(fn []
(let [vtic (:vtic @appstate)]
(console.log "klik")
(put! vtic "ping")))))