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
2022-02-12 19:12:15 +03:00
var (
work bool = true
duration time . Duration
2022-02-12 20:14:24 +03:00
inWork * sync . WaitGroup
2022-02-12 19:12:15 +03:00
)
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 )
2022-02-12 19:12:15 +03:00
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 )
2022-02-12 19:12:15 +03:00
* 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:12:15 +03:00
}
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 )
2022-02-12 19:12:15 +03:00
wg . Wait ( )
2022-02-12 20:14:24 +03:00
if work {
b . player ( wg )
} else {
inWork . Done ( )
}
2022-02-12 19:12:15 +03:00
}
2022-02-12 20:14:24 +03:00
//frameChanger is a loop to change frames
2022-02-12 19:12:15 +03:00
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 ( )
2022-02-12 19:12:15 +03:00
time . Sleep ( delay )
nextframe = 2
}
case 2 :
{
2022-02-12 20:14:24 +03:00
* b . str = frame2 + "Ends in " + duration . String ( )
2022-02-12 19:12:15 +03:00
time . Sleep ( delay )
nextframe = 1
}
}
2022-02-12 19:30:38 +03:00
b . runner ( )
2022-02-12 19:12:15 +03:00
}
2022-02-12 20:14:24 +03:00
inWork . Done ( )
2022-02-12 19:12:15 +03:00
}
2022-02-12 20:14:24 +03:00
//sound plays sound
func ( b * Roflcopter ) sound ( wg * sync . WaitGroup ) {
2022-02-12 19:12:15 +03:00
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 ( )
}