mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
144 lines
3.4 KiB
Go
144 lines
3.4 KiB
Go
// Copyright 2024, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package eventbus
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/wavetermdev/waveterm/pkg/waveobj"
|
|
)
|
|
|
|
const (
|
|
WSEvent_WaveObjUpdate = "waveobj:update"
|
|
WSEvent_BlockFile = "blockfile"
|
|
WSEvent_Config = "config"
|
|
WSEvent_UserInput = "userinput"
|
|
WSEvent_BlockControllerStatus = "blockcontroller:status"
|
|
WSEvent_LayoutAction = "layoutaction"
|
|
WSEvent_ElectronNewWindow = "electron:newwindow"
|
|
WSEvent_ElectronCloseWindow = "electron:closewindow"
|
|
WSEvent_Rpc = "rpc"
|
|
)
|
|
|
|
type WSEventType struct {
|
|
EventType string `json:"eventtype"`
|
|
ORef string `json:"oref,omitempty"`
|
|
Data any `json:"data"`
|
|
}
|
|
|
|
const (
|
|
FileOp_Append = "append"
|
|
FileOp_Truncate = "truncate"
|
|
FileOp_Invalidate = "invalidate"
|
|
)
|
|
|
|
type WSFileEventData struct {
|
|
ZoneId string `json:"zoneid"`
|
|
FileName string `json:"filename"`
|
|
FileOp string `json:"fileop"`
|
|
Data64 string `json:"data64"`
|
|
}
|
|
|
|
type WindowWatchData struct {
|
|
WindowWSCh chan any
|
|
WaveWindowId string
|
|
WatchedORefs map[waveobj.ORef]bool
|
|
}
|
|
|
|
var globalLock = &sync.Mutex{}
|
|
var wsMap = make(map[string]*WindowWatchData) // websocketid => WindowWatchData
|
|
|
|
func RegisterWSChannel(connId string, windowId string, ch chan any) {
|
|
globalLock.Lock()
|
|
defer globalLock.Unlock()
|
|
wsMap[connId] = &WindowWatchData{
|
|
WindowWSCh: ch,
|
|
WaveWindowId: windowId,
|
|
WatchedORefs: make(map[waveobj.ORef]bool),
|
|
}
|
|
}
|
|
|
|
func UnregisterWSChannel(connId string) {
|
|
globalLock.Lock()
|
|
defer globalLock.Unlock()
|
|
delete(wsMap, connId)
|
|
}
|
|
|
|
func getWindowWatchesForWindowId(windowId string) []*WindowWatchData {
|
|
globalLock.Lock()
|
|
defer globalLock.Unlock()
|
|
var watches []*WindowWatchData
|
|
for _, wdata := range wsMap {
|
|
if wdata.WaveWindowId == windowId {
|
|
watches = append(watches, wdata)
|
|
}
|
|
}
|
|
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 getAllWatches() []*WindowWatchData {
|
|
globalLock.Lock()
|
|
defer globalLock.Unlock()
|
|
watches := make([]*WindowWatchData, 0, len(wsMap))
|
|
for _, wdata := range wsMap {
|
|
watches = append(watches, wdata)
|
|
}
|
|
return watches
|
|
}
|
|
|
|
func SendEventToWindow(windowId string, event WSEventType) {
|
|
wwdArr := getWindowWatchesForWindowId(windowId)
|
|
for _, wdata := range wwdArr {
|
|
wdata.WindowWSCh <- event
|
|
}
|
|
}
|
|
|
|
func SendEvent(event WSEventType) {
|
|
wwdArr := getAllWatches()
|
|
for _, wdata := range wwdArr {
|
|
wdata.WindowWSCh <- event
|
|
}
|
|
}
|
|
|
|
func SendUpdateEvents(updates waveobj.UpdatesRtnType) {
|
|
for _, update := range updates {
|
|
SendEvent(WSEventType{
|
|
EventType: WSEvent_WaveObjUpdate,
|
|
ORef: waveobj.MakeORef(update.OType, update.OID).String(),
|
|
Data: update,
|
|
})
|
|
}
|
|
}
|
|
|
|
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))
|
|
}
|