Skip to content

Commit

Permalink
More type-specific getters for Object.
Browse files Browse the repository at this point in the history
  • Loading branch information
niemeyer committed Sep 20, 2013
1 parent 73a3c91 commit 19e92e4
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 12 deletions.
34 changes: 30 additions & 4 deletions all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,37 @@ var tests = []struct {
},
},
{
Summary: "Read an object field",
QML: "Item { property var obj: Rectangle { width: 300; height: 200 } }",
Summary: "Read object properties",
QML: `
Item {
property bool boolp: true
property int intp: 1
property var int64p: 4294967296
property real float32p: 1.1
property double float64p: 1.1
property string stringp: "<content>"
property var objectp: Rectangle { width: 123 }
}
`,
Done: func(d *TestData) {
d.Check(d.compinst.Object("obj").Int("width"), Equals, 300)
d.Check(d.compinst.Object("obj").Int("height"), Equals, 200)
obj := d.compinst
d.Check(obj.Bool("boolp"), Equals, true)
d.Check(obj.Int("intp"), Equals, 1)
d.Check(obj.Int64("intp"), Equals, int64(1))
d.Check(obj.Int64("int64p"), Equals, int64(4294967296))
d.Check(obj.Float64("intp"), Equals, float64(1))
d.Check(obj.Float64("int64p"), Equals, float64(4294967296))
d.Check(obj.Float64("float32p"), Equals, float64(1.1))
d.Check(obj.Float64("float64p"), Equals, float64(1.1))
d.Check(obj.String("stringp"), Equals, "<content>")
d.Check(obj.Object("objectp").Int("width"), Equals, 123)

d.Check(func() { obj.Bool("intp") }, Panics, `value of property "intp" is not a bool: 1`)
d.Check(func() { obj.Int("boolp") }, Panics, `value of property "boolp" cannot be represented as an int: true`)
d.Check(func() { obj.Int64("boolp") }, Panics, `value of property "boolp" cannot be represented as an int64: true`)
d.Check(func() { obj.Float64("boolp") }, Panics, `value of property "boolp" cannot be represented as a float64: true`)
d.Check(func() { obj.String("boolp") }, Panics, `value of property "boolp" is not a string: true`)
d.Check(func() { obj.Object("boolp") }, Panics, `value of property "boolp" is not a *qml.Object: true`)
},
},
{
Expand Down
2 changes: 2 additions & 0 deletions datatype.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ func packDataValue(value interface{}, dvalue *C.DataValue, engine *Engine, owner
}
}

// TODO Handle byte slices.

// unpackDataValue converts a value shipped by C++ into a native Go value.
//
// HEADS UP: This is considered safe to be run out of the main GUI thread.
Expand Down
74 changes: 66 additions & 8 deletions qml.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ func (obj *Object) Set(property string, value interface{}) error {
// If the property type is known, type-specific methods such as Int
// and String are more convenient to use.
func (obj *Object) Property(name string) interface{} {
// TODO Return an ok bool indicating whether the property was found.
// TODO Panic if the property is not found.
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))

Expand All @@ -289,35 +289,93 @@ func (obj *Object) Int(property string) int {
return int(value)
case int64:
if int64(int(value)) != value {
panic(fmt.Sprintf("value of property %q is too large for int: %v", property, value))
panic(fmt.Sprintf("value of property %q is too large for int: %#v", property, value))
}
return int(value)
case float32:
// May truncate, but seems a bit too much computing to validate these all the time.
return int(value)
case float64:
// May truncate, but seems a bit too much computing to validate these all the time.
return int(value)
default:
panic(fmt.Sprintf("value of property %q cannot be represented as an int: %v", property, value))
panic(fmt.Sprintf("value of property %q cannot be represented as an int: %#v", property, value))
}
}

// Int64 returns the int64 value of the given property.
// The call panics if the property value cannot be represented as an int64.
func (obj *Object) Int64(property string) int64 {
switch value := obj.Property(property).(type) {
case int:
return int64(value)
case int32:
return int64(value)
case int64:
return value
case float32:
// May truncate, but seems a bit too much computing to validate these all the time.
return int64(value)
case float64:
// May truncate, but seems a bit too much computing to validate these all the time.
return int64(value)
default:
panic(fmt.Sprintf("value of property %q cannot be represented as an int64: %#v", property, value))
}
}

// Float64 returns the float64 value of the given property.
// The call panics if the property value cannot be represented as float64.
func (obj *Object) Float64(property string) float64 {
switch value := obj.Property(property).(type) {
case int:
return float64(value)
case int32:
return float64(value)
case int64:
return float64(value)
case float32:
return float64(value)
case float64:
return value
default:
panic(fmt.Sprintf("value of property %q cannot be represented as a float64: %#v", property, value))
}
}

// Bool returns the bool value of the given property.
// The call panics if the property value is not a bool.
func (obj *Object) Bool(property string) bool {
value := obj.Property(property)
b, ok := value.(bool)
if !ok {
panic(fmt.Sprintf("value of property %q is not a bool: %#v", property, value))
}
return b
}

// String returns the string value of the given property.
// The call panics if the property value is not a string.
func (obj *Object) String(property string) string {
s, ok := obj.Property(property).(string)
value := obj.Property(property)
s, ok := value.(string)
if !ok {
panic(fmt.Sprintf("value of property %q is not a string: %v", property, s))
panic(fmt.Sprintf("value of property %q is not a string: %#v", property, value))
}
return s
}

// TODO More type-specific methods: int64, float64, etc

// TODO Consider getting rid of int32 and float32 results. Always returning 64-bit
// results will make it easier on clients that want to handle arbitrary typing.

// Object returns the *qml.Object value of the given property.
// The call panics if the property value is not a *qml.Object.
func (obj *Object) Object(property string) *Object {
object, ok := obj.Property(property).(*Object)
value := obj.Property(property)
object, ok := value.(*Object)
if !ok {
panic(fmt.Sprintf("value of property %q is not a *qml.Object: %v", property, object))
panic(fmt.Sprintf("value of property %q is not a *qml.Object: %#v", property, value))
}
return object
}
Expand Down

0 comments on commit 19e92e4

Please sign in to comment.