summaryrefslogtreecommitdiff
path: root/cmd/dolmetschctld
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/dolmetschctld')
-rw-r--r--cmd/dolmetschctld/dolmetschctld.go3
-rw-r--r--cmd/dolmetschctld/statemachine.go115
-rw-r--r--cmd/dolmetschctld/telnet.go3
-rw-r--r--cmd/dolmetschctld/web.go23
-rw-r--r--cmd/dolmetschctld/web_socket.go58
5 files changed, 61 insertions, 141 deletions
diff --git a/cmd/dolmetschctld/dolmetschctld.go b/cmd/dolmetschctld/dolmetschctld.go
index 9fa23fa..0f69b51 100644
--- a/cmd/dolmetschctld/dolmetschctld.go
+++ b/cmd/dolmetschctld/dolmetschctld.go
@@ -27,9 +27,10 @@ import (
"os"
"spreadspace.org/dolmetschctl/pkg/mixer"
+ "spreadspace.org/dolmetschctl/pkg/types"
)
-func addLanguage(sm *StateMachine, name Language, original, interpreter mixer.Channel) {
+func addLanguage(sm *StateMachine, name types.Language, original, interpreter mixer.Channel) {
if err := sm.AddLanguage(name, original, interpreter); err != nil {
log.Printf("adding language '%s' failed: %v", name, err)
os.Exit(1)
diff --git a/cmd/dolmetschctld/statemachine.go b/cmd/dolmetschctld/statemachine.go
index 2d8013f..a779604 100644
--- a/cmd/dolmetschctld/statemachine.go
+++ b/cmd/dolmetschctld/statemachine.go
@@ -29,54 +29,9 @@ import (
"time"
"spreadspace.org/dolmetschctl/pkg/mixer"
+ "spreadspace.org/dolmetschctl/pkg/types"
)
-type State int
-
-const (
- StateNew = iota
- StateSettling
- StateSettled
-)
-
-func (s State) String() string {
- switch s {
- case StateNew:
- return "new"
- case StateSettling:
- return "settling"
- case StateSettled:
- return "settled"
- default:
- return "unknown"
- }
-}
-
-func (s State) MarshalText() (data []byte, err error) {
- data = []byte(s.String())
- return
-}
-
-type Language string
-
-func (l Language) String() string {
- if l == "" {
- return "none"
- }
- return string(l)
-}
-
-func (s Language) MarshalText() (data []byte, err error) {
- data = []byte(s.String())
- return
-}
-
-type FullState struct {
- state State
- ratio float32
- language Language
-}
-
type MixerChannelState struct {
level mixer.FaderLevel
mute mixer.Mute
@@ -94,16 +49,16 @@ type MixerChannels struct {
}
type setLanguageReq struct {
- lang Language
+ lang types.Language
resCh chan error
}
type getLanguageReq struct {
- resCh chan Language
+ resCh chan types.Language
}
type getLanguagesReq struct {
- resCh chan []Language
+ resCh chan []types.Language
}
type setOriginal2InterpreterRatioReq struct {
@@ -116,7 +71,7 @@ type getOriginal2InterpreterRatioReq struct {
}
type getStateRes struct {
- FullState
+ types.FullState
}
type getStateReq struct {
@@ -124,7 +79,7 @@ type getStateReq struct {
}
type subscribeStateReq struct {
- ch chan<- FullState
+ ch chan<- types.FullState
resCh chan error
}
@@ -142,12 +97,12 @@ type StateMachine struct {
exitedCh chan struct{}
mixerEventCh chan mixer.Event
- languages map[Language]*MixerChannels
- channel2lang map[mixer.Channel]Language
+ languages map[types.Language]*MixerChannels
+ channel2lang map[mixer.Channel]types.Language
- state State
+ state types.State
original2InterpreterRatio float32
- language Language
+ language types.Language
stateSubscribers list.List
}
@@ -157,13 +112,13 @@ func (sm *StateMachine) publishState() {
for sub := sm.stateSubscribers.Front(); sub != nil; sub = next {
next = sub.Next()
- ch, ok := (sub.Value).(chan<- FullState)
+ ch, ok := (sub.Value).(chan<- types.FullState)
if !ok {
panic(fmt.Sprintf("statemachine: subscriber list element value has wrong type: %T", sub.Value))
}
select {
- case ch <- FullState{sm.state, sm.original2InterpreterRatio, sm.language}:
+ case ch <- types.FullState{sm.state, sm.original2InterpreterRatio, sm.language}:
default:
// subscriber is not responding...
// log.Printf("statemachine: removing subscriber '%v', because it is not responding", ch)
@@ -173,7 +128,7 @@ func (sm *StateMachine) publishState() {
}
}
-func (sm *StateMachine) subscribeState(out chan<- FullState) error {
+func (sm *StateMachine) subscribeState(out chan<- types.FullState) error {
// log.Printf("statemachine: %v subscribed to state changes", out)
sm.stateSubscribers.PushBack(out)
return nil
@@ -222,10 +177,10 @@ func (sm *StateMachine) initMixer() {
mcs.interpreter.target.level = mixer.FaderLevelOff
}
sm.language = ""
- sm.state = StateSettled
+ sm.state = types.StateSettled
}
-func (sm *StateMachine) getLanguages() (langs []Language) {
+func (sm *StateMachine) getLanguages() (langs []types.Language) {
langs = append(langs, "none")
for lang, _ := range sm.languages {
langs = append(langs, lang)
@@ -234,7 +189,7 @@ func (sm *StateMachine) getLanguages() (langs []Language) {
}
// the "current language" is what is currently spoken on stage
-func (sm *StateMachine) setLanguage(l Language) error {
+func (sm *StateMachine) setLanguage(l types.Language) error {
if l == "none" {
l = ""
}
@@ -283,18 +238,18 @@ func (sm *StateMachine) reconcile(ticker bool) {
}
}
- if sm.state != StateSettled && !ticker {
+ if sm.state != types.StateSettled && !ticker {
return
}
- sm.state = StateSettled
+ sm.state = types.StateSettled
for _, mcs := range sm.languages {
if mcs.original.target.level != mcs.original.current.level {
sm.mixer.SetLevel(mcs.original.num, calcNextLevel(mcs.original.target.level, mcs.original.current.level))
- sm.state = StateSettling
+ sm.state = types.StateSettling
}
if mcs.interpreter.target.level != mcs.interpreter.current.level {
sm.mixer.SetLevel(mcs.interpreter.num, calcNextLevel(mcs.interpreter.target.level, mcs.interpreter.current.level))
- sm.state = StateSettling
+ sm.state = types.StateSettling
}
}
}
@@ -311,7 +266,7 @@ func (sm *StateMachine) run() {
select {
case <-t.C:
- if sm.state == StateSettling {
+ if sm.state == types.StateSettling {
sm.reconcile(true)
}
case req := <-sm.setLanguageCh:
@@ -327,7 +282,7 @@ func (sm *StateMachine) run() {
case req := <-sm.getOriginal2InterpreterRatioCh:
req.resCh <- sm.original2InterpreterRatio
case req := <-sm.getStateCh:
- req.resCh <- getStateRes{FullState{sm.state, sm.original2InterpreterRatio, sm.language}}
+ req.resCh <- getStateRes{types.FullState{sm.state, sm.original2InterpreterRatio, sm.language}}
case req := <-sm.subscribeStateCh:
req.resCh <- sm.subscribeState(req.ch)
case ev := <-sm.mixerEventCh:
@@ -356,17 +311,17 @@ func NewStateMachine(m *mixer.Mixer) (*StateMachine, error) {
sm.exitedCh = make(chan struct{})
sm.mixerEventCh = make(chan mixer.Event, 1000)
- sm.languages = make(map[Language]*MixerChannels)
- sm.channel2lang = make(map[mixer.Channel]Language)
+ sm.languages = make(map[types.Language]*MixerChannels)
+ sm.channel2lang = make(map[mixer.Channel]types.Language)
- sm.state = StateNew
+ sm.state = types.StateNew
sm.language = ""
return sm, nil
}
// TODO: currently we can only deal with 2 languages...
-func (sm *StateMachine) AddLanguage(name Language, original, interpreter mixer.Channel) error {
- if sm.state != StateNew {
+func (sm *StateMachine) AddLanguage(name types.Language, original, interpreter mixer.Channel) error {
+ if sm.state != types.StateNew {
return fmt.Errorf("adding languages is only allowed during startup")
}
if name == "none" {
@@ -400,20 +355,20 @@ func (sm *StateMachine) Start() {
go sm.run()
}
-func (sm *StateMachine) SetLanguage(l Language) error {
+func (sm *StateMachine) SetLanguage(l types.Language) error {
resCh := make(chan error)
sm.setLanguageCh <- setLanguageReq{l, resCh}
return <-resCh
}
-func (sm *StateMachine) GetLanguage() Language {
- resCh := make(chan Language)
+func (sm *StateMachine) GetLanguage() types.Language {
+ resCh := make(chan types.Language)
sm.getLanguageCh <- getLanguageReq{resCh}
return <-resCh
}
-func (sm *StateMachine) GetLanguages() []Language {
- resCh := make(chan []Language)
+func (sm *StateMachine) GetLanguages() []types.Language {
+ resCh := make(chan []types.Language)
sm.getLanguagesCh <- getLanguagesReq{resCh}
return <-resCh
}
@@ -430,14 +385,14 @@ func (sm *StateMachine) GetOriginal2InterpreterRatio() float32 {
return <-resCh
}
-func (sm *StateMachine) GetState() (State, float32, Language) {
+func (sm *StateMachine) GetState() (types.State, float32, types.Language) {
resCh := make(chan getStateRes)
sm.getStateCh <- getStateReq{resCh}
res := <-resCh
- return res.state, res.ratio, res.language
+ return res.State, res.Ratio, res.Language
}
-func (sm *StateMachine) SubscribeState(out chan<- FullState) error {
+func (sm *StateMachine) SubscribeState(out chan<- types.FullState) error {
resCh := make(chan error)
sm.subscribeStateCh <- subscribeStateReq{out, resCh}
return <-resCh
diff --git a/cmd/dolmetschctld/telnet.go b/cmd/dolmetschctld/telnet.go
index a5a4555..5618ebe 100644
--- a/cmd/dolmetschctld/telnet.go
+++ b/cmd/dolmetschctld/telnet.go
@@ -26,6 +26,7 @@ import (
"strconv"
"github.com/spreadspace/telgo"
+ "spreadspace.org/dolmetschctl/pkg/types"
)
type TelnetInterface struct {
@@ -42,7 +43,7 @@ func telnetCmdLang(c *telgo.Client, args []string, sm *StateMachine) bool {
return false
}
- if err := sm.SetLanguage(Language(args[1])); err != nil {
+ if err := sm.SetLanguage(types.Language(args[1])); err != nil {
c.Sayln("selecting language failed: %v", err)
}
return false
diff --git a/cmd/dolmetschctld/web.go b/cmd/dolmetschctld/web.go
index 696169f..6ffcfea 100644
--- a/cmd/dolmetschctld/web.go
+++ b/cmd/dolmetschctld/web.go
@@ -26,6 +26,8 @@ import (
"encoding/json"
"net/http"
"time"
+
+ "spreadspace.org/dolmetschctl/pkg/types"
)
type WebInterface struct {
@@ -48,17 +50,8 @@ func webSendResponse(w http.ResponseWriter, status int, respdata interface{}) {
encoder.Encode(respdata)
}
-type webError struct {
- ResponseCode int `json:"response-code"`
- Error string `json:"error"`
-}
-
func webSendErrorResponse(w http.ResponseWriter, status int, error string) {
- webSendResponse(w, status, webError{ResponseCode: status, Error: error})
-}
-
-type webLanguage struct {
- Lang Language `json:"language"`
+ webSendResponse(w, status, types.WebError{ResponseCode: status, Error: error})
}
func webLanguageHandler(sm *StateMachine, w http.ResponseWriter, r *http.Request) {
@@ -67,7 +60,7 @@ func webLanguageHandler(sm *StateMachine, w http.ResponseWriter, r *http.Request
return
}
- var result webLanguage
+ var result types.WebLanguage
dec := json.NewDecoder(r.Body)
dec.DisallowUnknownFields()
if err := dec.Decode(&result); err != nil {
@@ -82,19 +75,13 @@ func webLanguageHandler(sm *StateMachine, w http.ResponseWriter, r *http.Request
webSendResponse(w, http.StatusOK, result)
}
-type webState struct {
- State State `json:"state"`
- Ratio float32 `json:"original-to-interpreter-ratio"`
- Lang Language `json:"language"`
-}
-
func webStateHandler(sm *StateMachine, w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
webSendErrorResponse(w, http.StatusMethodNotAllowed, "only GET method is allowed")
return
}
- var result webState
+ var result types.WebState
result.State, result.Ratio, result.Lang = sm.GetState()
webSendResponse(w, http.StatusOK, result)
}
diff --git a/cmd/dolmetschctld/web_socket.go b/cmd/dolmetschctld/web_socket.go
index f904a1c..09f2efc 100644
--- a/cmd/dolmetschctld/web_socket.go
+++ b/cmd/dolmetschctld/web_socket.go
@@ -30,33 +30,9 @@ import (
"net/http"
"github.com/gorilla/websocket"
+ "spreadspace.org/dolmetschctl/pkg/types"
)
-type webSocketRequest struct {
- Command string `json:"command"`
- Args []string `json:"arguments"`
-}
-
-type webSocketResponseBase struct {
- ResponseCode int `json:"response-code"`
- Type string `json:"type"`
-}
-
-type webSocketResponseError struct {
- webSocketResponseBase
- ErrorString string `json:"error"`
-}
-
-type webSocketResponseState struct {
- webSocketResponseBase
- webState
-}
-
-type webSocketResponseLanguages struct {
- webSocketResponseBase
- Languages []Language `json:"languages"`
-}
-
func sendWebSocketResponse(ws *websocket.Conn, rd interface{}) {
if err := ws.WriteJSON(rd); err != nil {
log.Println("Web(socket) client", ws.RemoteAddr(), "write error:", err)
@@ -64,14 +40,14 @@ func sendWebSocketResponse(ws *websocket.Conn, rd interface{}) {
}
func sendWebSocketErrorResponse(ws *websocket.Conn, code int, errStr string) {
- rd := &webSocketResponseError{}
+ rd := &types.WebSocketResponseError{}
rd.ResponseCode = code
rd.Type = "error"
rd.ErrorString = errStr
sendWebSocketResponse(ws, rd)
}
-func webSocketHandleRequest(ws *websocket.Conn, sm *StateMachine, req webSocketRequest, subCh chan<- FullState) {
+func webSocketHandleRequest(ws *websocket.Conn, sm *StateMachine, req types.WebSocketRequest, subCh chan<- types.FullState) {
switch req.Command {
case "state":
if len(req.Args) != 0 {
@@ -79,7 +55,7 @@ func webSocketHandleRequest(ws *websocket.Conn, sm *StateMachine, req webSocketR
return
}
- var result webSocketResponseState
+ var result types.WebSocketResponseState
result.ResponseCode = http.StatusOK
result.Type = "state"
result.State, result.Ratio, result.Lang = sm.GetState()
@@ -95,7 +71,7 @@ func webSocketHandleRequest(ws *websocket.Conn, sm *StateMachine, req webSocketR
return
}
- var result webSocketResponseState
+ var result types.WebSocketResponseState
result.ResponseCode = http.StatusOK
result.Type = "state"
result.State, result.Ratio, result.Lang = sm.GetState()
@@ -106,7 +82,7 @@ func webSocketHandleRequest(ws *websocket.Conn, sm *StateMachine, req webSocketR
return
}
- var result webSocketResponseLanguages
+ var result types.WebSocketResponseLanguages
result.ResponseCode = http.StatusOK
result.Type = "languages"
result.Languages = sm.GetLanguages()
@@ -117,12 +93,12 @@ func webSocketHandleRequest(ws *websocket.Conn, sm *StateMachine, req webSocketR
return
}
- if err := sm.SetLanguage(Language(req.Args[0])); err != nil {
+ if err := sm.SetLanguage(types.Language(req.Args[0])); err != nil {
sendWebSocketErrorResponse(ws, http.StatusBadRequest, err.Error())
return
}
- var result webSocketResponseState
+ var result types.WebSocketResponseState
result.ResponseCode = http.StatusOK
result.Type = "state"
result.State, result.Ratio, result.Lang = sm.GetState()
@@ -132,22 +108,22 @@ func webSocketHandleRequest(ws *websocket.Conn, sm *StateMachine, req webSocketR
}
}
-func webSocketSessionHandler(ws *websocket.Conn, sm *StateMachine, reqCh <-chan webSocketRequest) {
+func webSocketSessionHandler(ws *websocket.Conn, sm *StateMachine, reqCh <-chan types.WebSocketRequest) {
defer ws.Close()
- subCh := make(chan FullState, 100)
+ subCh := make(chan types.FullState, 100)
for {
select {
case state, ok := <-subCh:
if !ok {
return
}
- var result webSocketResponseState
+ var result types.WebSocketResponseState
result.ResponseCode = http.StatusOK
result.Type = "state"
- result.State = state.state
- result.Ratio = state.ratio
- result.Lang = state.language
+ result.State = state.State
+ result.Ratio = state.Ratio
+ result.Lang = state.Language
sendWebSocketResponse(ws, result)
case req, ok := <-reqCh:
if !ok {
@@ -168,20 +144,20 @@ func webSocketHandler(sm *StateMachine, w http.ResponseWriter, r *http.Request)
return
}
log.Println("Web(socket) client", ws.RemoteAddr(), "connected")
- reqCh := make(chan webSocketRequest)
+ reqCh := make(chan types.WebSocketRequest)
go webSocketSessionHandler(ws, sm, reqCh)
defer close(reqCh)
for {
t, r, err := ws.NextReader()
if err != nil {
- log.Println("Web(socket) Client", ws.RemoteAddr(), "disconnected:", err)
+ log.Println("Web(socket) client", ws.RemoteAddr(), "disconnected:", err)
return
}
switch t {
case websocket.TextMessage:
- var req webSocketRequest
+ var req types.WebSocketRequest
dec := json.NewDecoder(r)
dec.DisallowUnknownFields()
if err := dec.Decode(&req); err != nil {