コールバックな部分は若干やっつけだけど、基本的にはこんな感じだと思う。
event.goは綺麗というかすっきりして、ここまで来たらファイルを分離する意味が無い。
その分、main.goのhandleMouseEventがやたら汚い。
interface{}を具体的な型に落とす方法はswitchしかないのかな。
(一度投降後、何度かコードを綺麗にしてます)
main.go
package main
import (
"fmt"
"exp/draw"
"exp/draw/x11"
"image"
"./event"
"./gordon"
)
func handleMouseEvent(event interface{}, args ...interface{}) {
switch e := event.(type) {
case draw.MouseEvent:
{
me := draw.MouseEvent(e)
switch win := args[0].(type) {
case draw.Window:
{
win = draw.Window(win)
switch char := args[1].(type) {
case gordon.Character:
{
char = gordon.Character(char)
fmt.Printf(
"MouseEvent: Button= %d, Loc= %v\n",
me.Buttons, me.Loc)
draw.Draw(win.Screen(), char.Canon(), char.Mask(), image.ZP)
char.Position(me.Loc.X, me.Loc.Y)
draw.Draw(win.Screen(), char.Canon(), char, image.ZP)
win.FlushImage()
}
}
}
}
}
}
}
func main() {
gordon1, e := gordon.NewGordon(image.Point{X: 0, Y: 0})
if e != nil {
fmt.Printf("Error %v\n", e)
return
}
win, e := x11.NewWindow()
if e != nil {
fmt.Printf("Error %v\n", e)
return
}
eventChan := win.EventChan()
mouseCallBack := event.CallBack(handleMouseEvent)
sync := make(<-chan bool)
go event.HandleCallBack(eventChan, mouseCallBack, win, gordon1)
<-sync
}
event.go
package event
type CallBack func(event interface{}, args ...interface{})
func HandleCallBack(eventChan <-chan interface{}, fun CallBack, args ...interface{}) {
for {
event := <-eventChan
go fun(event, args...)
}
}
gordon.go
package gordon
import (
"bufio"
"image"
"image/png"
"os"
)
os.DevNull
type Character interface {
image.Image
Canon() image.Rectangle
Mask() image.Image
Position(x, y int)
}
type Gordon struct {
image.Image
Rect image.Rectangle
maskImage image.Image
}
func (g *Gordon) Position(x, y int) {
r := g.Bounds()
g.Rect = image.Rect(
x, y,
x+r.Max.X, y+r.Max.Y)
}
func (g *Gordon) Canon() image.Rectangle {
return g.Rect.Canon()
}
func (g *Gordon) Mask() image.Image {
return g.maskImage
}
func NewGordon(point image.Point) (gordon *Gordon, e os.Error) {
gordon = new(Gordon)
img, e := loadGordon()
if e != nil {
return nil, e
}
gordon.Image = img
gordon.Position(point.X, point.Y)
gordon.maskImage = image.NewGray(img.Bounds().Max.X, img.Bounds().Max.Y)
return gordon, e
}
func loadGordon() (image.Image, os.Error) {
file, e := os.Open("./Gordon.png", os.O_RDONLY, 0666)
if e != nil {
return nil, e
}
read := bufio.NewReader(file)
icon, e := png.Decode(read)
if e != nil {
return nil, e
}
return icon, nil
}
0 件のコメント:
コメントを投稿