refactor dynamic universes

Signed-off-by: Martyn Ranyard <m@rtyn.berlin>
This commit is contained in:
Martyn 2020-05-19 10:45:42 +02:00
parent 3e04b69b97
commit 209bebe51d
2 changed files with 87 additions and 51 deletions

View File

@ -1,16 +1,44 @@
package main package main
import ( import (
"image/color"
"fyne.io/fyne"
"fyne.io/fyne/app" "fyne.io/fyne/app"
"fyne.io/fyne/theme"
"fyne.io/fyne/widget" "fyne.io/fyne/widget"
fynewidget "git.martyn.berlin/martyn/LEDController/internal/fynewidget"
"log"
) )
type tappableIcon struct {
widget.Icon
}
func newTappableIcon(res fyne.Resource) *tappableIcon {
icon := &tappableIcon{}
icon.ExtendBaseWidget(icon)
icon.SetResource(res)
return icon
}
func (t *tappableIcon) Tapped(_ *fyne.PointEvent) {
log.Println("I have been tapped")
}
func (t *tappableIcon) TappedSecondary(_ *fyne.PointEvent) {
}
func main() { func main() {
app := app.New() app := app.New()
w := app.NewWindow("Hello") w := app.NewWindow("Hello")
w.SetContent(widget.NewVBox( w.SetContent(widget.NewVBox(
widget.NewLabel("Hello Fyne!"), widget.NewLabel("Hello Fyne!"),
newTappableIcon(theme.FyneLogo()),
fynewidget.NewOutputWidget(color.Black),
widget.NewButton("Quit", func() { widget.NewButton("Quit", func() {
app.Quit() app.Quit()
}), }),

View File

@ -3,14 +3,15 @@ package main
import ( import (
"fmt" "fmt"
"log" "log"
"time" "math"
"strconv"
"os" "os"
"strconv"
"time"
webserver "git.martyn.berlin/martyn/LEDController/internal/webserver" patterns "git.martyn.berlin/martyn/LEDController/internal/patterns"
queue "git.martyn.berlin/martyn/LEDController/internal/queue" queue "git.martyn.berlin/martyn/LEDController/internal/queue"
remapping "git.martyn.berlin/martyn/LEDController/internal/remapping" remapping "git.martyn.berlin/martyn/LEDController/internal/remapping"
patterns "git.martyn.berlin/martyn/LEDController/internal/patterns" webserver "git.martyn.berlin/martyn/LEDController/internal/webserver"
"github.com/Hundemeier/go-sacn/sacn" "github.com/Hundemeier/go-sacn/sacn"
) )
@ -18,10 +19,10 @@ import (
type RGBcolor = [3]byte type RGBcolor = [3]byte
var currentFrame [2][512]byte var currentFrame [2][512]byte
var channels [2]chan<-[512]byte var channels [2]chan<- [512]byte
var sema = make(chan struct{}, 1) // a binary semaphore guarding currentFrame var sema = make(chan struct{}, 1) // a binary semaphore guarding currentFrame
var currentEffect queue.QueueItem; var currentEffect queue.QueueItem
var globalEffectChannel = make(chan queue.QueueItem, 1024) var globalEffectChannel = make(chan queue.QueueItem, 1024)
func foreverLoop() { func foreverLoop() {
@ -30,22 +31,24 @@ func foreverLoop() {
for u := 0; u < 2; u++ { for u := 0; u < 2; u++ {
sema <- struct{}{} // acquire token sema <- struct{}{} // acquire token
channels[u] <- currentFrame[u] channels[u] <- currentFrame[u]
<- sema <-sema
} }
} }
} }
func reduceBrightness(universe [512]byte, percentage int) [512]byte{ func reduceBrightness(universe [512]byte, percentage int) [512]byte {
for i := range(universe) { for i := range universe {
universe[i] = byte(float64(universe[i]) * (float64(percentage) / float64(100))) universe[i] = byte(float64(universe[i]) * (float64(percentage) / float64(100)))
} }
return universe return universe
} }
var universeCount int = 0
func main() { func main() {
go func() { go func() {
var err error var err error
listenPort := 5353 listenPort := 5353
if os.Getenv("LISTEN_PORT") != "" { if os.Getenv("LISTEN_PORT") != "" {
listenPort, err = strconv.Atoi(os.Getenv("LISTEN_PORT")) listenPort, err = strconv.Atoi(os.Getenv("LISTEN_PORT"))
if err != nil { if err != nil {
@ -70,6 +73,9 @@ func main() {
PanelHeight = 4 PanelHeight = 4
} }
universeCount = int(math.Ceil(float64(PanelHeight*PanelWidth*3) / 510))
fmt.Printf("Universe count is %d", universeCount)
PanelBrightness, err := strconv.Atoi(os.Getenv("PANEL_BRIGHTNESS")) PanelBrightness, err := strconv.Atoi(os.Getenv("PANEL_BRIGHTNESS"))
if err != nil { if err != nil {
PanelBrightness = 100 PanelBrightness = 100
@ -82,8 +88,8 @@ func main() {
} }
//activates the universes //activates the universes
for i := 0; i < 2; i++ { for i := 0; i < universeCount; i++ {
channels[i], err = trans.Activate(uint16(i+1)) channels[i], err = trans.Activate(uint16(i + 1))
//deactivate the channel on exit //deactivate the channel on exit
defer close(channels[i]) defer close(channels[i])
trans.SetMulticast(uint16(i+1), false) //this specific setup will not multicast on windows, trans.SetMulticast(uint16(i+1), false) //this specific setup will not multicast on windows,
@ -91,9 +97,10 @@ func main() {
} }
// Plasma for start frame // Plasma for start frame
rearranged := remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.PlasmaPanel(PanelWidth, PanelHeight, 40))) /*rearranged := reduceBrightness(remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.PlasmaPanel(PanelWidth, PanelHeight, 40))), PanelBrightness)
currentFrame[0] = remapping.Slice512(rearranged[0]) for i := 0; i < universeCount; i++ {
currentFrame[1] = remapping.Slice512(rearranged[1]) currentFrame[i] = remapping.Slice512(rearranged[i])
}*/
var e queue.QueueItem var e queue.QueueItem
e.Effect = "red" e.Effect = "red"
e.Duration = 40 * 50 e.Duration = 40 * 50
@ -113,49 +120,50 @@ func main() {
currentEffect.Duration -= 40 currentEffect.Duration -= 40
} else { } else {
if len(globalEffectChannel) > 0 { if len(globalEffectChannel) > 0 {
currentEffect = <- globalEffectChannel currentEffect = <-globalEffectChannel
} }
} }
var rearranged [][]byte var rearranged [][]byte
switch currentEffect.Effect { switch currentEffect.Effect {
case "line": case "line":
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.ZigZag(PanelWidth, PanelHeight))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.ZigZag(PanelWidth, PanelHeight)))
case "plasma": case "plasma":
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.PlasmaPanel(PanelWidth, PanelHeight, currentEffect.Speed))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.PlasmaPanel(PanelWidth, PanelHeight, currentEffect.Speed)))
case "red": case "red":
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.RedPanel(PanelWidth,PanelHeight))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.RedPanel(PanelWidth, PanelHeight)))
case "random": case "random":
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.RandomColourPanel(PanelWidth,PanelHeight,currentEffect.Speed))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.RandomColourPanel(PanelWidth, PanelHeight, currentEffect.Speed)))
case "linearplasma": case "linearplasma":
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, patterns.LinearPlasma(PanelWidth*PanelHeight)) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, patterns.LinearPlasma(PanelWidth*PanelHeight))
case "gradientred": case "gradientred":
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, patterns.Gradient(255, 0, 0, 0, 0, 255, 0, PanelWidth*PanelHeight)) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, patterns.Gradient(255, 0, 0, 0, 0, 255, 0, PanelWidth*PanelHeight))
case "sine": case "sine":
var black patterns.RGBcolor var black patterns.RGBcolor
var red patterns.RGBcolor var red patterns.RGBcolor
red[0] = 255 red[0] = 255
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.Sinewave(PanelWidth, PanelHeight, black, red, currentEffect.Speed))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.Sinewave(PanelWidth, PanelHeight, black, red, currentEffect.Speed)))
case "sinechase": case "sinechase":
var black patterns.RGBcolor var black patterns.RGBcolor
var red patterns.RGBcolor var red patterns.RGBcolor
red[0] = 255 red[0] = 255
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.SineChase(PanelWidth, PanelHeight, black, red, currentEffect.Speed))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.SineChase(PanelWidth, PanelHeight, black, red, currentEffect.Speed)))
case "plasmapulse": case "plasmapulse":
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.PlasmaColourPanel(PanelWidth,PanelHeight, currentEffect.Speed))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.PlasmaColourPanel(PanelWidth, PanelHeight, currentEffect.Speed)))
case "colour": case "colour":
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.FillPanel(PanelWidth,PanelHeight, currentEffect.SeedColour[0], currentEffect.SeedColour[1], currentEffect.SeedColour[2]))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.FillPanel(PanelWidth, PanelHeight, currentEffect.SeedColour[0], currentEffect.SeedColour[1], currentEffect.SeedColour[2])))
case "fade": case "fade":
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.GradientPanel(PanelWidth,PanelHeight, currentEffect.SeedColour, currentEffect.SecondColour))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, true, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.GradientPanel(PanelWidth, PanelHeight, currentEffect.SeedColour, currentEffect.SecondColour)))
default: default:
rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.FillPanel(PanelWidth,PanelHeight, 128,0,128))) rearranged = remapping.SliceRearrange(PanelWidth, PanelHeight, false, remapping.XYGridToLinear(PanelWidth, PanelHeight, patterns.FillPanel(PanelWidth, PanelHeight, 128, 0, 128)))
} }
//rearranged := remapping.SliceRearrange(PanelWidth,PanelHeight,true,linearPlasma(PanelWidth*PanelHeight)) //rearranged := remapping.SliceRearrange(PanelWidth,PanelHeight,true,linearPlasma(PanelWidth*PanelHeight))
sema <- struct{}{} // acquire token sema <- struct{}{} // acquire token
currentFrame[0] = reduceBrightness(remapping.Slice512(rearranged[0]),PanelBrightness) for i := 0; i < universeCount; i++ {
currentFrame[1] = reduceBrightness(remapping.Slice512(rearranged[1]),PanelBrightness) currentFrame[i] = reduceBrightness(remapping.Slice512(rearranged[i]), PanelBrightness)
<- sema }
<-sema
time.Sleep(40 * time.Millisecond) time.Sleep(40 * time.Millisecond)
} }
}() }()
foreverLoop(); foreverLoop()
} }