2024-05-14 22:34:41 +02:00
|
|
|
// Copyright 2024, Command Line Inc.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
package eventbus
|
|
|
|
|
|
|
|
import (
|
2024-06-25 23:56:37 +02:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
2024-05-14 22:34:41 +02:00
|
|
|
"sync"
|
2024-06-25 23:56:37 +02:00
|
|
|
"time"
|
2024-05-14 22:34:41 +02:00
|
|
|
|
2024-09-05 23:25:45 +02:00
|
|
|
"github.com/wavetermdev/waveterm/pkg/waveobj"
|
2024-05-14 22:34:41 +02:00
|
|
|
)
|
|
|
|
|
2024-06-25 04:04:08 +02:00
|
|
|
const (
|
2024-09-12 03:03:55 +02:00
|
|
|
WSEvent_ElectronNewWindow = "electron:newwindow"
|
|
|
|
WSEvent_ElectronCloseWindow = "electron:closewindow"
|
|
|
|
WSEvent_Rpc = "rpc"
|
2024-06-25 04:04:08 +02:00
|
|
|
)
|
|
|
|
|
2024-06-12 02:42:10 +02:00
|
|
|
type WSEventType struct {
|
|
|
|
EventType string `json:"eventtype"`
|
|
|
|
ORef string `json:"oref,omitempty"`
|
|
|
|
Data any `json:"data"`
|
2024-05-14 22:34:41 +02:00
|
|
|
}
|
|
|
|
|
2024-05-28 00:44:57 +02:00
|
|
|
type WindowWatchData struct {
|
2024-06-12 02:42:10 +02:00
|
|
|
WindowWSCh chan any
|
|
|
|
WaveWindowId string
|
|
|
|
WatchedORefs map[waveobj.ORef]bool
|
2024-05-28 00:44:57 +02:00
|
|
|
}
|
|
|
|
|
2024-05-14 22:34:41 +02:00
|
|
|
var globalLock = &sync.Mutex{}
|
2024-06-12 02:42:10 +02:00
|
|
|
var wsMap = make(map[string]*WindowWatchData) // websocketid => WindowWatchData
|
2024-05-14 22:34:41 +02:00
|
|
|
|
2024-06-12 02:42:10 +02:00
|
|
|
func RegisterWSChannel(connId string, windowId string, ch chan any) {
|
2024-05-14 22:34:41 +02:00
|
|
|
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-05-28 00:44:57 +02:00
|
|
|
}
|
2024-05-14 22:34:41 +02:00
|
|
|
}
|
|
|
|
|
2024-06-12 02:42:10 +02:00
|
|
|
func UnregisterWSChannel(connId string) {
|
2024-05-14 22:34:41 +02:00
|
|
|
globalLock.Lock()
|
|
|
|
defer globalLock.Unlock()
|
2024-06-12 02:42:10 +02:00
|
|
|
delete(wsMap, connId)
|
2024-05-14 22:34:41 +02:00
|
|
|
}
|
|
|
|
|
2024-06-12 02:42:10 +02:00
|
|
|
func getWindowWatchesForWindowId(windowId string) []*WindowWatchData {
|
2024-05-28 00:44:57 +02:00
|
|
|
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-05-28 00:44:57 +02:00
|
|
|
}
|
|
|
|
}
|
2024-06-12 02:42:10 +02:00
|
|
|
return watches
|
2024-05-28 00:44:57 +02:00
|
|
|
}
|
|
|
|
|
2024-06-25 23:56:37 +02:00
|
|
|
// 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))
|
|
|
|
}
|