Vaguely works.
This commit is contained in:
114
streamdeck/client.go
Normal file
114
streamdeck/client.go
Normal file
@ -0,0 +1,114 @@
|
||||
package streamdeck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
type EventHandler func(ctx context.Context, client *Client, event EventReceived) error
|
||||
|
||||
type Client struct {
|
||||
c *websocket.Conn
|
||||
handlers map[string][]EventHandler
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, params RegistrationParams) (*Client, error) {
|
||||
interrupt := make(chan os.Signal, 1)
|
||||
signal.Notify(interrupt, os.Interrupt)
|
||||
|
||||
u := url.URL{Scheme: "ws", Host: fmt.Sprintf("127.0.0.1:%d", params.Port)}
|
||||
log.Printf("connecting to StreamDeck at %v\n", u)
|
||||
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("connected to StreamDeck\n")
|
||||
|
||||
done := make(chan struct{})
|
||||
|
||||
client := &Client{
|
||||
c: c,
|
||||
handlers: make(map[string][]EventHandler),
|
||||
done: done,
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer close(done)
|
||||
log.Println("starting read loop")
|
||||
for {
|
||||
_, message, err := client.c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
event := EventReceived{}
|
||||
if err := json.Unmarshal(message, &event); err != nil {
|
||||
log.Printf("failed to unmarshal received event: %s\n", string(message))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := setContext(ctx, event.Context)
|
||||
for _, f := range client.handlers[event.Event] {
|
||||
f(ctx, client, event)
|
||||
}
|
||||
|
||||
log.Println("recv: ", string(message))
|
||||
}
|
||||
}()
|
||||
|
||||
if err := client.register(params); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (client *Client) register(params RegistrationParams) error {
|
||||
log.Println("sending register event...")
|
||||
if err := client.c.WriteJSON(NewRegisterEvent(params)); err != nil {
|
||||
client.Close()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *Client) SetSettings(ctx context.Context, settings interface{}) error {
|
||||
return client.c.WriteJSON(NewEvent(ctx, SetSettings, settings))
|
||||
}
|
||||
|
||||
func (client *Client) GetSettings(ctx context.Context) error {
|
||||
return client.c.WriteJSON(NewEvent(ctx, GetSettings, nil))
|
||||
}
|
||||
|
||||
func (client *Client) Log(message string) error {
|
||||
return client.c.WriteJSON(NewLogMessage(message))
|
||||
}
|
||||
|
||||
func (client *Client) RegisterHandler(eventName string, handler EventHandler) {
|
||||
client.handlers[eventName] = append(client.handlers[eventName], handler)
|
||||
}
|
||||
|
||||
func (client *Client) Close() error {
|
||||
err := client.c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
select {
|
||||
case <-client.done:
|
||||
case <-time.After(time.Second):
|
||||
}
|
||||
return client.c.Close()
|
||||
}
|
||||
|
||||
func (client *Client) Join() {
|
||||
<-client.done
|
||||
}
|
53
streamdeck/constants.go
Normal file
53
streamdeck/constants.go
Normal file
@ -0,0 +1,53 @@
|
||||
package streamdeck
|
||||
|
||||
import "context"
|
||||
|
||||
const (
|
||||
DidReceiveSettings = "didReceiveSettings"
|
||||
DidReceiveGlobalSettings = "didReceiveGlobalSettings"
|
||||
KeyDown = "keyDown"
|
||||
KeyUp = "keyUp"
|
||||
WillAppear = "willAppear"
|
||||
WillDisappear = "willDisappear"
|
||||
TitleParametersDidChange = "titleParametersDidChange"
|
||||
DeviceDidConnect = "deviceDidConnect"
|
||||
DeviceDidDisconnect = "deviceDidDisconnect"
|
||||
ApplicationDidLaunch = "applicationDidLaunch"
|
||||
ApplicationDidTerminate = "applicationDidTerminate"
|
||||
SystemDidWakeUp = "systemDidWakeUp"
|
||||
PropertyInspectorDidAppear = "propertyInspectorDidAppear"
|
||||
PropertyInspectorDidDisappear = "propertyInspectorDidDisappear"
|
||||
SendToPlugin = "sendToPlugin"
|
||||
SendToPropertyInspector = "sendToPropertyInspector"
|
||||
|
||||
SetSettings = "setSettings"
|
||||
GetSettings = "getSettings"
|
||||
SetGlobalSettings = "setGlobalSettings"
|
||||
GetGlobalSettings = "getGlobalSettings"
|
||||
OpenURL = "openUrl"
|
||||
LogMessage = "logMessage"
|
||||
SetTitle = "setTitle"
|
||||
SetImage = "setImage"
|
||||
ShowAlert = "showAlert"
|
||||
ShowOk = "showOk"
|
||||
SetState = "setState"
|
||||
SwitchToProfile = "switchToProfile"
|
||||
)
|
||||
|
||||
type contextKeyType int
|
||||
|
||||
const (
|
||||
contextKey contextKeyType = iota
|
||||
)
|
||||
|
||||
func getContext(ctx context.Context) string {
|
||||
if ctx == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return ctx.Value(contextKey).(string)
|
||||
}
|
||||
|
||||
func setContext(ctx context.Context, streamdeckContext string) context.Context {
|
||||
return context.WithValue(ctx, contextKey, streamdeckContext)
|
||||
}
|
47
streamdeck/messages.go
Normal file
47
streamdeck/messages.go
Normal file
@ -0,0 +1,47 @@
|
||||
package streamdeck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type LogMessagePayload struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func NewLogMessage(message string) Event {
|
||||
return NewEvent(nil, LogMessage, LogMessagePayload{Message: message})
|
||||
}
|
||||
|
||||
type RegisterEvent struct {
|
||||
Event string `json:"event"`
|
||||
UUID string `json:"uuid"`
|
||||
}
|
||||
|
||||
func NewRegisterEvent(params RegistrationParams) RegisterEvent {
|
||||
return RegisterEvent{
|
||||
Event: params.RegisterEvent,
|
||||
UUID: params.PluginUUID,
|
||||
}
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
Action string `json:"action,omitempty"`
|
||||
Event string `json:"event,omitempty"`
|
||||
Context string `json:"context,omitempty"`
|
||||
Device string `json:"device,omitempty"`
|
||||
Payload string `json:"payload,omitempty"`
|
||||
}
|
||||
|
||||
func NewEvent(ctx context.Context, name string, payload interface{}) Event {
|
||||
payloadStr, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return Event{
|
||||
Event: name,
|
||||
Context: getContext(ctx),
|
||||
Payload: string(payloadStr),
|
||||
}
|
||||
}
|
8
streamdeck/registration.go
Normal file
8
streamdeck/registration.go
Normal file
@ -0,0 +1,8 @@
|
||||
package streamdeck
|
||||
|
||||
type RegistrationParams struct {
|
||||
Port int
|
||||
PluginUUID string
|
||||
RegisterEvent string
|
||||
Info string
|
||||
}
|
Reference in New Issue
Block a user