func Play() { // initial setup w, err := x11.NewWindow() if err != nil { panic("Could not make window!") } bounds := w.Screen().Bounds() midY := (bounds.Max.Y - bounds.Min.Y) / 2 b := ball{place{(bounds.Max.X - bounds.Min.X) / 2, midY}, math.Pi / 6} left := player{0, place{bounds.Min.X, midY}} right := player{0, place{bounds.Max.X, midY}} g := &game{w, b, left, right} // event channel events := make(chan func(), 1) // a buffer size of one should be plenty // window events keys := map[int]func(){'a': func() { left.up(bounds.Min.Y) }, 'z': func() { left.down(bounds.Max.Y) }, 'q': func() { os.Exit(0) }} go func() { c := w.EventChan() for { e := <-c switch t := e.(type) { case gui.ConfigEvent: g.redoImage() case gui.ErrEvent: panic("Cannot handle gui.ErrEvent!") case gui.KeyEvent: if f, ok := keys[t.Key]; ok { events <- f } case gui.MouseEvent: // ignored default: panic("Unknown event type!") } } }() // time events go func() { t := time.NewTicker(500 * 1e6) // 1e6 = 1 million nanos = 1 milli for { <-t.C events <- func() { g.tick() } } }() // main loop - respond to events for { (<-events)() // Can event-driven programming get any simpler? } }
func main() { window, err := x11.NewWindow() if err != nil { fmt.Printf("Cannot open an x11 window\n") return } screen := window.Screen() gc := draw2d.NewGraphicContext(screen) gc.SetStrokeColor(image.Black) gc.SetFillColor(image.White) gc.Clear() for i := 0.0; i < 360; i = i + 10 { // Go from 0 to 360 degrees in 10 degree steps gc.BeginPath() // Start a new path gc.Save() // Keep rotations temporary gc.MoveTo(144, 144) gc.Rotate(i * (math.Pi / 180.0)) // Rotate by degrees on stack from 'for' gc.RLineTo(72, 0) gc.Stroke() gc.Restore() // Get back the unrotated state } window.FlushImage() gc.SetLineWidth(3) nbclick := 0 for { switch evt := (<-window.EventChan()).(type) { case gui.KeyEvent: if evt.Key == 'q' { window.Close() } case gui.MouseEvent: if evt.Buttons&1 != 0 { if nbclick%2 == 0 { gc.MoveTo(float64(evt.Loc.X), float64(evt.Loc.Y)) } else { gc.LineTo(float64(evt.Loc.X), float64(evt.Loc.Y)) gc.Stroke() window.FlushImage() } nbclick = nbclick + 1 } } } }
func main() { var window Window flag.Parse() // Parse image paths fmt.Printf("%s\n", *imgPath) if *imgPath != "" { r := strings.TrimFunc(*imgPath, TrimFunc) split := strings.Split(r[1:len(r)-1], "-") start, _ := strconv.Atoi(split[0]) end, _ := strconv.Atoi(split[1]) f := 0 for i := start; i <= end; i++ { path := strings.Replace(*imgPath, r, strconv.Itoa(i), -1) window.Frames = append(window.Frames, Frame{Id: f, Path: path}) f++ } window.FrameCount = f } else if *savefile != "" { load(&window, *savefile) } // Do cpu profiling if asked for if *cpuprof != "" { f, err := os.Create(*cpuprof) if err != nil { fmt.Printf("Error: %v\n", err) } else { pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } } // Calibration data window.Dist = *dist if *calPath != "" { calimg, err := getImage(*calPath) if err == nil { window.Calibration = Frame{Path: *calPath, img: calimg} } } // Create X11 window xwindow, err := x11.NewWindow() window.Window = xwindow if err != nil { fmt.Printf("Error: %v\n", err) } window.Screen = xwindow.Screen() window.DrawFrame(window.Cfra) memno := 1 // Event loop for { event, ok := <-xwindow.EventChan() if ok != true { break } switch e := event.(type) { case gui.ConfigEvent: window.Screen = xwindow.Screen() window.DrawFrame(window.Cfra) break case gui.MouseEvent: window.DrawFrame(window.Cfra) break case gui.KeyEvent: switch e.Key { case 'c': case 's': fmt.Printf("Saving to %s ... ", *savefile) err := save(&window, *savefile) if err != nil { fmt.Printf("Error while saving: %s\n", err) break } fmt.Println("Done!") case 'l': fmt.Printf("Loading from %s ... ", *savefile) err := load(&window, *savefile) if err != nil { fmt.Printf("Error while loading: %s\n", err) break } fmt.Println("Done!") case 'm': if *memprof == "" { break } f, _ := os.Create(fmt.Sprintf("%s%d", *memprof, memno)) pprof.WriteHeapProfile(f) f.Close() memno++ case 'a': // Find all circles go func() { fmt.Println("Trying to transform all frames .. ") for window.GetState() == WORKING { time.Sleep(1e9) } frame := window.Cfra for i := 0; i < window.FrameCount; i++ { if window.Frames[frame].Calculated { continue } window.Frames[frame].Centre = findCircle(&window, frame) window.Frames[frame].Calculated = true frame++ runtime.GC() } fmt.Println("All frames transformed!") }() case 'g': fmt.Println("Garbage collecting") runtime.GC() case KEY_SPACE: // space go func() { cfra := window.Cfra if window.Frames[cfra].Calculated { return } for window.GetState() == WORKING { time.Sleep(1e9) } window.Frames[cfra].Centre = findCircle(&window, cfra) window.Frames[cfra].Calculated = true window.DrawFrame(cfra) runtime.GC() }() case KEY_LEFT: if window.Cfra > 0 { window.Cfra-- } window.DrawFrame(window.Cfra) case KEY_RIGHT: if window.Cfra < window.FrameCount-1 { window.Cfra++ } window.DrawFrame(window.Cfra) default: } } } }