generated from thinkode/modelRepository
11-hardware-definition (#17)
- Detection of FTDI and MIDI peripherals - Creation od OS2L peripherals - Optimization Reviewed-on: #17
This commit was merged in pull request #17.
This commit is contained in:
172
app.go
172
app.go
@@ -2,150 +2,78 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"dmxconnect/hardware"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
projectsDirectory = "projects" // The directory were are stored all the projects
|
||||
avatarsDirectory = "frontend/public" // The directory were are stored all the avatars
|
||||
projectExtension = ".dmxproj" // The extension of a DMX Connect project
|
||||
"sync"
|
||||
)
|
||||
|
||||
// App struct
|
||||
type App struct {
|
||||
ctx context.Context
|
||||
ctx context.Context
|
||||
cancelFunc context.CancelFunc
|
||||
hardwareManager *hardware.HardwareManager // For managing all the hardware
|
||||
wmiMutex sync.Mutex // Avoid some WMI operations at the same time
|
||||
projectInfo ProjectInfo // The project information structure
|
||||
projectSave string // The file name of the project
|
||||
}
|
||||
|
||||
// NewApp creates a new App application struct
|
||||
func NewApp() *App {
|
||||
return &App{}
|
||||
// Create a new hadware manager
|
||||
hardwareManager := hardware.NewHardwareManager()
|
||||
// hardwareManager.RegisterFinder(hardware.NewMIDIFinder(5 * time.Second))
|
||||
hardwareManager.RegisterFinder(hardware.NewFTDIFinder(5 * time.Second))
|
||||
// hardwareManager.RegisterFinder(hardware.NewOS2LFinder())
|
||||
return &App{
|
||||
hardwareManager: hardwareManager,
|
||||
projectSave: "",
|
||||
projectInfo: ProjectInfo{
|
||||
PeripheralsInfo: make(map[string]hardware.PeripheralInfo),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// startup is called when the app starts. The context is saved
|
||||
// so we can call the runtime methods
|
||||
func (a *App) startup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
func (a *App) onStartup(ctx context.Context) {
|
||||
a.ctx, a.cancelFunc = context.WithCancel(ctx)
|
||||
err := a.hardwareManager.Start(a.ctx)
|
||||
if err != nil {
|
||||
log.Err(err).Str("file", "app").Msg("unable to start the hardware manager")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// GetProjects gets all the projects in the projects directory
|
||||
func (a *App) GetProjects() ([]ProjectInfo, error) {
|
||||
projects := []ProjectInfo{}
|
||||
|
||||
f, err := os.Open(projectsDirectory)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to open the projects directory: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files, err := f.Readdir(0)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to read the projects directory: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, fileInfo := range files {
|
||||
// Open the file and get the show name
|
||||
fileData, err := os.ReadFile(filepath.Join(projectsDirectory, fileInfo.Name()))
|
||||
if err == nil {
|
||||
projectObject := ProjectInfo{}
|
||||
err = yaml.Unmarshal(fileData, &projectObject)
|
||||
if err == nil {
|
||||
// Add the SaveFile property
|
||||
projectObject.ShowInfo.SaveFile = fileInfo.Name()
|
||||
projects = append(projects, projectObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
return projects, nil
|
||||
// onReady is called when the DOM is ready
|
||||
// We get the current peripherals connected
|
||||
func (a *App) onReady(ctx context.Context) {
|
||||
// log.Debug().Str("file", "peripherals").Msg("getting peripherals...")
|
||||
// err := a.hardwareManager.Scan()
|
||||
// if err != nil {
|
||||
// log.Err(err).Str("file", "app").Msg("unable to get the peripherals")
|
||||
// }
|
||||
return
|
||||
}
|
||||
|
||||
// GetProjectInfo returns the information of the saved project
|
||||
func (a *App) GetProjectInfo(projectFile string) (ShowInfo, error) {
|
||||
projectPath := filepath.Join(projectsDirectory, projectFile)
|
||||
content, err := os.ReadFile(projectPath)
|
||||
// onShutdown is called when the app is closing
|
||||
// We stop all the pending processes
|
||||
func (a *App) onShutdown(ctx context.Context) {
|
||||
// Close the application properly
|
||||
log.Trace().Str("file", "app").Msg("app is closing")
|
||||
// Explicitly close the context
|
||||
a.cancelFunc()
|
||||
err := a.hardwareManager.Stop()
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to read the project file: %v", err)
|
||||
return ShowInfo{}, err
|
||||
log.Err(err).Str("file", "app").Msg("unable to stop the hardware manager")
|
||||
}
|
||||
|
||||
projectInfo := ProjectInfo{}
|
||||
|
||||
err = yaml.Unmarshal(content, &projectInfo)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to get the project information: %v", err)
|
||||
return ShowInfo{}, err
|
||||
}
|
||||
projectInfo.ShowInfo.SaveFile = projectFile
|
||||
return projectInfo.ShowInfo, nil
|
||||
}
|
||||
|
||||
// ChooseAvatarPath opens a filedialog to choose the show avatar
|
||||
func (a *App) ChooseAvatarPath() (string, error) {
|
||||
// Open the file dialog box
|
||||
filePath, err := runtime.OpenFileDialog(a.ctx, runtime.OpenDialogOptions{
|
||||
Title: "Choose your show avatar",
|
||||
Filters: []runtime.FileFilter{
|
||||
{
|
||||
DisplayName: "Images",
|
||||
Pattern: "*.png;*.jpg;*.jpeg",
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Copy the avatar to the application avatars path
|
||||
avatarPath := filepath.Join(avatarsDirectory, filepath.Base(filePath))
|
||||
_, err = copy(filePath, avatarPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Base(filePath), nil
|
||||
}
|
||||
|
||||
// SaveProject saves the project
|
||||
func (a *App) SaveProject(showInfo ShowInfo) (string, error) {
|
||||
log.Printf("Saving the project %s to %s", showInfo.Name, showInfo.SaveFile)
|
||||
// If there is no save file, create a new one with the show name
|
||||
if showInfo.SaveFile == "" {
|
||||
showInfo.SaveFile = fmt.Sprintf("%s%s", formatString(showInfo.Name), projectExtension)
|
||||
}
|
||||
project := ProjectInfo{}
|
||||
log.Printf("The number of universes: %d", showInfo.UniversesNumber)
|
||||
project.ShowInfo = showInfo
|
||||
data, err := yaml.Marshal(project)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = os.WriteFile(filepath.Join(projectsDirectory, showInfo.SaveFile), data, os.ModePerm)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return showInfo.SaveFile, nil
|
||||
}
|
||||
|
||||
// ShowInfo defines the information of the show
|
||||
type ShowInfo struct {
|
||||
Name string `yaml:"name"`
|
||||
Date string `yaml:"date"`
|
||||
UniversesNumber int `yaml:"universesNumber"`
|
||||
Avatar string `yaml:"avatar"`
|
||||
Comments string `yaml:"comments"`
|
||||
SaveFile string `yaml:"-"`
|
||||
}
|
||||
|
||||
// ProjectInfo defines all the information for a lighting project
|
||||
type ProjectInfo struct {
|
||||
ShowInfo ShowInfo `yaml:"show"` // Show information
|
||||
return
|
||||
}
|
||||
|
||||
func formatString(input string) string {
|
||||
|
||||
Reference in New Issue
Block a user