133 lines
3.0 KiB
Go
133 lines
3.0 KiB
Go
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
|
|
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()
|
|
}
|
|
|
|
// 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,
|
|
}
|
|
}
|
|
|
|
// 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
|
|
if playSound {
|
|
go b.player(wg)
|
|
}
|
|
go b.timeCounter(500 * time.Millisecond)
|
|
go b.frameChanger(125 * time.Millisecond)
|
|
return inWork
|
|
}
|
|
|
|
// 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
|
|
time.Sleep(step)
|
|
}
|
|
work = false
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
|
|
//player is a loop to start sound play
|
|
func (b *Roflcopter) player(wg *sync.WaitGroup) {
|
|
b.sound(wg)
|
|
wg.Wait()
|
|
if work {
|
|
b.player(wg)
|
|
} else {
|
|
inWork.Done()
|
|
}
|
|
}
|
|
|
|
//frameChanger is a loop to change frames
|
|
func (b *Roflcopter) frameChanger(delay time.Duration) {
|
|
nextframe := 2
|
|
|
|
for work {
|
|
switch nextframe {
|
|
case 1:
|
|
{
|
|
*b.str = frame1 + "Ends in " + duration.String()
|
|
time.Sleep(delay)
|
|
nextframe = 2
|
|
}
|
|
|
|
case 2:
|
|
{
|
|
*b.str = frame2 + "Ends in " + duration.String()
|
|
time.Sleep(delay)
|
|
nextframe = 1
|
|
}
|
|
}
|
|
b.runner()
|
|
}
|
|
inWork.Done()
|
|
}
|
|
|
|
//sound plays sound
|
|
func (b *Roflcopter) sound(wg *sync.WaitGroup) {
|
|
wg.Add(1)
|
|
t := 1*time.Second + 380*time.Millisecond
|
|
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()
|
|
}
|