go-roflcopter/roflcopter/roflcopter.go

133 lines
3.0 KiB
Go
Raw Normal View History

2021-12-12 02:12:56 +03:00
package roflcopter
import (
"bytes"
_ "embed"
"io"
"log"
"sync"
"time"
"github.com/faiface/beep/mp3"
"github.com/faiface/beep/speaker"
)
//go:embed embed\swah.mp3
var swah []byte
var (
work bool = true
duration time.Duration
2022-02-12 20:14:24 +03:00
inWork *sync.WaitGroup
)
const (
frame1 = " ROFL:ROFL: \n _^____ \n L __/ [] \\ \n O ===__ \\ \n L \\________] \n I I \n --------/ \n"
frame2 = " :ROFL:ROFL\n _^____ \n __/ [] \\ \nLOL===__ \\ \n \\________] \n I I \n --------/ \n"
)
type Roflcopter struct {
work bool
count time.Duration
str *string
runner func()
}
2022-02-12 20:14:24 +03:00
// NewRoflcopter creates a new instance of roflcopter. amount sets duration, outStr is used to output frames, funcrunner will be called after frame change
func NewRoflcopter(amount time.Duration, outStr *string, funcrunner func()) *Roflcopter {
inWork = new(sync.WaitGroup)
return &Roflcopter{
work: true,
str: outStr,
count: amount,
runner: funcrunner,
}
}
2022-02-12 20:14:24 +03:00
// Start starts frame changing. Soundplaying can be set by true or false. Returns WaitGroup to know when it has finished work.
func (b *Roflcopter) Start(playSound bool) *sync.WaitGroup {
var wg *sync.WaitGroup = new(sync.WaitGroup)
inWork.Add(1)
*b.str = frame1 + b.count.String()
work = b.work
duration = b.count
2022-02-12 20:14:24 +03:00
if playSound {
go b.player(wg)
2022-02-12 02:12:00 +03:00
}
2022-02-12 20:14:24 +03:00
go b.timeCounter(500 * time.Millisecond)
2022-02-12 19:30:38 +03:00
go b.frameChanger(125 * time.Millisecond)
2022-02-12 20:14:24 +03:00
return inWork
}
2022-02-12 19:30:38 +03:00
2022-02-12 20:14:24 +03:00
// OnlySound only plays sound. Frames are not changing. Returns WaitGroup to know when it has finished work
func (b *Roflcopter) OnlySound() *sync.WaitGroup {
var wg *sync.WaitGroup = new(sync.WaitGroup)
inWork.Add(1)
work = b.work
duration = b.count
go b.player(wg)
go b.timeCounter(500 * time.Millisecond)
return inWork
}
// timeCounter counts time and stops other work when time ends
func (b *Roflcopter) timeCounter(step time.Duration) {
for duration > 0 {
duration -= step
2022-02-12 19:30:38 +03:00
time.Sleep(step)
}
work = false
2022-02-12 20:14:24 +03:00
time.Sleep(100 * time.Millisecond)
2022-02-12 19:30:38 +03:00
}
2022-02-12 20:14:24 +03:00
//player is a loop to start sound play
func (b *Roflcopter) player(wg *sync.WaitGroup) {
b.sound(wg)
wg.Wait()
2022-02-12 20:14:24 +03:00
if work {
b.player(wg)
} else {
inWork.Done()
}
}
2022-02-12 20:14:24 +03:00
//frameChanger is a loop to change frames
func (b *Roflcopter) frameChanger(delay time.Duration) {
nextframe := 2
for work {
switch nextframe {
case 1:
{
2022-02-12 20:14:24 +03:00
*b.str = frame1 + "Ends in " + duration.String()
time.Sleep(delay)
nextframe = 2
}
case 2:
{
2022-02-12 20:14:24 +03:00
*b.str = frame2 + "Ends in " + duration.String()
time.Sleep(delay)
nextframe = 1
}
}
2022-02-12 19:30:38 +03:00
b.runner()
}
2022-02-12 20:14:24 +03:00
inWork.Done()
}
2022-02-12 20:14:24 +03:00
//sound plays sound
func (b *Roflcopter) sound(wg *sync.WaitGroup) {
wg.Add(1)
2022-02-12 19:30:38 +03:00
t := 1*time.Second + 380*time.Millisecond
2021-12-12 02:12:56 +03:00
streamer, format, err := mp3.Decode(io.NopCloser(bytes.NewReader(swah)))
if err != nil {
log.Fatal(err)
}
defer streamer.Close()
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
speaker.Play(streamer)
time.Sleep(t * 1)
wg.Done()
}