diff options
Diffstat (limited to 'cmd/dolmetschctld')
-rw-r--r-- | cmd/dolmetschctld/dolmetschctld.go | 8 | ||||
-rw-r--r-- | cmd/dolmetschctld/statemachine.go | 92 | ||||
-rw-r--r-- | cmd/dolmetschctld/telnet.go | 68 |
3 files changed, 153 insertions, 15 deletions
diff --git a/cmd/dolmetschctld/dolmetschctld.go b/cmd/dolmetschctld/dolmetschctld.go index 0f6793b..45536e8 100644 --- a/cmd/dolmetschctld/dolmetschctld.go +++ b/cmd/dolmetschctld/dolmetschctld.go @@ -60,11 +60,15 @@ func main() { defer sm.Shutdown() var telnet *TelnetInterface - if telnet, err = NewTelnetInterface(sm); err != nil { + if telnet, err = NewTelnetInterface("127.0.0.1:1234", sm); err != nil { log.Printf("creating telnet control interface failed: %v", err) os.Exit(1) } - telnet.Run() + log.Printf("telnet interface successfully initialized!") + + if err = telnet.Run(); err != nil { + log.Printf("running telnet interface failed: %v", err) + } log.Printf("exiting.") } diff --git a/cmd/dolmetschctld/statemachine.go b/cmd/dolmetschctld/statemachine.go index c388d24..2aba4bb 100644 --- a/cmd/dolmetschctld/statemachine.go +++ b/cmd/dolmetschctld/statemachine.go @@ -23,34 +23,92 @@ package main import ( - "time" + "errors" + "log" "spreadspace.org/dolmetschctl/pkg/mixer" ) +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" + } +} + type Language string +type LanguageChannels struct { + main mixer.Channel + voice mixer.Channel +} + +type selectLangRequest struct { + l Language + resultCh chan error +} + type StateMachine struct { mixer *mixer.Mixer - selectLangCh chan Language + selectLangCh chan selectLangRequest quitCh chan bool exitedCh chan struct{} + + languages map[Language]LanguageChannels + + currentState State + currentLang Language + targetLang Language } func NewStateMachine(m *mixer.Mixer) (*StateMachine, error) { sm := &StateMachine{mixer: m} - sm.selectLangCh = make(chan Language, 10) + sm.selectLangCh = make(chan selectLangRequest, 10) sm.quitCh = make(chan bool, 1) sm.exitedCh = make(chan struct{}) + + sm.languages = make(map[Language]LanguageChannels) + sm.languages["en"] = LanguageChannels{0x20, 0x24} + sm.languages["de"] = LanguageChannels{0x22, 0x25} + + sm.currentState = StateNew + sm.currentLang = "" + sm.targetLang = "" + return sm, nil } -func (sm *StateMachine) selectLang(l Language) { - sm.mixer.UnMute(0x24) - sm.mixer.SetLevel(0x24, 42) - time.Sleep(2 * time.Second) - sm.mixer.Mute(0x24) - sm.mixer.SetLevel(0x24, mixer.FaderLevel0db) +func (sm *StateMachine) selectLang(l Language) error { + if l != "" { + if _, exists := sm.languages[l]; !exists { + return errors.New("language '" + string(l) + "' does not exist") + } + } + sm.targetLang = l + log.Printf("new target language: '%s'", sm.targetLang) + return nil +} + +func (sm *StateMachine) reconcile() { + if sm.targetLang == sm.currentLang { + sm.currentState = StateSettled + return + } + sm.currentState = StateSettling } func (sm *StateMachine) run() { @@ -58,11 +116,17 @@ func (sm *StateMachine) run() { for { select { - case l := <-sm.selectLangCh: - sm.selectLang(l) + case req := <-sm.selectLangCh: + req.resultCh <- sm.selectLang(req.l) case <-sm.quitCh: return } + + oldState := sm.currentState + sm.reconcile() + if oldState != sm.currentState { + log.Printf("new state: %s", sm.currentState) + } } } @@ -70,8 +134,10 @@ func (sm *StateMachine) Start() { go sm.run() } -func (sm *StateMachine) SelectLanguage(l Language) { - sm.selectLangCh <- l +func (sm *StateMachine) SelectLanguage(l Language) error { + resultCh := make(chan error) + sm.selectLangCh <- selectLangRequest{l, resultCh} + return <-resultCh } func (sm *StateMachine) Shutdown() { diff --git a/cmd/dolmetschctld/telnet.go b/cmd/dolmetschctld/telnet.go new file mode 100644 index 0000000..d2f7fc3 --- /dev/null +++ b/cmd/dolmetschctld/telnet.go @@ -0,0 +1,68 @@ +// +// dolmetschctl +// +// +// Copyright (C) 2019 Christian Pointner <equinox@spreadspace.org> +// +// This file is part of dolmetschctl. +// +// dolmetschctl is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// dolmetschctl is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with dolmetschctl. If not, see <http://www.gnu.org/licenses/>. +// + +package main + +import ( + "fmt" + + "github.com/spreadspace/telgo" +) + +type TelnetInterface struct { + server *telgo.Server +} + +func telnetCmdLang(c *telgo.Client, args []string, sm *StateMachine) bool { + if len(args) != 2 { + c.Sayln("usage: lang <language>") + return false + } + lang := args[1] + if lang == "none" { + lang = "" + } + if err := sm.SelectLanguage(Language(lang)); err != nil { + c.Sayln(fmt.Sprintf("selecting language failed: %v", err)) + } + return false +} + +func telnetQuit(c *telgo.Client, args []string) bool { + return true +} + +func (telnet *TelnetInterface) Run() error { + return telnet.server.Run() +} + +func NewTelnetInterface(addr string, sm *StateMachine) (telnet *TelnetInterface, err error) { + telnet = &TelnetInterface{} + + cmdlist := make(telgo.CmdList) + cmdlist["lang"] = func(c *telgo.Client, args []string) bool { return telnetCmdLang(c, args, sm) } + cmdlist["quit"] = telnetQuit + + telnet.server, err = telgo.NewServer(addr, "dolmetschctl> ", cmdlist, nil) + + return +} |