From 8616aa071b129384123f85191f5927a7e22d8123 Mon Sep 17 00:00:00 2001 From: Gustavo Niemeyer Date: Thu, 23 Jan 2014 15:25:04 -0200 Subject: [PATCH] Added end-to-end test for painting. --- all_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++- bridge.go | 5 +++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/all_test.go b/all_test.go index ba31d7d9..76ab2c52 100644 --- a/all_test.go +++ b/all_test.go @@ -5,6 +5,7 @@ import ( "flag" "fmt" "github.com/niemeyer/qml" + "github.com/niemeyer/qml/gl" "image" "image/color" "io/ioutil" @@ -73,6 +74,26 @@ func (s *S) TearDownTest(c *C) { qml.SetLogger(nil) } +type RectType struct { + PaintCount int +} + +func (r *RectType) Paint() { + r.PaintCount++ + + // TODO Dynamically compute this. + width := gl.Float(100) + height := gl.Float(100) + + gl.Color3f(1.0, 0.0, 0.0) + gl.Begin(gl.QUADS) + gl.Vertex2f(0, 0) + gl.Vertex2f(width, 0) + gl.Vertex2f(width, height) + gl.Vertex2f(0, height) + gl.End() +} + type TestType struct { private bool // Besides being private, also adds a gap in the reflect field index. @@ -223,11 +244,13 @@ type TestData struct { component qml.Object root qml.Object value *TestType + rect *RectType } var tests = []struct { Summary string Value TestType + Rect RectType Init func(d *TestData) @@ -893,16 +916,49 @@ var tests = []struct { QML: `Item{}`, Done: func(d *TestData) { d.Assert(d.root.TypeName(), Equals, "QQuickItem") }, }, + { + Summary: "Custom Go type with painting", + QML: ` + import GoTypes 4.2 + Rectangle { + width: 200; height: 200 + color: "black" + GoRect { + width: 100; height: 100; x: 50; y: 50 + } + } + `, + Done: func(d *TestData) { + d.Assert(d.rect.PaintCount, Equals, 0) + + window := d.component.CreateWindow(nil) + defer window.Destroy() + window.Show() + + // Qt doesn't hide the Window if we call it too quickly. :-( + time.Sleep(100 * time.Millisecond) + + d.Assert(d.rect.PaintCount, Equals, 1) + + image := window.Snapshot() + d.Assert(image.At(25, 25), Equals, color.RGBA{0, 0, 0, 255}) + d.Assert(image.At(100, 100), Equals, color.RGBA{255, 0, 0, 255}) + }, + }, } var tablef = flag.String("tablef", "", "if provided, TestTable only runs tests with a summary matching the regexp") func (s *S) TestTable(c *C) { - var goTypeValue *TestType = &TestType{} + var goTypeValue *TestType + var goRectValue *RectType types := []qml.TypeSpec{{ Name: "GoType", New: func() interface{} { return goTypeValue }, + }, { + Name: "GoRect", + New: func() interface{} { return goRectValue }, }, { Name: "GoSingleton", New: func() interface{} { return goTypeValue }, @@ -930,9 +986,13 @@ func (s *S) TestTable(c *C) { goTypeValue = &value s.context.SetVar("value", &value) + rect := t.Rect + goRectValue = &rect + testData := TestData{ C: c, value: &value, + rect: &rect, engine: s.engine, context: s.context, } diff --git a/bridge.go b/bridge.go index 5fcc151e..67f9081e 100644 --- a/bridge.go +++ b/bridge.go @@ -246,6 +246,7 @@ func wrapGoValue(engine *Engine, gvalue interface{}, owner valueOwner) (cvalue u } else { engine.values[gvalue] = fold } + //fmt.Printf("[DEBUG] value alive (wrapped): %x/%#v\n", fold.cvalue, fold.gvalue) stats.valuesAlive(+1) C.engineSetContextForObject(engine.addr, fold.cvalue) switch owner { @@ -272,12 +273,15 @@ var typeNew = make(map[*valueFold]bool) //export hookGoValueTypeNew func hookGoValueTypeNew(cvalue unsafe.Pointer, specp unsafe.Pointer) (foldp unsafe.Pointer) { + // TODO Do some basic validation on the created gvalue. Pointer-of-pointer is + // not okay, etc. See wrapGoValue for the list of checks, possibly refactoring. fold := &valueFold{ gvalue: (*TypeSpec)(specp).New(), cvalue: cvalue, owner: jsOwner, } typeNew[fold] = true + //fmt.Printf("[DEBUG] value alive (type-created): %x/%#v\n", fold.cvalue, fold.gvalue) stats.valuesAlive(+1) return unsafe.Pointer(fold) } @@ -320,6 +324,7 @@ func hookGoValueDestroyed(enginep unsafe.Pointer, foldp unsafe.Pointer) { } } } + //fmt.Printf("[DEBUG] value destroyed: %x/%#v\n", fold.cvalue, fold.gvalue) stats.valuesAlive(-1) }