Beispiel #1
0
// packDataValue packs the provided Go value into a C.DataValue for
// shiping into C++ land.
//
// For simple types (bool, int, etc) value is converted into a
// native C++ value. For anything else, including cases when value
// has a type that has an underlying simple type, the Go value itself
// is encapsulated into a C++ wrapper so that field access and method
// calls work.
//
// This must be run from the main GUI thread due to the cases where
// calling wrapGoValue is necessary.
func packDataValue(value interface{}, dvalue *C.DataValue, engine *Engine, owner valueOwner) {
	datap := unsafe.Pointer(&dvalue.data)
	if value == nil {
		dvalue.dataType = C.DTInvalid
		return
	}
	switch value := value.(type) {
	case string:
		dvalue.dataType = C.DTString
		cstr, cstrlen := unsafeStringData(value)
		*(**C.char)(datap) = cstr
		dvalue.len = cstrlen
	case bool:
		dvalue.dataType = C.DTBool
		*(*bool)(datap) = value
	case int:
		if value > 1<<31-1 {
			dvalue.dataType = C.DTInt64
			*(*int64)(datap) = int64(value)
		} else {
			dvalue.dataType = C.DTInt32
			*(*int32)(datap) = int32(value)
		}
	case int64:
		dvalue.dataType = C.DTInt64
		*(*int64)(datap) = value
	case int32:
		dvalue.dataType = C.DTInt32
		*(*int32)(datap) = value
	case uint64:
		dvalue.dataType = C.DTUint64
		*(*uint64)(datap) = value
	case uint32:
		dvalue.dataType = C.DTUint32
		*(*uint32)(datap) = value
	case float64:
		dvalue.dataType = C.DTFloat64
		*(*float64)(datap) = value
	case float32:
		dvalue.dataType = C.DTFloat32
		*(*float32)(datap) = value
	case *Common:
		dvalue.dataType = C.DTObject
		*(*unsafe.Pointer)(datap) = value.addr
	case color.RGBA:
		dvalue.dataType = C.DTColor
		*(*uint32)(datap) = uint32(value.A)<<24 | uint32(value.R)<<16 | uint32(value.G)<<8 | uint32(value.B)
	default:
		dvalue.dataType = C.DTObject
		if obj, ok := value.(Object); ok {
			*(*unsafe.Pointer)(datap) = obj.Common().addr
		} else {
			*(*unsafe.Pointer)(datap) = wrapGoValue(engine, value, owner)
		}
	}
}
Beispiel #2
0
// packDataValue packs the provided Go value into a C.DataValue for
// shiping into C++ land.
//
// For simple types (bool, int, etc) value is converted into a
// native C++ value. For anything else, including cases when value
// has a type that has an underlying simple type, the Go value itself
// is encapsulated into a C++ wrapper so that field access and method
// calls work.
//
// This must be run from the main GUI thread due to the cases where
// calling wrapGoValue is necessary.
func packDataValue(value interface{}, dvalue *C.DataValue, engine *Engine, owner valueOwner) {
	datap := unsafe.Pointer(&dvalue.data)
	if value == nil {
		dvalue.dataType = C.DTInvalid
		return
	}
	switch value := value.(type) {
	case string:
		dvalue.dataType = C.DTString
		cstr, cstrlen := unsafeStringData(value)
		*(**C.char)(datap) = cstr
		dvalue.len = cstrlen
	case bool:
		dvalue.dataType = C.DTBool
		*(*bool)(datap) = value
	case int:
		dvalue.dataType = intDT
		*(*int)(datap) = value
	case int64:
		dvalue.dataType = C.DTInt64
		*(*int64)(datap) = value
	case int32:
		dvalue.dataType = C.DTInt32
		*(*int32)(datap) = value
	case float64:
		dvalue.dataType = C.DTFloat64
		*(*float64)(datap) = value
	case float32:
		dvalue.dataType = C.DTFloat32
		*(*float32)(datap) = value
	case *Object:
		dvalue.dataType = C.DTObject
		*(*unsafe.Pointer)(datap) = value.addr
	default:
		dvalue.dataType = C.DTObject
		*(*unsafe.Pointer)(datap) = wrapGoValue(engine, value, owner)
	}
}
Beispiel #3
0
// packDataValue packs the provided Go value into a C.DataValue for
// shiping into C++ land.
//
// For simple types (bool, int, etc) value is converted into a
// native C++ value. For anything else, including cases when value
// has a type that has an underlying simple type, the Go value itself
// is encapsulated into a C++ wrapper so that field access and method
// calls work.
//
// This must be run from the main GUI thread due to the cases where
// calling wrapGoValue is necessary.
func packDataValue(value interface{}, dvalue *C.DataValue, engine *Engine, owner valueOwner) {
	datap := unsafe.Pointer(&dvalue.data)
	if value == nil {
		dvalue.dataType = C.DTInvalid
		return
	}
	switch value := value.(type) {
	case string:
		dvalue.dataType = C.DTString
		cstr, cstrlen := unsafeStringData(value)
		*(**C.char)(datap) = cstr
		dvalue.len = cstrlen
	case bool:
		dvalue.dataType = C.DTBool
		*(*bool)(datap) = value
	case int:
		if value > 1<<31-1 {
			dvalue.dataType = C.DTInt64
			*(*int64)(datap) = int64(value)
		} else {
			dvalue.dataType = C.DTInt32
			*(*int32)(datap) = int32(value)
		}
	case int64:
		dvalue.dataType = C.DTInt64
		*(*int64)(datap) = value
	case int32:
		dvalue.dataType = C.DTInt32
		*(*int32)(datap) = value
	case uint64:
		dvalue.dataType = C.DTUint64
		*(*uint64)(datap) = value
	case uint32:
		dvalue.dataType = C.DTUint32
		*(*uint32)(datap) = value
	case float64:
		dvalue.dataType = C.DTFloat64
		*(*float64)(datap) = value
	case float32:
		dvalue.dataType = C.DTFloat32
		*(*float32)(datap) = value
	case *Common:
		dvalue.dataType = C.DTObject
		*(*unsafe.Pointer)(datap) = value.addr
	case color.RGBA:
		dvalue.dataType = C.DTColor
		*(*uint32)(datap) = uint32(value.A)<<24 | uint32(value.R)<<16 | uint32(value.G)<<8 | uint32(value.B)
	default:
		rv := reflect.ValueOf(value)
		switch rv.Type().Kind() {
		case reflect.Ptr:
			rv = rv.Elem()
			if rv.Kind() != reflect.Array && rv.Kind() != reflect.Slice {
				break
			}
			fallthrough

		case reflect.Array, reflect.Slice:
			dvalue.dataType = C.DTVariantList
			dataValues := make([]C.DataValue, rv.Len())

			for i := range dataValues {
				packDataValue(rv.Index(i).Interface(), &dataValues[i], engine, owner)
			}

			switch len(dataValues) {
			case 0:
				*(*unsafe.Pointer)(unsafe.Pointer(&dvalue.data)) = C.newVariantList(nil, 0)

			default:
				*(*unsafe.Pointer)(unsafe.Pointer(&dvalue.data)) = C.newVariantList(&dataValues[0], C.int(len(dataValues)))
			}

			return
		}

		dvalue.dataType = C.DTObject
		if obj, ok := value.(Object); ok {
			*(*unsafe.Pointer)(datap) = obj.Common().addr
		} else {
			*(*unsafe.Pointer)(datap) = wrapGoValue(engine, value, owner)
		}
	}
}