Yeah, I kinda gave up, i will fix it later or something I recon

This commit is contained in:
2026-02-09 23:23:45 +00:00
parent 2952ec7085
commit 97caeafd58
16 changed files with 464 additions and 103 deletions
+76
View File
@@ -0,0 +1,76 @@
package cdashdisplay
import (
"esdi/peripheral/communication"
"esdi/peripheral/communication/packets"
"fmt"
"path/filepath"
"time"
"github.com/tarm/serial"
)
func listPorts() ([]string, error) {
ttyUSBs, err := filepath.Glob("/dev/ttyUSB*")
if err != nil {
return []string{}, err
}
return ttyUSBs, nil
}
func probe(WT *communication.WalkieTalkie) error {
err := WT.TurnOn()
if err != nil {
return err
}
// Send the identification command
cmd := communication.CmdRequestID
var response packets.IdentificationPacket
err = WT.SendCommand(cmd, []byte{0x06, 0x07, 0x08, 0x09}, &response)
if err != nil {
return err
}
if response.DeviceID != 0x01 {
return fmt.Errorf("wrong ID")
}
return nil
}
func findDisplayPort() (*communication.WalkieTalkie, error) {
ports, err := listPorts()
if err != nil {
return nil, err
}
pLogger.Info(fmt.Sprintf("Looking into %v", ports))
var wt *communication.WalkieTalkie
for _, port := range ports {
wt = &communication.WalkieTalkie{
Cfg: &serial.Config{
Name: port,
Baud: 115200,
ReadTimeout: 500 * time.Millisecond,
},
}
err = probe(wt)
if err == nil {
break
}
pLogger.Info(fmt.Sprintf("wasn't port %s", port))
wt = nil
}
if wt == nil {
return nil, fmt.Errorf("couldn't find cdashdisplay")
}
pLogger.Info(fmt.Sprintf("found cdashdisplay on port: %s", wt.Cfg.Name))
return wt, nil
}
+150
View File
@@ -0,0 +1,150 @@
// Package cdashdisplay will handle the USB connections
package cdashdisplay
import (
helper "esdi/helpers"
"esdi/peripheral/communication"
"esdi/peripheral/communication/packets"
"esdi/peripheral/types"
"fmt"
"log/slog"
)
var pLogger *slog.Logger
func SetLogger(l *slog.Logger) {
pLogger = l
}
const (
newWindowCMDID types.Command = 3
destroyWindowCMDID types.Command = 4
moveWindowCMDID types.Command = 5
newLayoutCMDID types.Command = 6
)
var (
DefaultDecorations = UIDecorations{
HasBorder: 1,
BGColour: 0x1041, // Look in the eslabsCurses library for these colours
FGColour: 0xffff,
TitleColour: 0xffff,
BorderColour: 0xf800,
TitleSize: 2,
TextSize: 4,
Padding: 0x00,
}
)
type UIDimensions struct {
X0 uint16
Y0 uint16
Width uint16
Height uint16
}
type UIDecorations struct {
BGColour uint16
FGColour uint16
TitleColour uint16
BorderColour uint16
TitleSize uint8
TextSize uint8
HasBorder uint8
Padding uint8
}
type UIWindow struct {
Dims UIDimensions
Decor UIDecorations
Title [32]byte
}
type LayoutTree struct {
Windows map[int16]UIWindow
}
func NewLayoutTree() *LayoutTree {
return &LayoutTree{
Windows: make(map[int16]UIWindow),
}
}
func (l *LayoutTree) AddWindow(idx int16, w UIWindow) {
l.Windows[idx] = w
}
type CDashState struct {
Layout *LayoutTree
}
func NewCDashState() *CDashState {
return &CDashState{
Layout: NewLayoutTree(),
}
}
type CDashDisplay struct {
WT *communication.WalkieTalkie
State *CDashState
}
func NewCDashDisplay() (*CDashDisplay, error) {
// Look for the port
p, err := findDisplayPort()
if err != nil {
pLogger.Info("failed to find cdashdisplay port: %s", err.Error())
return nil, err
}
return &CDashDisplay{
WT: p,
State: NewCDashState(),
}, nil
}
func (d *CDashDisplay) CreateWindow(win UIWindow) (int16, error) {
bytes, err := helper.StructToBytes(win)
if err != nil {
return -1, err
}
// Send the command
var wID packets.NewWindowID
err = d.WT.SendCommand(newWindowCMDID, bytes, &wID)
if err != nil {
return -1, err
}
pLogger.Info(fmt.Sprintf("Recived ID message: %v", wID))
d.State.Layout.AddWindow(wID.ID, win)
return wID.ID, nil
}
func (d *CDashDisplay) DestroyWindow(wID int16) error {
type UIWindowDestructPacket struct {
WinID int16
}
packet := UIWindowDestructPacket{
WinID: wID,
}
bytes, err := helper.StructToBytes(packet)
if err != nil {
return err
}
var ack packets.AckPacket
err = d.WT.SendCommand(destroyWindowCMDID, bytes, &ack)
if err != nil {
return err
}
// NODE: add this
// d.State.Layout.RemoveWindow(wID)
return nil
}
+8 -1
View File
@@ -2,6 +2,8 @@
package cmd package cmd
import ( import (
"context"
"log/slog"
"os" "os"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -14,9 +16,14 @@ var rootCmd = &cobra.Command{
Long: `Allows the configuration and communication with the dashDisplay`, Long: `Allows the configuration and communication with the dashDisplay`,
} }
type loggerKey struct{}
// Execute adds all child commands to the root command and sets flags appropriately. // Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd. // This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() { func Execute(log *slog.Logger) {
ctx := context.WithValue(context.Background(), loggerKey{}, log)
rootCmd.SetContext(ctx)
err := rootCmd.Execute() err := rootCmd.Execute()
if err != nil { if err != nil {
os.Exit(1) os.Exit(1)
+9 -1
View File
@@ -3,14 +3,22 @@ package cmd
import ( import (
"esdi/tui" "esdi/tui"
"fmt" "fmt"
"log/slog"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func tuiCmdAction(cmd *cobra.Command, args []string) { func tuiCmdAction(cmd *cobra.Command, args []string) {
err := tui.Run() logger, ok := cmd.Context().Value(loggerKey{}).(*slog.Logger)
if !ok {
fmt.Printf("Error loading logger from context: %s\n", logger)
return
}
err := tui.Run(logger)
if err != nil { if err != nil {
fmt.Printf("Error running TUI: %s\n", err.Error()) fmt.Printf("Error running TUI: %s\n", err.Error())
return
} }
} }
-14
View File
@@ -6,7 +6,6 @@ require (
github.com/ESilva15/ESgoRepl v0.1.0 github.com/ESilva15/ESgoRepl v0.1.0
github.com/ESilva15/gobngsdk v0.0.2 github.com/ESilva15/gobngsdk v0.0.2
github.com/ESilva15/goirsdk v0.2.0 github.com/ESilva15/goirsdk v0.2.0
github.com/charmbracelet/bubbletea v1.3.10
github.com/gdamore/tcell/v2 v2.8.1 github.com/gdamore/tcell/v2 v2.8.1
github.com/rivo/tview v0.42.0 github.com/rivo/tview v0.42.0
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.1
@@ -15,25 +14,12 @@ require (
) )
require ( require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/lipgloss v1.1.0 // indirect
github.com/charmbracelet/x/ansi v0.10.1 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/gdamore/encoding v1.0.1 // indirect github.com/gdamore/encoding v1.0.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/sys v0.39.0 // indirect golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.21.0 // indirect golang.org/x/text v0.21.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
-32
View File
@@ -4,23 +4,7 @@ github.com/ESilva15/gobngsdk v0.0.2 h1:N6stNOE14Wg80BAZMFu/Qd9Qa/J0DmExCfdPoDf7l
github.com/ESilva15/gobngsdk v0.0.2/go.mod h1:cKLaZRgM0tGGXDvosaSjHnxeyC5Y6rg7zCLqEUJnOzw= github.com/ESilva15/gobngsdk v0.0.2/go.mod h1:cKLaZRgM0tGGXDvosaSjHnxeyC5Y6rg7zCLqEUJnOzw=
github.com/ESilva15/goirsdk v0.2.0 h1:zmtYyH3ayGRcDfzzLrJmEpX6zdmCHTUqbs4tnV2hXmI= github.com/ESilva15/goirsdk v0.2.0 h1:zmtYyH3ayGRcDfzzLrJmEpX6zdmCHTUqbs4tnV2hXmI=
github.com/ESilva15/goirsdk v0.2.0/go.mod h1:5borQbw+L4fe9b58JFHRHZwrzz0sMVAteuYbRnFOc0Q= github.com/ESilva15/goirsdk v0.2.0/go.mod h1:5borQbw+L4fe9b58JFHRHZwrzz0sMVAteuYbRnFOc0Q=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
github.com/gdamore/tcell/v2 v2.8.1 h1:KPNxyqclpWpWQlPLx6Xui1pMk8S+7+R37h3g07997NU= github.com/gdamore/tcell/v2 v2.8.1 h1:KPNxyqclpWpWQlPLx6Xui1pMk8S+7+R37h3g07997NU=
@@ -31,18 +15,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/rivo/tview v0.42.0 h1:b/ftp+RxtDsHSaynXTbJb+/n/BxDEi+W3UfF5jILK6c= github.com/rivo/tview v0.42.0 h1:b/ftp+RxtDsHSaynXTbJb+/n/BxDEi+W3UfF5jILK6c=
github.com/rivo/tview v0.42.0/go.mod h1:cSfIYfhpSGCjp3r/ECJb+GKS7cGJnqV8vfjQPwoXyfY= github.com/rivo/tview v0.42.0/go.mod h1:cSfIYfhpSGCjp3r/ECJb+GKS7cGJnqV8vfjQPwoXyfY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -56,16 +30,12 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
@@ -89,11 +59,9 @@ golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+17 -2
View File
@@ -1,8 +1,23 @@
package main package main
import "esdi/cmd" import (
"esdi/cmd"
"log/slog"
"os"
)
func main() { func main() {
output, err := os.OpenFile("./output.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
panic("failed to open logging file: " + err.Error())
}
logger := slog.New(
slog.NewTextHandler(output, &slog.HandlerOptions{
Level: slog.LevelDebug,
}),
)
// Launches the cobra package stuff // Launches the cobra package stuff
cmd.Execute() cmd.Execute(logger)
} }
@@ -0,0 +1,20 @@
package packets
import (
"esdi/peripheral/communication/constvar"
)
type NewWindowID struct {
StartMarker byte
ID int16
EndMarker byte
}
func (pkt *NewWindowID) Validate() bool {
if pkt.StartMarker != constvar.StartOfText ||
pkt.EndMarker != constvar.EndOfText {
return false
}
return true
}
+40 -2
View File
@@ -16,10 +16,11 @@ const (
newWindowCMDID types.Command = 3 newWindowCMDID types.Command = 3
destroyWindowCMDID types.Command = 4 destroyWindowCMDID types.Command = 4
moveWindowCMDID types.Command = 5 moveWindowCMDID types.Command = 5
newLayoutCMDID types.Command = 6
) )
var ( var (
defaultDecorations = UIDecorations{ DefaultDecorations = UIDecorations{
HasBorder: 1, HasBorder: 1,
BGColour: 0x1041, // Look in the eslabsCurses library for these colours BGColour: 0x1041, // Look in the eslabsCurses library for these colours
FGColour: 0xffff, FGColour: 0xffff,
@@ -55,6 +56,29 @@ type UIWindow struct {
Title [32]byte Title [32]byte
} }
type LayoutTree struct {
Windows map[int]UIWindow
}
func (l *LayoutTree) AddWindow(idx int, w UIWindow) {
l.Windows[idx] = w
}
func NewLayoutTree() *LayoutTree {
return &LayoutTree{
Windows: make(map[int]UIWindow),
}
}
type CDashState struct {
Layout *LayoutTree
}
// Well fuck it really, this will make do for now really lmao
var (
state *CDashState
)
var CDashDisplay = Device{ var CDashDisplay = Device{
ID: CDashDisplayDevID, ID: CDashDisplayDevID,
Name: helper.B32("ESLabs CDashDisplay"), Name: helper.B32("ESLabs CDashDisplay"),
@@ -80,6 +104,13 @@ var CDashDisplay = Device{
ArgCheck: moveWindowArgCheck, ArgCheck: moveWindowArgCheck,
Fn: moveWindow, Fn: moveWindow,
}, },
"new-layout": {
Identifier: newLayoutCMDID,
Name: "new-layout",
Desc: "creates a new layout",
ArgCheck: nil,
Fn: nil,
},
}, },
} }
@@ -121,7 +152,7 @@ func createWindow(dCMD *DeviceCMD, args []string) (types.Command, []byte, error)
Width: uint16(width), Width: uint16(width),
Height: uint16(height), Height: uint16(height),
}, },
Decor: defaultDecorations, Decor: DefaultDecorations,
Title: helper.B32(args[4]), Title: helper.B32(args[4]),
} }
@@ -130,6 +161,13 @@ func createWindow(dCMD *DeviceCMD, args []string) (types.Command, []byte, error)
return 0, []byte{}, err return 0, []byte{}, err
} }
// All went well so far so we can update the state
if state == nil {
state = &CDashState{Layout: NewLayoutTree()}
}
state.Layout.AddWindow(0, data)
return dCMD.GetIdentifier(), bytes, nil return dCMD.GetIdentifier(), bytes, nil
} }
+10 -5
View File
@@ -18,9 +18,10 @@ var DeviceMap = map[int]Device{
} }
type Device struct { type Device struct {
ID uint8 ID uint8
Name [32]byte Name [32]byte
API map[string]DeviceCMD API map[string]DeviceCMD
State any
} }
func (dev *Device) HasFunction(f string) *DeviceCMD { func (dev *Device) HasFunction(f string) *DeviceCMD {
@@ -52,8 +53,6 @@ type DeviceCMD struct {
Identifier types.Command Identifier types.Command
Name string Name string
Desc string Desc string
Header DeviceCMDHeader
Data DeviceCMDPayload
ArgCheck ArgCheckFn ArgCheck ArgCheckFn
Fn DeviceCMDFn Fn DeviceCMDFn
} }
@@ -80,3 +79,9 @@ func (dCMD *DeviceCMD) GetName() string {
func (dCMD *DeviceCMD) GetDesc() string { func (dCMD *DeviceCMD) GetDesc() string {
return dCMD.Desc return dCMD.Desc
} }
type DeviceInstance[T any] struct {
Def *Device
ID uint8
State T
}
+11 -20
View File
@@ -2,11 +2,7 @@
package controllers package controllers
import ( import (
"fmt"
"esdi/tui/internal/events" "esdi/tui/internal/events"
"esdi/tui/internal/models"
"esdi/tui/internal/ui"
) )
type LayoutController struct { type LayoutController struct {
@@ -18,22 +14,17 @@ func NewLayoutController(bus *events.Bus) *LayoutController {
EvBus: bus, EvBus: bus,
} }
bus.On(ui.CreateWindowEv{}, func(e any) {
ev := e.(ui.CreateWindowEv)
lc.createWindow(ev.Window)
})
return lc return lc
} }
func (lc *LayoutController) createWindow(win models.Window) { // func (lc *LayoutController) createWindow(win models.Window) {
lc.EvBus.Emit(ui.LogEv{ // lc.EvBus.Emit(ui.LogEv{
Log: fmt.Sprintf("x : %d\n"+ // Log: fmt.Sprintf("x : %d\n"+
"y : %d\n"+ // "y : %d\n"+
"width : %d\n"+ // "width : %d\n"+
"height: %d\n"+ // "height: %d\n"+
"title : %s\n", win.X, win.Y, win.Width, win.Height, win.Title), // "title : %s\n", win.X, win.Y, win.Width, win.Height, win.Title),
}) // })
//
lc.EvBus.Emit(ui.WindowCreatedEv{Window: win}) // lc.EvBus.Emit(ui.WindowCreatedEv{})
} // }
+57 -15
View File
@@ -2,11 +2,14 @@
package controllers package controllers
import ( import (
"esdi/cdashdisplay"
helper "esdi/helpers"
"esdi/peripheral" "esdi/peripheral"
"esdi/tui/internal/dom" "esdi/tui/internal/dom"
"esdi/tui/internal/events" "esdi/tui/internal/events"
"esdi/tui/internal/ui" "esdi/tui/internal/ui"
"fmt" "fmt"
"log/slog"
"github.com/rivo/tview" "github.com/rivo/tview"
) )
@@ -17,46 +20,85 @@ type Ctrls struct {
} }
type MainController struct { type MainController struct {
Logger *slog.Logger
App *tview.Application App *tview.Application
Dom *dom.DOM Dom *dom.DOM
EvBus *events.Bus EvBus *events.Bus
DevClerk *peripheral.PeripheralDeviceClerk DevClerk *peripheral.PeripheralDeviceClerk
CDash *cdashdisplay.CDashDisplay
} }
func NewMainController() *MainController { func NewMainController(logger *slog.Logger) *MainController {
mc := &MainController{ mc := &MainController{
Logger: logger,
App: tview.NewApplication(), App: tview.NewApplication(),
Dom: dom.NewDOM(), Dom: dom.NewDOM(),
EvBus: events.NewBus(), EvBus: events.NewBus(),
DevClerk: peripheral.NewPeripheralDeviceClerk(), DevClerk: peripheral.NewPeripheralDeviceClerk(),
CDash: nil,
} }
mc.EvBus.On(ui.RedrawEv{}, func(e any) { mc.EvBus.On(ui.RedrawEv{}, func(e any) {
mc.App.QueueUpdateDraw(func() {}) go func() {
mc.App.QueueUpdateDraw(func() {})
}()
}) })
mc.EvBus.On(ui.ChangeFocusEv{}, func(e any) { mc.EvBus.On(ui.ChangeFocusEv{}, func(e any) {
mc.App.SetFocus(e.(ui.ChangeFocusEv).Target) go func() {
mc.App.SetFocus(e.(ui.ChangeFocusEv).Target)
}()
}) })
mc.EvBus.On(ui.LogEv{}, func(e any) { mc.EvBus.On(ui.LogEv{}, func(e any) {
mc.EvBus.Emit(ui.PrintLogEv{Log: e.(ui.LogEv).Log}) go func() {
mc.EvBus.Emit(ui.PrintLogEv{Log: e.(ui.LogEv).Log})
}()
})
mc.EvBus.On(ui.CreateWindowEv{}, func(e any) {
go func() {
win := e.(ui.CreateWindowEv).Window
uiWindow := cdashdisplay.UIWindow{
Dims: cdashdisplay.UIDimensions{
X0: win.X,
Y0: win.Y,
Width: win.Width,
Height: win.Height,
},
Decor: cdashdisplay.DefaultDecorations,
Title: helper.B32(win.Title),
}
wID, err := mc.CDash.CreateWindow(uiWindow)
if err != nil {
mc.EvBus.Emit(ui.PrintLogEv{Log: "failed to create window\n"})
return
}
mc.EvBus.Emit(ui.WindowCreatedEv{ID: wID, Title: win.Title})
mc.EvBus.Emit(ui.PrintLogEv{Log: "Window created!\n"})
}()
})
mc.EvBus.On(ui.DestroyWindowEv{}, func(e any) {
mc.Logger.Info(fmt.Sprintf("Called in to destroy win: %d", e.(ui.DestroyWindowEv).ID))
mc.CDash.DestroyWindow(e.(ui.DestroyWindowEv).ID)
}) })
mc.EvBus.On(ui.FindCDashDisplay{}, func(e any) { mc.EvBus.On(ui.FindCDashDisplay{}, func(e any) {
err := mc.DevClerk.FindDevices() go func() {
if err != nil { mc.Logger.Info("Looking for CDashDisplay")
mc.EvBus.Emit(ui.LogEv{Log: "Error finding devices: " + err.Error() + "\n"}) cdashdisplay.SetLogger(mc.Logger.With("[device]", "cdashdisplay"))
}
if len(mc.DevClerk.Devices) == 0 { display, err := cdashdisplay.NewCDashDisplay()
mc.EvBus.Emit(ui.LogEv{Log: " there are no devices\n"}) if err != nil {
} return
}
for _, d := range mc.DevClerk.Devices { mc.CDash = display
msg := fmt.Sprintf(" [%2d] %s\n", d.ID, d.Name) }()
mc.EvBus.Emit(ui.LogEv{Log: msg})
}
}) })
return mc return mc
+3 -2
View File
@@ -5,15 +5,16 @@ import (
"esdi/tui/internal/controllers" "esdi/tui/internal/controllers"
"esdi/tui/internal/views" "esdi/tui/internal/views"
"fmt" "fmt"
"log/slog"
"github.com/gdamore/tcell/v2" "github.com/gdamore/tcell/v2"
) )
func Start() error { func Start(logger *slog.Logger) error {
// The app starts running here! // The app starts running here!
// //
// Set the event capture for the global app itself here // Set the event capture for the global app itself here
mc := controllers.NewMainController() mc := controllers.NewMainController(logger.With("[ctrl]", "main"))
mc.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { mc.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyCtrlC || event.Rune() == 'q' { if event.Key() == tcell.KeyCtrlC || event.Rune() == 'q' {
+14 -1
View File
@@ -30,10 +30,23 @@ type CreateWindowEv struct {
Window models.Window Window models.Window
} }
type WindowCreatedEv struct { type DestroyWindowEv struct {
ID int16
}
type LayoutRegisterWindowEv struct {
Window models.Window Window models.Window
} }
type WindowCreatedEv struct {
ID int16
Title string
}
type WindowDestroyedEv struct {
ID int16
}
type ErrorCreateWindowEv struct { type ErrorCreateWindowEv struct {
Error error Error error
} }
+43 -5
View File
@@ -18,6 +18,27 @@ const (
layoutToolActionPagesID = "layout-tool-action-pages" layoutToolActionPagesID = "layout-tool-action-pages"
) )
func FindNodeByReference(
node *tview.TreeNode,
want any,
) *tview.TreeNode {
if node == nil {
return nil
}
if node.GetReference() == want {
return node
}
for _, child := range node.GetChildren() {
if found := FindNodeByReference(child, want); found != nil {
return found
}
}
return nil
}
func BindWindowEvents( func BindWindowEvents(
bus *events.Bus, bus *events.Bus,
doc *dom.DOM, doc *dom.DOM,
@@ -38,9 +59,24 @@ func BindWindowEvents(
return return
} }
newWindow := tview.NewTreeNode(e.(ui.WindowCreatedEv).Window.Title) newWindow := tview.NewTreeNode(e.(ui.WindowCreatedEv).Title).
SetReference(e.(ui.WindowCreatedEv).ID)
root.AddChild(newWindow) root.AddChild(newWindow)
}) })
bus.On(ui.WindowDestroyedEv{}, func(e any) {
root := tree.GetRoot()
if root == nil {
bus.Emit(ui.LogEv{Log: "unable to get current tree node"})
}
node := FindNodeByReference(root, e.(ui.WindowDestroyedEv).ID)
if node != nil {
root.RemoveChild(node)
}
// NODE: add a log here in case it fails so we know whats going on
})
bus.On(ui.ErrorCreateWindowEv{}, func(e any) { bus.On(ui.ErrorCreateWindowEv{}, func(e any) {
bus.Emit(ui.LogEv{ bus.Emit(ui.LogEv{
Log: fmt.Sprintf( Log: fmt.Sprintf(
@@ -68,19 +104,21 @@ func layoutToolTreeViewEvents(bus *events.Bus, doc *dom.DOM,
case 'x': case 'x':
// Delete selected window // Delete selected window
bus.Emit(ui.LogEv{Log: "calling delete window\n"}) bus.Emit(ui.LogEv{Log: "calling delete window\n"})
curNode := tree.GetCurrentNode() curNode := tree.GetCurrentNode()
if curNode == nil { if curNode == nil {
bus.Emit(ui.LogEv{Log: "unable to get current tree node"}) bus.Emit(ui.LogEv{Log: "unable to get current tree node"})
break break
} }
root := tree.GetRoot() ref := curNode.GetReference()
if root == nil { wID, ok := ref.(int16)
bus.Emit(ui.LogEv{Log: "unable to get current tree node"}) if !ok {
// Whatever, do something better here
break break
} }
root.RemoveChild(curNode) bus.Emit(ui.DestroyWindowEv{ID: wID})
case 'm': case 'm':
// Go into move mode // Go into move mode
case 'e': case 'e':
+6 -3
View File
@@ -1,8 +1,11 @@
// Package tui // Package tui
package tui package tui
import t "esdi/tui/internal/tui" import (
t "esdi/tui/internal/tui"
"log/slog"
)
func Run() error { func Run(logger *slog.Logger) error {
return t.Start() return t.Start(logger)
} }