waveterm/pkg/eventbus/eventbus.go

91 lines
2.1 KiB
Go
Raw Normal View History

// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package eventbus
import (
"encoding/json"
"fmt"
"log"
"os"
"sync"
"time"
2024-09-05 23:25:45 +02:00
"github.com/wavetermdev/waveterm/pkg/waveobj"
)
const (
WSEvent_ElectronNewWindow = "electron:newwindow"
WSEvent_ElectronCloseWindow = "electron:closewindow"
WSEvent_Rpc = "rpc"
)
2024-06-12 02:42:10 +02:00
type WSEventType struct {
EventType string `json:"eventtype"`
ORef string `json:"oref,omitempty"`
Data any `json:"data"`
}
type WindowWatchData struct {
2024-06-12 02:42:10 +02:00
WindowWSCh chan any
WaveWindowId string
WatchedORefs map[waveobj.ORef]bool
}
var globalLock = &sync.Mutex{}
2024-06-12 02:42:10 +02:00
var wsMap = make(map[string]*WindowWatchData) // websocketid => WindowWatchData
2024-06-12 02:42:10 +02:00
func RegisterWSChannel(connId string, windowId string, ch chan any) {
globalLock.Lock()
defer globalLock.Unlock()
2024-06-12 02:42:10 +02:00
wsMap[connId] = &WindowWatchData{
WindowWSCh: ch,
WaveWindowId: windowId,
WatchedORefs: make(map[waveobj.ORef]bool),
}
}
2024-06-12 02:42:10 +02:00
func UnregisterWSChannel(connId string) {
globalLock.Lock()
defer globalLock.Unlock()
2024-06-12 02:42:10 +02:00
delete(wsMap, connId)
}
2024-06-12 02:42:10 +02:00
func getWindowWatchesForWindowId(windowId string) []*WindowWatchData {
globalLock.Lock()
defer globalLock.Unlock()
2024-06-12 02:42:10 +02:00
var watches []*WindowWatchData
for _, wdata := range wsMap {
if wdata.WaveWindowId == windowId {
watches = append(watches, wdata)
}
}
2024-06-12 02:42:10 +02:00
return watches
}
// TODO fix busy wait -- but we need to wait until a new window connects back with a websocket
// returns true if the window is connected
func BusyWaitForWindowId(windowId string, timeout time.Duration) bool {
endTime := time.Now().Add(timeout)
for {
if len(getWindowWatchesForWindowId(windowId)) > 0 {
return true
}
if time.Now().After(endTime) {
return false
}
time.Sleep(20 * time.Millisecond)
}
}
func SendEventToElectron(event WSEventType) {
barr, err := json.Marshal(event)
if err != nil {
log.Printf("cannot marshal electron message: %v\n", err)
return
}
// send to electron
log.Printf("sending event to electron: %q\n", event.EventType)
fmt.Fprintf(os.Stderr, "\nWAVESRV-EVENT:%s\n", string(barr))
}