func (s *christmas) animateNextFrame(frameCount int, frame framebuffer.Segment) { // Time to change lights if time.Now().Sub(s.changeTime) > 0 { s.changeTime = time.Now().Add(s.period) // Move on to next light colour if s.nextColour == uint(len(s.lightColours))-1 { s.nextColour = 0 } else { s.nextColour++ } // Set each LED appropriately off := framebuffer.NewRgbFromInt(0) for i := uint(0); i < frame.Len(); i++ { // Which colour index should this be c := (i / s.lightSize) % uint(len(s.lightColours)) // Either turn colour on or turn LED off if c == s.nextColour { frame.Set(i, s.lightColours[s.nextColour]) } else { frame.Set(i, off) } } } }
func (s *sweetshop) animateNextFrame(frameCount int, frame framebuffer.Segment) { if time.Now().Sub(s.changeTime) > 0 { // Set next change time s.changeTime = time.Now().Add(s.period) // Refresh the random colours for i := uint(0); i < frame.Len(); i++ { frame.Set(i, framebuffer.NewRgbFromInt(rand.Int()&(1<<24-1))) } } }
// Start animate driver new version func StartDriver(renderer chan *framebuffer.FrameBuffer) { // Start the animator go routine go func() { // The animations in play from the UI (default all off) var animators []segNameAndAnimator = make([]segNameAndAnimator, 1) animators[0] = segNameAndAnimator{"All", newStaticColour(framebuffer.NewRgbFromInt(0))} var lastRenderedFrameBuffer *framebuffer.FrameBuffer frameCounter := 0 for { select { // Request to render a frame buffer case fb := <-renderer: renderStartTime := time.Now() // Create / Copy frame buffer to be rendered if lastRenderedFrameBuffer == nil { fb = framebuffer.NewFrameBuffer() } else { fb = lastRenderedFrameBuffer.CloneFrameBuffer() } // Animate and return updated frame buffer for _, v := range animators { // Resolve the segment to animate, based on string name if seg, err := framebuffer.GetNamedSegment(fb, v.namedSegment); err == nil { v.animator.animateNextFrame(frameCounter, seg) } } // Report render time and send buffer stats.AddFrameRenderTimeSample(time.Since(renderStartTime)) renderer <- fb lastRenderedFrameBuffer = fb // Request animation update case currentAnimations := <-animationChanged: animators = buildAnimatorList(currentAnimations) lastRenderedFrameBuffer = nil frameCounter = 0 } } }() }
// Append an animation specified as a string func appendAnimatorsForAction(animators *[]segNameAndAnimator, seg SegmentAction) { switch seg.Animation { case "Static": if colour, err := strconv.ParseInt(seg.Params, 16, 32); err == nil { *animators = append(*animators, segNameAndAnimator{seg.Segment, newStaticColour(framebuffer.NewRgbFromInt(int(colour)))}) } else { log.WithFields(log.Fields{"params": seg.Params, "Error": err.Error()}).Warn("Bad animataion parameter") } case "Runner": *animators = append(*animators, segNameAndAnimator{seg.Segment, newRunner(framebuffer.NewRgb(0, 0, 255))}) case "Cylon": *animators = append(*animators, segNameAndAnimator{seg.Segment, newCylon()}) case "Rainbow": // TODO MAKE TIME A PARAMETER *animators = append(*animators, segNameAndAnimator{seg.Segment, newRainbow(time.Second * 15)}) case "Sweet Shop": // TODO MAKE TIME A PARAMETER *animators = append(*animators, segNameAndAnimator{seg.Segment, newSweetshop(time.Second * 1)}) case "Candle": // TODO MAKE POSITION AND REPEAT PARAMETERS *animators = append(*animators, segNameAndAnimator{seg.Segment, newCandle()}) case "Christmas": // TODO MAKE TIME A PARAMETER *animators = append(*animators, segNameAndAnimator{seg.Segment, newChristmas(time.Second * 1)}) case "Pulse": *animators = append(*animators, segNameAndAnimator{seg.Segment, newPulse()}) default: log.WithField("action", seg.Animation).Warn("Unknown animataion action") } }